diff options
author | Michael Natterer <mitch@gimp.org> | 2010-04-15 13:03:43 +0200 |
---|---|---|
committer | Michael Natterer <mitch@gimp.org> | 2010-04-15 13:03:43 +0200 |
commit | ece97b23597b8ec3c761d3d90030876b81ca7b09 (patch) | |
tree | 3fb50b8241669f7b7b3b5f2290b3a9885fe9a842 /gtk/gtktooltip.c | |
parent | fdf936b5ad62818a6e9dfc4b906175de94af8224 (diff) | |
download | gtk+-ece97b23597b8ec3c761d3d90030876b81ca7b09.tar.gz |
Bug 615162 - Fix tooltips on offscreen widgets
Fix the "widget under pointer" logic and keyboard tooltip positioning
to do the right thing on offscreen widgets.
Diffstat (limited to 'gtk/gtktooltip.c')
-rw-r--r-- | gtk/gtktooltip.c | 86 |
1 files changed, 59 insertions, 27 deletions
diff --git a/gtk/gtktooltip.c b/gtk/gtktooltip.c index 87871e885c..5cc2334c31 100644 --- a/gtk/gtktooltip.c +++ b/gtk/gtktooltip.c @@ -20,6 +20,10 @@ */ #include "config.h" + +#include <math.h> +#include <string.h> + #include "gtktooltip.h" #include "gtkintl.h" #include "gtkwindow.h" @@ -31,8 +35,6 @@ #include "gtkalias.h" -#include <string.h> - #undef DEBUG_TOOLTIP @@ -472,9 +474,9 @@ gtk_tooltip_trigger_tooltip_query (GdkDisplay *display) event.motion.y = y; event.motion.is_hint = FALSE; - gdk_window_get_origin (window, &x, &y); - event.motion.x_root = event.motion.x + x; - event.motion.y_root = event.motion.y + y; + gdk_window_get_root_coords (window, x, y, &x, &y); + event.motion.x_root = x; + event.motion.y_root = y; _gtk_tooltip_handle_event (&event); } @@ -674,13 +676,15 @@ find_widget_under_pointer (GdkWindow *window, */ while (window && window != event_widget->window) { - gint px, py; + gdouble px, py; - gdk_window_get_position (window, &px, &py); - child_loc.x += px; - child_loc.y += py; + gdk_window_coords_to_parent (window, + child_loc.x, child_loc.y, + &px, &py); + child_loc.x = px; + child_loc.y = py; - window = gdk_window_get_parent (window); + window = gdk_window_get_effective_parent (window); } /* Failing to find widget->window can happen for e.g. a detached handle box; @@ -860,6 +864,39 @@ gtk_tooltip_run_requery (GtkWidget **widget, } static void +get_bounding_box (GtkWidget *widget, + GdkRectangle *bounds) +{ + GdkWindow *window; + gint x, y; + gint w, h; + gint x1, y1; + gint x2, y2; + gint x3, y3; + gint x4, y4; + + window = gtk_widget_get_parent_window (widget); + + x = widget->allocation.x; + y = widget->allocation.y; + w = widget->allocation.width; + h = widget->allocation.height; + + gdk_window_get_root_coords (window, x, y, &x1, &y1); + gdk_window_get_root_coords (window, x + w, y, &x2, &y2); + gdk_window_get_root_coords (window, x, y + h, &x3, &y3); + gdk_window_get_root_coords (window, x + w, y + h, &x4, &y4); + +#define MIN4(a,b,c,d) MIN(MIN(a,b),MIN(c,d)) +#define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d)) + + bounds->x = floor (MIN4 (x1, x2, x3, x4)); + bounds->y = floor (MIN4 (y1, y2, y3, y4)); + bounds->width = ceil (MAX4 (x1, x2, x3, x4)) - bounds->x; + bounds->height = ceil (MAX4 (y1, y2, y3, y4)) - bounds->y; +} + +static void gtk_tooltip_position (GtkTooltip *tooltip, GdkDisplay *display, GtkWidget *new_tooltip_widget) @@ -873,18 +910,15 @@ gtk_tooltip_position (GtkTooltip *tooltip, /* FIXME: should we swap this when RTL is enabled? */ if (tooltip->keyboard_mode_enabled) { - gdk_window_get_origin (new_tooltip_widget->window, &x, &y); - if (!gtk_widget_get_has_window (new_tooltip_widget)) - { - x += new_tooltip_widget->allocation.x; - y += new_tooltip_widget->allocation.y; - } + GdkRectangle bounds; + + get_bounding_box (new_tooltip_widget, &bounds); /* For keyboard mode we position the tooltip below the widget, * right of the center of the widget. */ - x += new_tooltip_widget->allocation.width / 2; - y += new_tooltip_widget->allocation.height + 4; + x = bounds.x + bounds.width / 2; + y = bounds.y + bounds.height + 4; } else { @@ -960,14 +994,18 @@ gtk_tooltip_show_tooltip (GdkDisplay *display) } else { + gint tx, ty; + window = tooltip->last_window; if (!GDK_IS_WINDOW (window)) return; - gdk_window_get_origin (window, &x, &y); - x = tooltip->last_x - x; - y = tooltip->last_y - y; + gdk_window_get_pointer (window, &x, &y, NULL); + + gdk_window_get_root_coords (window, x, y, &tx, &ty); + tooltip->last_x = tx; + tooltip->last_y = ty; pointer_widget = tooltip_widget = find_widget_under_pointer (window, &x, &y); @@ -1290,9 +1328,6 @@ _gtk_tooltip_handle_event (GdkEvent *event) if (current_tooltip) { gtk_tooltip_set_last_window (current_tooltip, event->any.window); - gdk_event_get_root_coords (event, - ¤t_tooltip->last_x, - ¤t_tooltip->last_y); } if (current_tooltip && current_tooltip->keyboard_mode_enabled) @@ -1398,9 +1433,6 @@ _gtk_tooltip_handle_event (GdkEvent *event) current_tooltip); gtk_tooltip_set_last_window (current_tooltip, event->any.window); - gdk_event_get_root_coords (event, - ¤t_tooltip->last_x, - ¤t_tooltip->last_y); gtk_tooltip_start_delay (display); } |