diff options
author | Matthias Clasen <mclasen@redhat.com> | 2015-04-06 21:27:17 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2015-04-06 21:27:17 -0400 |
commit | 4c80ac0733289b43377b47fc846507a689747f43 (patch) | |
tree | 9982488b8c62cf692291b82a39f1fe271dbd8187 /gtk/gtkscrolledwindow.c | |
parent | cfb5f160f2d024dc118484bea5e1415f6de250c0 (diff) | |
download | gtk+-4c80ac0733289b43377b47fc846507a689747f43.tar.gz |
Fix indicator proximity checks
The coordinate translations here were not working properly
for window widgets inside the scrolled window, as can be
seen e.g. for the horizontal scrollbar of the 'Tree View'
example in gtk3-demo.
https://bugzilla.gnome.org/show_bug.cgi?id=747406
Diffstat (limited to 'gtk/gtkscrolledwindow.c')
-rw-r--r-- | gtk/gtkscrolledwindow.c | 80 |
1 files changed, 53 insertions, 27 deletions
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 4016122185..b3e66b14aa 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -977,51 +977,77 @@ indicator_set_over (Indicator *indicator, gtk_widget_queue_resize (indicator->scrollbar); } +static void +translate_to_widget (GtkWidget *widget, + GdkEvent *event, + gint *x, + gint *y) +{ + GtkWidget *event_widget; + GdkWindow *event_widget_window; + GdkWindow *window; + gdouble event_x, event_y; + gint wx, wy; + GtkAllocation allocation; + + event_widget = gtk_get_event_widget (event); + event_widget_window = gtk_widget_get_window (event_widget); + gdk_event_get_coords (event, &event_x, &event_y); + window = event->any.window; + while (window && window != event_widget_window) + { + gdk_window_get_position (window, &wx, &wy); + event_x += wx; + event_y += wy; + window = gdk_window_get_effective_parent (window); + } + + if (!gtk_widget_get_has_window (event_widget)) + { + gtk_widget_get_allocation (event_widget, &allocation); + event_x -= allocation.x; + event_y -= allocation.y; + } + + gtk_widget_translate_coordinates (event_widget, widget, + (gint)event_x, (gint)event_y, + x, y); +} + static gboolean event_close_to_indicator (GtkScrolledWindow *sw, Indicator *indicator, GdkEvent *event) { - GtkAllocation alloc, indicator_alloc; GtkScrolledWindowPrivate *priv; - GtkWidget *event_widget; - gint win_x, win_y; - gdouble x, y; + GtkAllocation indicator_alloc; + gint x, y; gint distance; + gint win_x, win_y; priv = sw->priv; - event_widget = gtk_get_event_widget (event); - gdk_event_get_coords (event, &x, &y); - gtk_widget_get_allocation (GTK_WIDGET (sw), &alloc); gtk_widget_get_allocation (indicator->scrollbar, &indicator_alloc); gdk_window_get_position (indicator->window, &win_x, &win_y); - - if (event->any.window == indicator->window || - event_widget == indicator->scrollbar) - { - gint xcoord = x, ycoord = y; - - gtk_widget_translate_coordinates (indicator->scrollbar, - GTK_WIDGET (sw), - xcoord, ycoord, - &xcoord, &ycoord); - x = xcoord; - y = ycoord; - } + translate_to_widget (GTK_WIDGET (sw), event, &x, &y); if (indicator->over) distance = INDICATOR_FAR_DISTANCE; else distance = INDICATOR_CLOSE_DISTANCE; - if ((indicator == &priv->hindicator && - y >= win_y - distance && - y < win_y + indicator_alloc.height + distance) || - (indicator == &priv->vindicator && - x >= win_x - distance && - x < win_x + indicator_alloc.width + distance)) - return TRUE; + if (indicator == &priv->hindicator) + { + if (y >= win_y - distance && + y < win_y + indicator_alloc.height + distance) + return TRUE; + } + else if (indicator == &priv->vindicator) + { + if (x >= win_x - distance && + x < win_x + indicator_alloc.width + distance) + return TRUE; + } return FALSE; } |