X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkwidget.c;h=37460e3419680aab8b42d52e0f51003bb474fc0a;hb=1074aa0c49f647ed4b2a969618051c59da5aad01;hp=231d27b7738b75f3edcf44b28a5ef9db820f80c8;hpb=bbb981fd1aecae0dba4ab9e23ed38ce91ba771f9;p=~andy%2Fgtk diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 231d27b77..37460e341 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -1805,6 +1805,13 @@ gtk_widget_class_init (GtkWidgetClass *klass) * restore it. The signal emission takes care of calling cairo_save() * before and cairo_restore() after invoking the handler. * + * The signal handler will get a @cr with a clip region already set to the + * widget's dirty region, i.e. to the area that needs repainting. Complicated + * widgets that want to avoid redrawing themselves completely can get the full + * extents of the clip region with gdk_cairo_get_clip_rectangle(), or they can + * get a finer-grained representation of the dirty region with + * cairo_copy_clip_rectangle_list(). + * * Returns: %TRUE to stop other handlers from being invoked for the event. % %FALSE to propagate the event further. * @@ -4554,6 +4561,7 @@ unref_tick_callback_info (GtkWidget *widget, g_signal_handlers_disconnect_by_func (frame_clock, (gpointer) gtk_widget_on_frame_clock_update, widget); + gdk_frame_clock_end_updating (frame_clock); } } @@ -4576,6 +4584,8 @@ gtk_widget_on_frame_clock_update (GdkFrameClock *frame_clock, GtkWidgetPrivate *priv = widget->priv; GList *l; + g_object_ref (widget); + for (l = priv->tick_callbacks; l;) { GtkTickCallbackInfo *info = l->data; @@ -4597,9 +4607,7 @@ gtk_widget_on_frame_clock_update (GdkFrameClock *frame_clock, l = next; } - if (priv->tick_callbacks != NULL) - gdk_frame_clock_request_phase (frame_clock, - GDK_FRAME_CLOCK_PHASE_UPDATE); + g_object_unref (widget); } static guint tick_callback_id; @@ -4626,11 +4634,16 @@ static guint tick_callback_id; * gdk_frame_clock_get_frame_time() should generally be used for timing * continuous animations and * gdk_frame_timings_get_predicted_presentation_time() if you are - * trying to display isolated frames particular times. + * trying to display isolated frames at particular times. * * This is a more convenient alternative to connecting directly to the - * ::update signal of GdkFrameClock, since you don't have to worry about - * when a #GdkFrameClock is assigned to a widget. + * #GdkFrameClock::update signal of #GdkFrameClock, since you don't + * have to worry about when a #GdkFrameClock is assigned to a widget. + * + * Returns: an id for the connection of this callback. Remove the callback + * by passing it to gtk_widget_remove_tick_callback() + * + * Since: 3.8 */ guint gtk_widget_add_tick_callback (GtkWidget *widget, @@ -4651,8 +4664,7 @@ gtk_widget_add_tick_callback (GtkWidget *widget, g_signal_connect (frame_clock, "update", G_CALLBACK (gtk_widget_on_frame_clock_update), widget); - gdk_frame_clock_request_phase (frame_clock, - GDK_FRAME_CLOCK_PHASE_UPDATE); + gdk_frame_clock_begin_updating (frame_clock); } info = g_slice_new0 (GtkTickCallbackInfo); @@ -4669,6 +4681,16 @@ gtk_widget_add_tick_callback (GtkWidget *widget, return info->id; } +/** + * gtk_widget_remove_tick_callback: + * @widget: a #GtkWidget + * @id: an id returned by gtk_widget_add_tick_callback() + * + * Removes a tick callback previously registered with + * gtk_widget_add_tick_callback(). + * + * Since: 3.8 + */ void gtk_widget_remove_tick_callback (GtkWidget *widget, guint id) @@ -4702,8 +4724,7 @@ gtk_widget_connect_frame_clock (GtkWidget *widget, g_signal_connect (frame_clock, "update", G_CALLBACK (gtk_widget_on_frame_clock_update), widget); - gdk_frame_clock_request_phase (frame_clock, - GDK_FRAME_CLOCK_PHASE_UPDATE); + gdk_frame_clock_begin_updating (frame_clock); } if (priv->context) @@ -4720,9 +4741,12 @@ gtk_widget_disconnect_frame_clock (GtkWidget *widget, _gtk_container_stop_idle_sizer (GTK_CONTAINER (widget)); if (priv->tick_callbacks) - g_signal_handlers_disconnect_by_func (frame_clock, - (gpointer) gtk_widget_on_frame_clock_update, - widget); + { + g_signal_handlers_disconnect_by_func (frame_clock, + (gpointer) gtk_widget_on_frame_clock_update, + widget); + gdk_frame_clock_end_updating (frame_clock); + } if (priv->context) gtk_style_context_set_frame_clock (priv->context, NULL); @@ -5032,8 +5056,9 @@ gtk_widget_queue_resize_no_redraw (GtkWidget *widget) * * Unrealized widgets do not have a frame clock. * - * Since: 3.0 * Return value: (transfer none): a #GdkFrameClock (or #NULL if widget is unrealized) + * + * Since: 3.0 */ GdkFrameClock* gtk_widget_get_frame_clock (GtkWidget *widget) @@ -7478,13 +7503,13 @@ gtk_widget_set_receives_default (GtkWidget *widget, * gtk_widget_get_receives_default: * @widget: a #GtkWidget * - * Determines whether @widget is alyways treated as default widget - * withing its toplevel when it has the focus, even if another widget + * Determines whether @widget is always treated as the default widget + * within its toplevel when it has the focus, even if another widget * is the default. * * See gtk_widget_set_receives_default(). * - * Return value: %TRUE if @widget acts as default widget when focussed, + * Return value: %TRUE if @widget acts as the default widget when focussed, * %FALSE otherwise * * Since: 2.18 @@ -14073,7 +14098,7 @@ gtk_widget_register_window (GtkWidget *widget, gdk_window_set_user_data (window, widget); priv->registered_windows = g_list_prepend (priv->registered_windows, window); - if (!gtk_widget_get_has_window (widget) && !gdk_window_has_native (window)) + if (priv->window != window && !gdk_window_has_native (window)) gdk_window_set_opacity (window, priv->norender_children ? 0.0 : 1.0); } @@ -14205,21 +14230,25 @@ gtk_widget_propagate_alpha (GtkWidget *widget) parent = priv->parent; - norender = - /* If this widget has an opacity group, never render it */ - priv->opacity_group || - /* If the parent has norender_children, propagate that here */ - (parent != NULL && parent->priv->norender_children); - - /* Windowed widget children should norender if: */ + /* Norender affects only windowed widget and means don't render widget->window in the + normal fashion. + We only set this if the parent has norender_children, because: + a) For an opacity group (that does not have a norender_children parent) we still + need to render the window or we will never get an expose event. + b) For alpha we set the opacity of window->widget directly, so no other + work is needed. + */ + norender = (parent != NULL && parent->priv->norender_children); + + /* windows under this widget should not render if: + a) This widget has an opacity group + b) This widget has alpha and is no-windowed (otherwise we'd set alpha on widget->window) + c) This widget has norender but is no-windowed (a windowed widget would "swallow" the norender) + */ norender_children = - /* The widget is no_window (otherwise its enought to mark it norender/alpha), and */ - !gtk_widget_get_has_window (widget) && - ( /* norender is set, or */ - norender || - /* widget has an alpha */ - priv->alpha != 255 - ); + priv->opacity_group || + (!gtk_widget_get_has_window (widget) && + ( norender || priv->alpha != 255)); if (gtk_widget_get_has_window (widget)) { @@ -14227,14 +14256,12 @@ gtk_widget_propagate_alpha (GtkWidget *widget) gdk_window_set_opacity (priv->window, norender ? 0 : priv->alpha / 255.0); } - else /* !has_window */ + + for (l = priv->registered_windows; l != NULL; l = l->next) { - for (l = priv->registered_windows; l != NULL; l = l->next) - { - GdkWindow *w = l->data; - if (!gdk_window_has_native (w)) - gdk_window_set_opacity (w, norender_children ? 0.0 : 1.0); - } + GdkWindow *w = l->data; + if (w != priv->window && !gdk_window_has_native (w)) + gdk_window_set_opacity (w, norender_children ? 0.0 : 1.0); } priv->norender = norender;