Blame SOURCES/tooltip-positioning.patch

f95c2c
diff --git a/gtk/gtktooltip.c b/gtk/gtktooltip.c
f95c2c
index 5cc2334..204a2b6 100644
f95c2c
--- a/gtk/gtktooltip.c
f95c2c
+++ b/gtk/gtktooltip.c
f95c2c
@@ -903,53 +903,128 @@ gtk_tooltip_position (GtkTooltip *tooltip,
f95c2c
 {
f95c2c
   gint x, y;
f95c2c
   GdkScreen *screen;
f95c2c
+  gint monitor_num;
f95c2c
+  GdkRectangle monitor;
f95c2c
+  GtkRequisition requisition;
f95c2c
+  guint cursor_size;
f95c2c
+  GdkRectangle bounds;
f95c2c
+
f95c2c
+#define MAX_DISTANCE 32
f95c2c
 
f95c2c
   tooltip->tooltip_widget = new_tooltip_widget;
f95c2c
 
f95c2c
+  screen = gtk_widget_get_screen (new_tooltip_widget);
f95c2c
+
f95c2c
+  gtk_widget_size_request (GTK_WIDGET (tooltip->current_window), &requisition);
f95c2c
+
f95c2c
+  monitor_num = gdk_screen_get_monitor_at_point (screen,
f95c2c
+                                                 tooltip->last_x,
f95c2c
+                                                 tooltip->last_y);
f95c2c
+  gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
f95c2c
+
f95c2c
+  get_bounding_box (new_tooltip_widget, &bounds);
f95c2c
+
f95c2c
   /* Position the tooltip */
f95c2c
-  /* FIXME: should we swap this when RTL is enabled? */
f95c2c
-  if (tooltip->keyboard_mode_enabled)
f95c2c
+
f95c2c
+  cursor_size = gdk_display_get_default_cursor_size (display);
f95c2c
+
f95c2c
+  /* Try below */
f95c2c
+  x = bounds.x + bounds.width / 2 - requisition.width / 2;
f95c2c
+  y = bounds.y + bounds.height + 4;
f95c2c
+
f95c2c
+  if (y + requisition.height <= monitor.y + monitor.height)
f95c2c
     {
f95c2c
-      GdkRectangle bounds;
f95c2c
+      if (tooltip->keyboard_mode_enabled)
f95c2c
+        goto found;
f95c2c
 
f95c2c
-      get_bounding_box (new_tooltip_widget, &bounds);
f95c2c
+      if (y <= tooltip->last_y + cursor_size + MAX_DISTANCE)
f95c2c
+        {
f95c2c
+          if (tooltip->last_x + cursor_size + MAX_DISTANCE < x)
f95c2c
+            x = tooltip->last_x + cursor_size + MAX_DISTANCE;
f95c2c
+          else if (x + requisition.width < tooltip->last_x - MAX_DISTANCE)
f95c2c
+            x = tooltip->last_x - MAX_DISTANCE - requisition.width;
f95c2c
 
f95c2c
-      /* For keyboard mode we position the tooltip below the widget,
f95c2c
-       * right of the center of the widget.
f95c2c
-       */
f95c2c
-      x = bounds.x + bounds.width / 2;
f95c2c
-      y = bounds.y + bounds.height + 4;
f95c2c
+          goto found;
f95c2c
+        }
f95c2c
+   }
f95c2c
+
f95c2c
+  /* Try above */
f95c2c
+  x = bounds.x + bounds.width / 2 - requisition.width / 2;
f95c2c
+  y = bounds.y - requisition.height - 4;
f95c2c
+
f95c2c
+  if (y >= monitor.y)
f95c2c
+    {
f95c2c
+      if (tooltip->keyboard_mode_enabled)
f95c2c
+        goto found;
f95c2c
+
f95c2c
+      if (y + requisition.height >= tooltip->last_y - MAX_DISTANCE)
f95c2c
+        {
f95c2c
+          if (tooltip->last_x + cursor_size + MAX_DISTANCE < x)
f95c2c
+            x = tooltip->last_x + cursor_size + MAX_DISTANCE;
f95c2c
+          else if (x + requisition.width < tooltip->last_x - MAX_DISTANCE)
f95c2c
+            x = tooltip->last_x - MAX_DISTANCE - requisition.width;
f95c2c
+
f95c2c
+          goto found;
f95c2c
+        }
f95c2c
     }
f95c2c
-  else
f95c2c
+
f95c2c
+  /* Try right FIXME: flip on rtl ? */
f95c2c
+  x = bounds.x + bounds.width + 4;
f95c2c
+  y = bounds.y + bounds.height / 2 - requisition.height / 2;
f95c2c
+
f95c2c
+  if (x + requisition.width <= monitor.x + monitor.width)
f95c2c
     {
f95c2c
-      guint cursor_size;
f95c2c
+      if (tooltip->keyboard_mode_enabled)
f95c2c
+        goto found;
f95c2c
 
f95c2c
-      x = tooltip->last_x;
f95c2c
-      y = tooltip->last_y;
f95c2c
+      if (x <= tooltip->last_x + cursor_size + MAX_DISTANCE)
f95c2c
+        {
f95c2c
+          if (tooltip->last_y + cursor_size + MAX_DISTANCE < y)
f95c2c
+            y = tooltip->last_y + cursor_size + MAX_DISTANCE;
f95c2c
+          else if (y + requisition.height < tooltip->last_y - MAX_DISTANCE)
f95c2c
+            y = tooltip->last_y - MAX_DISTANCE - requisition.height;
f95c2c
 
f95c2c
-      /* For mouse mode, we position the tooltip right of the cursor,
f95c2c
-       * a little below the cursor's center.
f95c2c
-       */
f95c2c
-      cursor_size = gdk_display_get_default_cursor_size (display);
f95c2c
-      x += cursor_size / 2;
f95c2c
-      y += cursor_size / 2;
f95c2c
+          goto found;
f95c2c
+        }
f95c2c
     }
f95c2c
 
f95c2c
-  screen = gtk_widget_get_screen (new_tooltip_widget);
f95c2c
+  /* Try left FIXME: flip on rtl ? */
f95c2c
+  x = bounds.x - requisition.width - 4;
f95c2c
+  y = bounds.y + bounds.height / 2 - requisition.height / 2;
f95c2c
 
f95c2c
-  /* Show it */
f95c2c
-  if (tooltip->current_window)
f95c2c
+  if (x >= monitor.x)
f95c2c
     {
f95c2c
-      gint monitor_num;
f95c2c
-      GdkRectangle monitor;
f95c2c
-      GtkRequisition requisition;
f95c2c
+      if (tooltip->keyboard_mode_enabled)
f95c2c
+        goto found;
f95c2c
 
f95c2c
-      gtk_widget_size_request (GTK_WIDGET (tooltip->current_window),
f95c2c
-                               &requisition);
f95c2c
+      if (x + requisition.width >= tooltip->last_x - MAX_DISTANCE)
f95c2c
+        {
f95c2c
+          if (tooltip->last_y + cursor_size + MAX_DISTANCE < y)
f95c2c
+            y = tooltip->last_y + cursor_size + MAX_DISTANCE;
f95c2c
+          else if (y + requisition.height < tooltip->last_y - MAX_DISTANCE)
f95c2c
+            y = tooltip->last_y - MAX_DISTANCE - requisition.height;
f95c2c
 
f95c2c
-      monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
f95c2c
-      gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
f95c2c
+          goto found;
f95c2c
+        }
f95c2c
+    }
f95c2c
 
f95c2c
+   /* Fallback */
f95c2c
+  if (tooltip->keyboard_mode_enabled)
f95c2c
+    {
f95c2c
+      x = bounds.x + bounds.width / 2 - requisition.width / 2;
f95c2c
+      y = bounds.y + bounds.height + 4;
f95c2c
+    }
f95c2c
+  else
f95c2c
+    {
f95c2c
+      /* At cursor */
f95c2c
+      x = tooltip->last_x + cursor_size * 3 / 4;
f95c2c
+      y = tooltip->last_y + cursor_size * 3 / 4;
f95c2c
+    }
f95c2c
+
f95c2c
+found:
f95c2c
+  /* Show it */
f95c2c
+  if (tooltip->current_window)
f95c2c
+    {
f95c2c
       if (x + requisition.width > monitor.x + monitor.width)
f95c2c
         x -= x - (monitor.x + monitor.width) + requisition.width;
f95c2c
       else if (x < monitor.x)
f95c2c
@@ -957,7 +1032,9 @@ gtk_tooltip_position (GtkTooltip *tooltip,
f95c2c
 
f95c2c
       if (y + requisition.height > monitor.y + monitor.height)
f95c2c
         y -= y - (monitor.y + monitor.height) + requisition.height;
f95c2c
-  
f95c2c
+      else if (y < monitor.y)
f95c2c
+        y = monitor.y;
f95c2c
+
f95c2c
       if (!tooltip->keyboard_mode_enabled)
f95c2c
         {
f95c2c
           /* don't pop up under the pointer */
f95c2c
@@ -965,7 +1042,7 @@ gtk_tooltip_position (GtkTooltip *tooltip,
f95c2c
               y <= tooltip->last_y && tooltip->last_y < y + requisition.height)
f95c2c
             y = tooltip->last_y - requisition.height - 2;
f95c2c
         }
f95c2c
-  
f95c2c
+
f95c2c
       gtk_window_move (GTK_WINDOW (tooltip->current_window), x, y);
f95c2c
       gtk_widget_show (GTK_WIDGET (tooltip->current_window));
f95c2c
     }