Unnecessary repainting in custom widget




I'm working on a custom widget and there are two cases where the entire
widget gets repainted when only part of it is updated. I have the following
code inside my draw function to see what gets repainted:

    double x1,y1,x2,y2;

    cairo_clip_extents(cr,&x1,&y1,&x2,&y2);
    g_print("draw clip  pos: %f,%f size: %fx%f\n",x1,y1,x2-x1,y2-y1);


The entire widget code is rather large so I'll just explain what I'm doing.

The first is when the focus moves in or out of the widget. My widget is
composed of multiple distinct parts that can receive focus, so I
implemented the focus and focus_out_event functions (via GtkWidgetClass).
When the focus needs to move, I check if there is another part in that
direction. If there is, I call gdk_window_invalidate_rect on the areas of
the two parts and return TRUE. If not, I return FALSE and let the default
behaviour take place. If the focus leaves the widget,
gdk_window_invalidate_rect gets called inside the focus_out_event function.
I even call gtk_widget_grab_focus myself if the widget didn't already have
focus. This all works fine except whenever the focus moves in or out of my
widget, the entire widget gets repainted. I even implemented the
focus_in_event function to try to inhibit this behaviour. It doesn't seem
to matter whether I return TRUE or FALSE in the focus_[in/out]_event
functions.

The second is with style transitions. I use the
gtk_style_context_[push/pop]_animatable_region functions for the different
parts of the widget and manage state (as in GtkStateType) manually (I don't
use gtk_widget_set_state or gtk_widget_set_state_flags). Whenever a state
changes, I call gtk_style_context_notify_state_change and
gdk_window_invalidate_rect on the relevant area. For both
gtk_style_context_- functions I specify a unique region ID. Without
transitions, it works perfectly. I then added "GtkButton:hover { color:
#cc2222; transition: 1s linear }" to a css file that the test application
loads. Both the fake button I draw using the gtk_render_- functions and a
real button I added for comparison animate very nicely when hovered over
but again I find the entire widget is being repainted. It's a bigger
problem here because this time the widget is being redrawn many times a
second. I take it that the point of specifying a region ID in the
gtk_style_context_[push/pop]_animatable_region functions is so that the
combined region that the gtk_render_- calls define can be saved and used to
invalidate only the relevant part during a transition update.

Can I prevent the entire widget from being repainted in either of these
cases without resorting to hacks or using additional GdkWindow objects?

                                          


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]