diff -up gtk+-2.18.3/gtk/gtktooltip.c.positioning gtk+-2.18.3/gtk/gtktooltip.c
--- gtk+-2.18.3/gtk/gtktooltip.c.positioning	2009-10-23 13:12:16.205437913 -0400
+++ gtk+-2.18.3/gtk/gtktooltip.c	2009-10-23 13:52:15.922749329 -0400
@@ -1023,57 +1023,134 @@ gtk_tooltip_position (GtkTooltip *toolti
 		      GtkWidget  *new_tooltip_widget)
 {
   gint x, y;
+  gint wx, wy;
   GdkScreen *screen;
+  gint monitor_num;
+  GdkRectangle monitor;
+  GtkRequisition requisition;
+  guint cursor_size;
+
+#define MAX_DISTANCE 32
 
   tooltip->tooltip_widget = new_tooltip_widget;
 
+  screen = gtk_widget_get_screen (new_tooltip_widget);
+
+  gtk_widget_size_request (GTK_WIDGET (tooltip->current_window), &requisition);
+
+  monitor_num = gdk_screen_get_monitor_at_point (screen,
+                                                 tooltip->last_x,
+                                                 tooltip->last_y);
+  gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+  gdk_window_get_origin (new_tooltip_widget->window, &wx, &wy);
+  if (GTK_WIDGET_NO_WINDOW (new_tooltip_widget))
+    {
+      wx += new_tooltip_widget->allocation.x;
+      wy += new_tooltip_widget->allocation.y;
+    }
+
   /* Position the tooltip */
-  /* FIXME: should we swap this when RTL is enabled? */
-  if (tooltip->keyboard_mode_enabled)
+
+  cursor_size = gdk_display_get_default_cursor_size (display);
+
+  /* Try below */
+  x = wx + new_tooltip_widget->allocation.width / 2 - requisition.width / 2;
+  y = wy + new_tooltip_widget->allocation.height + 4;
+
+  if (y + requisition.height <= monitor.y + monitor.height)
     {
-      gdk_window_get_origin (new_tooltip_widget->window, &x, &y);
-      if (GTK_WIDGET_NO_WINDOW (new_tooltip_widget))
+      if (tooltip->keyboard_mode_enabled)
+        goto found;
+
+      if (y <= tooltip->last_y + cursor_size + MAX_DISTANCE)
         {
-	  x += new_tooltip_widget->allocation.x;
-	  y += new_tooltip_widget->allocation.y;
-	}
+          if (tooltip->last_x + cursor_size + MAX_DISTANCE < x)
+            x = tooltip->last_x + cursor_size + MAX_DISTANCE;
+          else if (x + requisition.width < tooltip->last_x - MAX_DISTANCE)
+            x = tooltip->last_x - MAX_DISTANCE - requisition.width;
 
-      /* 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;
+          goto found;
+        }
+   }
+
+  /* Try above */
+  x = wx + new_tooltip_widget->allocation.width / 2 - requisition.width / 2;
+  y = wy - requisition.height - 4;
+
+  if (y >= monitor.y)
+    {
+      if (tooltip->keyboard_mode_enabled)
+        goto found;
+
+      if (y + requisition.height >= tooltip->last_y - MAX_DISTANCE)
+        {
+          if (tooltip->last_x + cursor_size + MAX_DISTANCE < x)
+            x = tooltip->last_x + cursor_size + MAX_DISTANCE;
+          else if (x + requisition.width < tooltip->last_x - MAX_DISTANCE)
+            x = tooltip->last_x - MAX_DISTANCE - requisition.width;
+
+          goto found;
+        }
     }
-  else
+
+  /* Try right FIXME: flip on rtl ? */
+  x = wx + new_tooltip_widget->allocation.width + 4;
+  y = wy + new_tooltip_widget->allocation.height / 2 - requisition.height / 2;
+
+  if (x + requisition.width <= monitor.x + monitor.width)
     {
-      guint cursor_size;
+      if (tooltip->keyboard_mode_enabled)
+        goto found;
 
-      x = tooltip->last_x;
-      y = tooltip->last_y;
+      if (x <= tooltip->last_x + cursor_size + MAX_DISTANCE)
+        {
+          if (tooltip->last_y + cursor_size + MAX_DISTANCE < y)
+            y = tooltip->last_y + cursor_size + MAX_DISTANCE;
+          else if (y + requisition.height < tooltip->last_y - MAX_DISTANCE)
+            y = tooltip->last_y - MAX_DISTANCE - requisition.height;
 
-      /* For mouse mode, we position the tooltip right of the cursor,
-       * a little below the cursor's center.
-       */
-      cursor_size = gdk_display_get_default_cursor_size (display);
-      x += cursor_size / 2;
-      y += cursor_size / 2;
+          goto found;
+        }
     }
 
-  screen = gtk_widget_get_screen (new_tooltip_widget);
+  /* Try left FIXME: flip on rtl ? */
+  x = wx - requisition.width - 4;
+  y = wy + new_tooltip_widget->allocation.height / 2 - requisition.height / 2;
 
-  /* Show it */
-  if (tooltip->current_window)
+  if (x >= monitor.x)
     {
-      gint monitor_num;
-      GdkRectangle monitor;
-      GtkRequisition requisition;
+      if (tooltip->keyboard_mode_enabled)
+        goto found;
 
-      gtk_widget_size_request (GTK_WIDGET (tooltip->current_window),
-                               &requisition);
+      if (x + requisition.width >= tooltip->last_x - MAX_DISTANCE)
+        {
+          if (tooltip->last_y + cursor_size + MAX_DISTANCE < y)
+            y = tooltip->last_y + cursor_size + MAX_DISTANCE;
+          else if (y + requisition.height < tooltip->last_y - MAX_DISTANCE)
+            y = tooltip->last_y - MAX_DISTANCE - requisition.height;
 
-      monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
-      gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+          goto found;
+        }
+    }
 
+  /* Fallback */
+  if (tooltip->keyboard_mode_enabled)
+    {
+      x = wx + new_tooltip_widget->allocation.width / 2 - requisition.width / 2;
+      y = wy + new_tooltip_widget->allocation.height + 4;
+    }
+  else
+    {
+      /* At cursor */
+      x = tooltip->last_x + cursor_size * 3 / 4;
+      y = tooltip->last_y + cursor_size * 3 / 4;
+    }
+
+found:
+  /* Show it */
+  if (tooltip->current_window)
+    {
       if (x + requisition.width > monitor.x + monitor.width)
         x -= x - (monitor.x + monitor.width) + requisition.width;
       else if (x < monitor.x)
@@ -1081,7 +1158,9 @@ gtk_tooltip_position (GtkTooltip *toolti
 
       if (y + requisition.height > monitor.y + monitor.height)
         y -= y - (monitor.y + monitor.height) + requisition.height;
-  
+      else if (y < monitor.y)
+        y = monitor.y;
+
       if (!tooltip->keyboard_mode_enabled)
         {
           /* don't pop up under the pointer */
@@ -1089,7 +1168,7 @@ gtk_tooltip_position (GtkTooltip *toolti
               y <= tooltip->last_y && tooltip->last_y < y + requisition.height)
             y = tooltip->last_y - requisition.height - 2;
         }
-  
+
       gtk_window_move (GTK_WINDOW (tooltip->current_window), x, y);
       gtk_widget_show (GTK_WIDGET (tooltip->current_window));
     }
