Commit 51ddf0e1 authored by Matthias Clasen's avatar Matthias Clasen

Better tooltip positioning

Avoid the covering up the widget that you are tipping, as
far as possible. Bug 599618.
parent a473b593
......@@ -903,53 +903,128 @@ gtk_tooltip_position (GtkTooltip *tooltip,
{
gint x, y;
GdkScreen *screen;
gint monitor_num;
GdkRectangle monitor;
GtkRequisition requisition;
guint cursor_size;
GdkRectangle bounds;
#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);
get_bounding_box (new_tooltip_widget, &bounds);
/* 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 = bounds.x + bounds.width / 2 - requisition.width / 2;
y = bounds.y + bounds.height + 4;
if (y + requisition.height <= monitor.y + monitor.height)
{
GdkRectangle bounds;
if (tooltip->keyboard_mode_enabled)
goto found;
get_bounding_box (new_tooltip_widget, &bounds);
if (y <= tooltip->last_y + cursor_size + 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;
/* For keyboard mode we position the tooltip below the widget,
* right of the center of the widget.
*/
x = bounds.x + bounds.width / 2;
y = bounds.y + bounds.height + 4;
goto found;
}
}
/* Try above */
x = bounds.x + bounds.width / 2 - requisition.width / 2;
y = bounds.y - 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 = bounds.x + bounds.width + 4;
y = bounds.y + bounds.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 = bounds.x - requisition.width - 4;
y = bounds.y + bounds.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 = bounds.x + bounds.width / 2 - requisition.width / 2;
y = bounds.y + bounds.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)
......@@ -957,7 +1032,9 @@ gtk_tooltip_position (GtkTooltip *tooltip,
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 */
......@@ -965,7 +1042,7 @@ gtk_tooltip_position (GtkTooltip *tooltip,
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));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment