From 8d10b09aff0bc03c54c2f1899900cc062f36ad4b Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Thu, 16 Aug 2012 09:35:53 +0200 Subject: [PATCH 16/68] gtk: correctly handle toggling of the scrollbar visibility setting By doing most things unconditionally, like connecting to signals and creating the opacity adjustment. Queue a resize when the setting changes so things get recalculated properly, and make sure the scrollbars get expose events if they are visible. Unrelated: don't leak the priv->opacity adjustment. --- gtk/gtkscrolledwindow.c | 244 +++++++++++++++++++++++------------------------ 1 file changed, 119 insertions(+), 125 deletions(-) diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 3220e91..7680f5d 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -529,29 +529,25 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window) G_CALLBACK (gtk_scrolled_window_overlay_scrollbars_changed), scrolled_window); - if (g_getenv ("GTK2_KINETIC_SCROLLING")) - { - gtk_scrolled_window_set_kinetic_scrolling (scrolled_window, TRUE); - gtk_scrolled_window_set_capture_button_press (scrolled_window, TRUE); - } - - if (priv->overlay_scrollbars) - { - priv->opacity = g_object_new (GTK_TYPE_ADJUSTMENT, - "lower", 0.0, - "upper", 0.5, - "value", 0.0, - NULL); - priv->sb_min_height = 20; - priv->sb_padding = 2; - priv->sb_radius = 3; - priv->sb_width = 6; - priv->sb_fade_out_delay = 1000; - - g_signal_connect (priv->opacity, "value-changed", - G_CALLBACK (gtk_scrolled_window_expose_scrollbars), - scrolled_window); - } + gtk_scrolled_window_set_kinetic_scrolling (scrolled_window, TRUE); + gtk_scrolled_window_set_capture_button_press (scrolled_window, TRUE); + + priv->opacity = g_object_new (GTK_TYPE_ADJUSTMENT, + "lower", 0.0, + "upper", 0.5, + "value", 0.0, + NULL); + g_object_ref_sink (priv->opacity); + + priv->sb_min_height = 20; + priv->sb_padding = 2; + priv->sb_radius = 3; + priv->sb_width = 6; + priv->sb_fade_out_delay = 1000; + + g_signal_connect (priv->opacity, "value-changed", + G_CALLBACK (gtk_scrolled_window_expose_scrollbars), + scrolled_window); } /** @@ -632,16 +628,12 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window, g_signal_handlers_disconnect_by_func (old_adjustment, gtk_scrolled_window_adjustment_changed, scrolled_window); - - if (priv->overlay_scrollbars) - { - g_signal_handlers_disconnect_by_func (old_adjustment, - gtk_scrolled_window_adjustment_value_changed, - scrolled_window); - g_signal_handlers_disconnect_by_func (old_adjustment, - gtk_scrolled_window_expose_scrollbars, - scrolled_window); - } + g_signal_handlers_disconnect_by_func (old_adjustment, + gtk_scrolled_window_adjustment_value_changed, + scrolled_window); + g_signal_handlers_disconnect_by_func (old_adjustment, + gtk_scrolled_window_expose_scrollbars, + scrolled_window); gtk_range_set_adjustment (GTK_RANGE (scrolled_window->hscrollbar), hadjustment); @@ -658,19 +650,18 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window, gtk_scrolled_window_adjustment_changed (hadjustment, scrolled_window); gtk_scrolled_window_adjustment_value_changed (hadjustment, scrolled_window); - if (priv->overlay_scrollbars) - { - g_signal_connect (hadjustment, "value-changed", - G_CALLBACK (gtk_scrolled_window_adjustment_value_changed), - scrolled_window); +#if 0 + g_signal_connect (hadjustment, "value-changed", + G_CALLBACK (gtk_scrolled_window_adjustment_value_changed), + scrolled_window); +#endif - g_signal_connect (hadjustment, "changed", - G_CALLBACK (gtk_scrolled_window_expose_scrollbars), - scrolled_window); - g_signal_connect (hadjustment, "value-changed", - G_CALLBACK (gtk_scrolled_window_expose_scrollbars), - scrolled_window); - } + g_signal_connect (hadjustment, "changed", + G_CALLBACK (gtk_scrolled_window_expose_scrollbars), + scrolled_window); + g_signal_connect (hadjustment, "value-changed", + G_CALLBACK (gtk_scrolled_window_expose_scrollbars), + scrolled_window); if (bin->child) gtk_widget_set_scroll_adjustments (bin->child, @@ -725,16 +716,12 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window, g_signal_handlers_disconnect_by_func (old_adjustment, gtk_scrolled_window_adjustment_changed, scrolled_window); - - if (priv->overlay_scrollbars) - { - g_signal_handlers_disconnect_by_func (old_adjustment, - gtk_scrolled_window_adjustment_value_changed, - scrolled_window); - g_signal_handlers_disconnect_by_func (old_adjustment, - gtk_scrolled_window_expose_scrollbars, - scrolled_window); - } + g_signal_handlers_disconnect_by_func (old_adjustment, + gtk_scrolled_window_adjustment_value_changed, + scrolled_window); + g_signal_handlers_disconnect_by_func (old_adjustment, + gtk_scrolled_window_expose_scrollbars, + scrolled_window); gtk_range_set_adjustment (GTK_RANGE (scrolled_window->vscrollbar), vadjustment); @@ -751,20 +738,19 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window, gtk_scrolled_window_adjustment_changed (vadjustment, scrolled_window); gtk_scrolled_window_adjustment_value_changed (vadjustment, scrolled_window); - if (priv->overlay_scrollbars) - { - g_signal_connect (vadjustment, - "value-changed", - G_CALLBACK (gtk_scrolled_window_adjustment_value_changed), - scrolled_window); +#if 0 + g_signal_connect (vadjustment, + "value-changed", + G_CALLBACK (gtk_scrolled_window_adjustment_value_changed), + scrolled_window); +#endif - g_signal_connect (vadjustment, "changed", - G_CALLBACK (gtk_scrolled_window_expose_scrollbars), - scrolled_window); - g_signal_connect (vadjustment, "value-changed", - G_CALLBACK (gtk_scrolled_window_expose_scrollbars), - scrolled_window); - } + g_signal_connect (vadjustment, "changed", + G_CALLBACK (gtk_scrolled_window_expose_scrollbars), + scrolled_window); + g_signal_connect (vadjustment, "value-changed", + G_CALLBACK (gtk_scrolled_window_expose_scrollbars), + scrolled_window); if (bin->child) gtk_widget_set_scroll_adjustments (bin->child, @@ -1224,16 +1210,12 @@ gtk_scrolled_window_destroy (GtkObject *object) g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)), gtk_scrolled_window_adjustment_changed, scrolled_window); - - if (priv->overlay_scrollbars) - { - g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)), - gtk_scrolled_window_adjustment_value_changed, - scrolled_window); - g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)), - gtk_scrolled_window_expose_scrollbars, - scrolled_window); - } + g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)), + gtk_scrolled_window_adjustment_value_changed, + scrolled_window); + g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar)), + gtk_scrolled_window_expose_scrollbars, + scrolled_window); gtk_widget_unparent (scrolled_window->hscrollbar); gtk_widget_destroy (scrolled_window->hscrollbar); @@ -1245,16 +1227,12 @@ gtk_scrolled_window_destroy (GtkObject *object) g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)), gtk_scrolled_window_adjustment_changed, scrolled_window); - - if (priv->overlay_scrollbars) - { - g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)), - gtk_scrolled_window_adjustment_value_changed, - scrolled_window); - g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)), - gtk_scrolled_window_expose_scrollbars, - scrolled_window); - } + g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)), + gtk_scrolled_window_adjustment_value_changed, + scrolled_window); + g_signal_handlers_disconnect_by_func (gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar)), + gtk_scrolled_window_expose_scrollbars, + scrolled_window); gtk_widget_unparent (scrolled_window->vscrollbar); gtk_widget_destroy (scrolled_window->vscrollbar); @@ -1283,6 +1261,12 @@ gtk_scrolled_window_destroy (GtkObject *object) priv->button_press_event = NULL; } + if (priv->opacity) + { + g_object_unref (priv->opacity); + priv->opacity = NULL; + } + GTK_OBJECT_CLASS (gtk_scrolled_window_parent_class)->destroy (object); } @@ -1482,11 +1466,23 @@ static gboolean gtk_scrolled_window_expose (GtkWidget *widget, GdkEventExpose *event) { + GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget); GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (widget); if (gtk_widget_is_drawable (widget)) { - if (event->window == priv->overshoot_window) + GdkWindow *hscrollbar_window = NULL; + GdkWindow *vscrollbar_window = NULL; + + if (scrolled_window->hscrollbar) + hscrollbar_window = gtk_widget_get_window (scrolled_window->hscrollbar); + + if (scrolled_window->vscrollbar) + vscrollbar_window = gtk_widget_get_window (scrolled_window->vscrollbar); + + if (event->window == priv->overshoot_window || + event->window == hscrollbar_window || + event->window == vscrollbar_window) GTK_WIDGET_CLASS (gtk_scrolled_window_parent_class)->expose_event (widget, event); else gtk_scrolled_window_paint (widget, &event->area); @@ -1935,8 +1931,7 @@ gtk_scrolled_window_size_allocate (GtkWidget *widget, priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window); bin = GTK_BIN (scrolled_window); - if (priv->overlay_scrollbars) - gtk_scrolled_window_expose_scrollbars (NULL, scrolled_window); + gtk_scrolled_window_expose_scrollbars (NULL, scrolled_window); scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window); gtk_widget_style_get (widget, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL); @@ -3108,12 +3103,9 @@ gtk_scrolled_window_add (GtkContainer *container, g_warning ("gtk_scrolled_window_add(): cannot add non scrollable widget " "use gtk_scrolled_window_add_with_viewport() instead"); - if (priv->overlay_scrollbars) - { - g_signal_connect_after (child, "expose-event", - G_CALLBACK (gtk_scrolled_window_child_expose), - container); - } + g_signal_connect_after (child, "expose-event", + G_CALLBACK (gtk_scrolled_window_child_expose), + container); } static void @@ -3128,12 +3120,9 @@ gtk_scrolled_window_remove (GtkContainer *container, priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (container); - if (priv->overlay_scrollbars) - { - g_signal_handlers_disconnect_by_func (child, - gtk_scrolled_window_child_expose, - container); - } + g_signal_handlers_disconnect_by_func (child, + gtk_scrolled_window_child_expose, + container); gtk_widget_set_scroll_adjustments (child, NULL, NULL); @@ -3624,6 +3613,9 @@ gtk_scrolled_window_child_expose (GtkWidget *widget, GdkRectangle hslider_rect; cairo_t *cr; + if (!priv->overlay_scrollbars) + return FALSE; + cr = gdk_cairo_create (eevent->window); gdk_cairo_region (cr, eevent->region); cairo_clip (cr); @@ -3769,27 +3761,32 @@ static void gtk_scrolled_window_expose_scrollbars (GtkAdjustment *adj, GtkScrolledWindow *scrolled_window) { - GtkWidget *child = gtk_bin_get_child (GTK_BIN (scrolled_window)); + GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (scrolled_window); - if (child && gtk_widget_get_visible (child)) + if (priv->overlay_scrollbars) { - GtkAllocation alloc; - - gtk_widget_get_allocation (child, &alloc); - - if (scrolled_window->vscrollbar) - gtk_widget_queue_draw_area (child, - alloc.width - 20, - 0, - 20, - alloc.height); + GtkWidget *child = gtk_bin_get_child (GTK_BIN (scrolled_window)); - if (scrolled_window->hscrollbar) - gtk_widget_queue_draw_area (child, - 0, - alloc.height - 20, - alloc.width, - 20); + if (child && gtk_widget_get_visible (child)) + { + GtkAllocation alloc; + + gtk_widget_get_allocation (child, &alloc); + + if (scrolled_window->vscrollbar) + gtk_widget_queue_draw_area (child, + alloc.width - 20, + 0, + 20, + alloc.height); + + if (scrolled_window->hscrollbar) + gtk_widget_queue_draw_area (child, + 0, + alloc.height - 20, + alloc.width, + 20); + } } } @@ -3798,17 +3795,14 @@ gtk_scrolled_window_overlay_scrollbars_changed (GtkSettings *settings, GParamSpec *arg, gpointer user_data) { - GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (user_data); GtkScrolledWindowPrivate *priv = GTK_SCROLLED_WINDOW_GET_PRIVATE (user_data); - /* FIXME: tear down/set up things to make the switch */ - g_object_get (settings, "gtk-enable-overlay-scrollbars", &priv->overlay_scrollbars, NULL); - g_print ("enable-overlay-scrollbar is now: %d\n", priv->overlay_scrollbars); + gtk_widget_queue_resize (user_data); } #define __GTK_SCROLLED_WINDOW_C__ -- 1.7.10.2 (Apple Git-33)