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:
		
				
					committed by
					
						
						Kristian Rietveld
					
				
			
			
				
	
			
			
			
						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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user