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_get_has_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)); }