mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 13:41:07 +00:00
Fix #457642, reported by Christian Persch.
2007-08-21 Kristian Rietveld <kris@imendio.com> Fix #457642, reported by Christian Persch. * gtk/gtktooltip.c: added debugging output which can be compiled in with a #define, annotated all coordinate translations in the source code, (find_widget_under_pointer): remove the "no-window correction"; always convert the coordinates from window relative to allocation relative; after recursing through a container, translate the coordinates from container allocation relative to child widget allocation relative; (find_topmost_widget_from_event): now we get allocation relative coordinates here we do not have to distinguish no-window and window widgets. svn path=/trunk/; revision=18663
This commit is contained in:
parent
cefd6732fc
commit
f6235caef9
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
||||
2007-08-21 Kristian Rietveld <kris@imendio.com>
|
||||
|
||||
Fix #457642, reported by Christian Persch.
|
||||
|
||||
* gtk/gtktooltip.c: added debugging output which can be compiled
|
||||
in with a #define, annotated all coordinate translations in the
|
||||
source code,
|
||||
(find_widget_under_pointer): remove the "no-window correction";
|
||||
always convert the coordinates from window relative to allocation
|
||||
relative; after recursing through a container, translate the
|
||||
coordinates from container allocation relative to child widget
|
||||
allocation relative;
|
||||
(find_topmost_widget_from_event): now we get allocation relative
|
||||
coordinates here we do not have to distinguish no-window and window
|
||||
widgets.
|
||||
|
||||
2007-08-18 Cody Russell <bratsche@gnome.org>
|
||||
|
||||
* gtk/gtkimcontextsimple.c: Fixed incorrect compose mapping
|
||||
|
104
gtk/gtktooltip.c
104
gtk/gtktooltip.c
@ -33,6 +33,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef DEBUG_TOOLTIP
|
||||
|
||||
|
||||
#define GTK_TOOLTIP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TOOLTIP, GtkTooltipClass))
|
||||
#define GTK_IS_TOOLTIP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TOOLTIP))
|
||||
@ -456,11 +458,27 @@ child_location_foreach (GtkWidget *child,
|
||||
if (!GTK_WIDGET_DRAWABLE (child))
|
||||
return;
|
||||
|
||||
/* (child_loc->x, child_loc->y) are relative to
|
||||
* child_loc->container's allocation.
|
||||
*/
|
||||
|
||||
if (!child_loc->child &&
|
||||
gtk_widget_translate_coordinates (child_loc->container, child,
|
||||
child_loc->x, child_loc->y,
|
||||
&x, &y))
|
||||
{
|
||||
#ifdef DEBUG_TOOLTIP
|
||||
g_print ("candidate: %s alloc=[(%d,%d) %dx%d] (%d, %d)->(%d, %d)\n",
|
||||
gtk_widget_get_name (child),
|
||||
child->allocation.x,
|
||||
child->allocation.y,
|
||||
child->allocation.width,
|
||||
child->allocation.height,
|
||||
child_loc->x, child_loc->y,
|
||||
x, y);
|
||||
#endif /* DEBUG_TOOLTIP */
|
||||
|
||||
/* (x, y) relative to child's allocation. */
|
||||
if (x >= 0 && x < child->allocation.width
|
||||
&& y >= 0 && y < child->allocation.height)
|
||||
{
|
||||
@ -468,6 +486,9 @@ child_location_foreach (GtkWidget *child,
|
||||
{
|
||||
struct ChildLocation tmp = { NULL, NULL, 0, 0 };
|
||||
|
||||
/* Take (x, y) relative the child's allocation and
|
||||
* recurse.
|
||||
*/
|
||||
tmp.x = x;
|
||||
tmp.y = y;
|
||||
tmp.container = child;
|
||||
@ -486,6 +507,9 @@ child_location_foreach (GtkWidget *child,
|
||||
}
|
||||
}
|
||||
|
||||
/* Translates coordinates from dest_widget->window relative (src_x, src_y),
|
||||
* to allocation relative (dest_x, dest_y) of dest_widget.
|
||||
*/
|
||||
static void
|
||||
window_to_alloc (GtkWidget *dest_widget,
|
||||
gint src_x,
|
||||
@ -499,6 +523,9 @@ window_to_alloc (GtkWidget *dest_widget,
|
||||
gint wx, wy;
|
||||
gdk_window_get_position (dest_widget->window, &wx, &wy);
|
||||
|
||||
/* Offset coordinates if widget->window is smaller than
|
||||
* widget->allocation.
|
||||
*/
|
||||
src_x += wx - dest_widget->allocation.x;
|
||||
src_y += wy - dest_widget->allocation.y;
|
||||
}
|
||||
@ -514,6 +541,9 @@ window_to_alloc (GtkWidget *dest_widget,
|
||||
*dest_y = src_y;
|
||||
}
|
||||
|
||||
/* Translates coordinates from window relative (x, y) to
|
||||
* allocation relative (x, y) of the returned widget.
|
||||
*/
|
||||
static GtkWidget *
|
||||
find_widget_under_pointer (GdkWindow *window,
|
||||
gint *x,
|
||||
@ -527,9 +557,20 @@ find_widget_under_pointer (GdkWindow *window,
|
||||
if (!event_widget)
|
||||
return NULL;
|
||||
|
||||
#ifdef DEBUG_TOOLTIP
|
||||
g_print ("event window %p (belonging to %p (%s)) (%d, %d)\n",
|
||||
window, event_widget, gtk_widget_get_name (event_widget),
|
||||
*x, *y);
|
||||
#endif
|
||||
|
||||
/* Coordinates are relative to event window */
|
||||
child_loc.x = *x;
|
||||
child_loc.y = *y;
|
||||
|
||||
/* We go down the window hierarchy to the widget->window,
|
||||
* coordinates stay relative to the current window.
|
||||
* We end up with window == widget->window, coordinates relative to that.
|
||||
*/
|
||||
while (window && window != event_widget->window)
|
||||
{
|
||||
gint px, py;
|
||||
@ -541,12 +582,6 @@ find_widget_under_pointer (GdkWindow *window,
|
||||
window = gdk_window_get_parent (window);
|
||||
}
|
||||
|
||||
if (GTK_WIDGET_NO_WINDOW (event_widget))
|
||||
{
|
||||
child_loc.x += event_widget->allocation.x;
|
||||
child_loc.y += event_widget->allocation.y;
|
||||
}
|
||||
|
||||
/* Failing to find widget->window can happen for e.g. a detached handle box;
|
||||
* chaining ::query-tooltip up to its parent probably makes little sense,
|
||||
* and users better implement tooltips on handle_box->child.
|
||||
@ -555,11 +590,16 @@ find_widget_under_pointer (GdkWindow *window,
|
||||
if (!window)
|
||||
return NULL;
|
||||
|
||||
/* Convert the window relative coordinates to allocation
|
||||
* relative coordinates.
|
||||
*/
|
||||
window_to_alloc (event_widget,
|
||||
child_loc.x, child_loc.y,
|
||||
&child_loc.x, &child_loc.y);
|
||||
|
||||
if (GTK_IS_CONTAINER (event_widget))
|
||||
{
|
||||
window_to_alloc (event_widget,
|
||||
child_loc.x, child_loc.y,
|
||||
&child_loc.x, &child_loc.y);
|
||||
GtkWidget *container = event_widget;
|
||||
|
||||
child_loc.container = event_widget;
|
||||
child_loc.child = NULL;
|
||||
@ -567,12 +607,23 @@ find_widget_under_pointer (GdkWindow *window,
|
||||
gtk_container_forall (GTK_CONTAINER (event_widget),
|
||||
child_location_foreach, &child_loc);
|
||||
|
||||
/* Here we have a widget, with coordinates relative to
|
||||
* child_loc.container's allocation.
|
||||
*/
|
||||
|
||||
if (child_loc.child)
|
||||
event_widget = child_loc.child;
|
||||
else if (child_loc.container)
|
||||
event_widget = child_loc.container;
|
||||
|
||||
/* Translate to event_widget's allocation */
|
||||
gtk_widget_translate_coordinates (container, event_widget,
|
||||
child_loc.x, child_loc.y,
|
||||
&child_loc.x, &child_loc.y);
|
||||
|
||||
}
|
||||
|
||||
/* We return (x, y) relative to the allocation of event_widget. */
|
||||
if (x)
|
||||
*x = child_loc.x;
|
||||
if (y)
|
||||
@ -581,6 +632,9 @@ find_widget_under_pointer (GdkWindow *window,
|
||||
return event_widget;
|
||||
}
|
||||
|
||||
/* Ignores (x, y) on input, translates event coordinates to
|
||||
* allocation relative (x, y) of the returned widget.
|
||||
*/
|
||||
static GtkWidget *
|
||||
find_topmost_widget_coords_from_event (GdkEvent *event,
|
||||
gint *x,
|
||||
@ -594,26 +648,16 @@ find_topmost_widget_coords_from_event (GdkEvent *event,
|
||||
tx = dx;
|
||||
ty = dy;
|
||||
|
||||
/* Returns coordinates relative to tmp's allocation. */
|
||||
tmp = find_widget_under_pointer (event->any.window, &tx, &ty);
|
||||
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
/* Make sure the pointer can actually be on the widget returned */
|
||||
if (GTK_WIDGET_NO_WINDOW (tmp))
|
||||
{
|
||||
if (tx < tmp->allocation.x ||
|
||||
tx >= tmp->allocation.x + tmp->allocation.width ||
|
||||
ty < tmp->allocation.y ||
|
||||
ty >= tmp->allocation.y + tmp->allocation.height)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tx < 0 || tx >= tmp->allocation.width ||
|
||||
ty < 0 || ty >= tmp->allocation.height)
|
||||
return NULL;
|
||||
}
|
||||
/* Make sure the pointer can actually be on the widget returned. */
|
||||
if (tx < 0 || tx >= tmp->allocation.width ||
|
||||
ty < 0 || ty >= tmp->allocation.height)
|
||||
return NULL;
|
||||
|
||||
if (x)
|
||||
*x = tx;
|
||||
@ -1093,6 +1137,7 @@ _gtk_tooltip_handle_event (GdkEvent *event)
|
||||
if (touchscreen)
|
||||
return;
|
||||
|
||||
/* Returns coordinates relative to has_tooltip_widget's allocation. */
|
||||
has_tooltip_widget = find_topmost_widget_coords_from_event (event, &x, &y);
|
||||
display = gdk_drawable_get_display (event->any.window);
|
||||
current_tooltip = g_object_get_data (G_OBJECT (display),
|
||||
@ -1124,6 +1169,17 @@ _gtk_tooltip_handle_event (GdkEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TOOLTIP
|
||||
if (has_tooltip_widget)
|
||||
g_print ("%p (%s) at (%d, %d) %dx%d pointer: (%d, %d)\n",
|
||||
has_tooltip_widget, gtk_widget_get_name (has_tooltip_widget),
|
||||
has_tooltip_widget->allocation.x,
|
||||
has_tooltip_widget->allocation.y,
|
||||
has_tooltip_widget->allocation.width,
|
||||
has_tooltip_widget->allocation.height,
|
||||
x, y);
|
||||
#endif /* DEBUG_TOOLTIP */
|
||||
|
||||
/* Always poll for a next motion event */
|
||||
gdk_event_request_motions (&event->motion);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user