fix cairo widget background
authorRobin Gareus <robin@gareus.org>
Fri, 29 Aug 2014 23:42:37 +0000 (01:42 +0200)
committerRobin Gareus <robin@gareus.org>
Fri, 29 Aug 2014 23:43:10 +0000 (01:43 +0200)
libs/gtkmm2ext/cairo_widget.cc
libs/gtkmm2ext/gtkmm2ext/cairo_widget.h

index 033a66f9080dc2f4c67e80fa7e1a0c113f3c541a..16e7f29b5f7ac71bd66ea39c892bc604bd2900de 100644 (file)
@@ -41,12 +41,14 @@ CairoWidget::CairoWidget ()
        , _need_bg (true)
        , _grabbed (false)
        , _name_proxy (this, X_("name"))
+       , _current_parent (0)
 {
        _name_proxy.connect (sigc::mem_fun (*this, &CairoWidget::on_name_changed));
 }
 
 CairoWidget::~CairoWidget ()
 {
+       if (_parent_style_change) _parent_style_change.disconnect();
 }
 
 bool
@@ -54,14 +56,13 @@ CairoWidget::on_expose_event (GdkEventExpose *ev)
 {
        cairo_t* cr = gdk_cairo_create (get_window ()->gobj());
        cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height);
-       cairo_clip (cr);
+       cairo_clip_preserve (cr);
 
-       /* paint expose area the color of the parent window bg 
+       /* paint expose area the color of the parent window bg
        */
        
        Gdk::Color bg (get_parent_bg());
        
-       cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height);
        cairo_set_source_rgb (cr, bg.get_red_p(), bg.get_green_p(), bg.get_blue_p());
        cairo_fill (cr);
 
@@ -103,28 +104,38 @@ CairoWidget::on_size_allocate (Gtk::Allocation& alloc)
 Gdk::Color
 CairoWidget::get_parent_bg ()
 {
-        Widget* parent;
+       Widget* parent;
 
        parent = get_parent ();
 
-        while (parent) {
+       while (parent) {
                void* p = g_object_get_data (G_OBJECT(parent->gobj()), has_cairo_widget_background_info);
 
                if (p) {
                        Glib::RefPtr<Gtk::Style> style = parent->get_style();
+                       if (_current_parent != parent) {
+                               if (_parent_style_change) _parent_style_change.disconnect();
+                               _current_parent = parent;
+                               _parent_style_change = parent->signal_style_changed().connect (mem_fun (*this, &CairoWidget::on_style_changed));
+                       }
                        return style->get_bg (get_state());
                }
-               
+
                if (!parent->get_has_window()) {
                        parent = parent->get_parent();
                } else {
                        break;
                }
-        }
+       }
 
-        if (parent && parent->get_has_window()) {
+       if (parent && parent->get_has_window()) {
+               if (_current_parent != parent) {
+                       if (_parent_style_change) _parent_style_change.disconnect();
+                       _current_parent = parent;
+                       _parent_style_change = parent->signal_style_changed().connect (mem_fun (*this, &CairoWidget::on_style_changed));
+               }
                return parent->get_style ()->get_bg (parent->get_state());
-        } 
+       }
 
        return get_style ()->get_bg (get_state());
 }
@@ -161,11 +172,17 @@ CairoWidget::set_active (bool yn)
        }
 }
 
+void
+CairoWidget::on_style_changed (const Glib::RefPtr<Gtk::Style>&)
+{
+       queue_draw();
+}
+
 void
 CairoWidget::on_state_changed (Gtk::StateType)
 {
        /* this will catch GTK-level state changes from calls like
-          ::set_sensitive() 
+          ::set_sensitive()
        */
 
        if (get_state() == Gtk::STATE_INSENSITIVE) {
@@ -186,7 +203,7 @@ CairoWidget::set_draw_background (bool yn)
 void
 CairoWidget::provide_background_for_cairo_widget (Gtk::Widget& w, const Gdk::Color& bg)
 {
-       /* set up @w to be able to provide bg information to 
+       /* set up @w to be able to provide bg information to
           any CairoWidgets that are packed inside it.
        */
 
index 9f0487798a10958623e62cd6ee829333af696c21..2e845b94eb3c590feb2da01ad763870fa59b3313 100644 (file)
@@ -39,7 +39,7 @@ public:
        Gtkmm2ext::ActiveState active_state() const { return _active_state; }
        Gtkmm2ext::VisualState visual_state() const { return _visual_state; }
        
-       /* derived widgets can override these two to catch 
+       /* derived widgets can override these two to catch
           changes in active & visual state
        */
        
@@ -79,6 +79,7 @@ protected:
        virtual bool on_expose_event (GdkEventExpose *);
        void on_size_allocate (Gtk::Allocation &);
        void on_state_changed (Gtk::StateType);
+       void on_style_changed (const Glib::RefPtr<Gtk::Style>&);
        Gdk::Color get_parent_bg ();
        
        /* this is an additional virtual "on_..." method. Glibmm does not
@@ -96,6 +97,8 @@ protected:
 
   private:
        Glib::SignalProxyProperty _name_proxy;
+       sigc::connection _parent_style_change;
+       Widget * _current_parent;
 };
 
 #endif