Broken pipe

parent d77b4c14
......@@ -2750,8 +2750,116 @@ gtk_menu_position (GtkMenu *menu)
(* menu->position_func) (menu, &x, &y, &push_in, menu->position_func_data);
else
{
x = CLAMP (x - 2, monitor.x, MAX (monitor.x, monitor.x + monitor.width - requisition.width));
y = CLAMP (y - 2, monitor.y, MAX (monitor.y, monitor.y + monitor.height - requisition.height));
gint space_left, space_right, space_above, space_below;
gint needed_width;
gint needed_height;
gint xthickness = widget->style->xthickness;
gint ythickness = widget->style->ythickness;
gboolean rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
/* The placement of popup menus horizontally works like this (with
* RTL in parentheses)
*
* - If there is enough room to the right (left) of the mouse cursor,
* position the menu there.
*
* - Otherwise, if if there is enough room to the left (right) of the
* mouse cursor, position the menu there.
*
* - Otherwise if the menu is smaller than the monitor, position it
* on the side of the mouse cursor that has the most space available
*
* - Otherwise (if there is simply not enough room for the menu on the
* monitor), position it as far left (right) as possible.
*
* Positioning in the vertical direction is similar: first try below
* mouse cursor, then above.
*/
space_left = x - monitor.x;
space_right = monitor.x + monitor.width - x - 1;
space_above = y - monitor.y;
space_below = monitor.y + monitor.height - y - 1;
/* position horizontally */
/* the amount of space we need to position the menu. Note the
* menu is offset "xthickness" pixels
*/
needed_width = requisition.width - xthickness;
if (needed_width <= space_left ||
needed_width <= space_right)
{
if ((rtl && needed_width <= space_left) ||
(!rtl && needed_width > space_right))
{
/* position left */
x = x + xthickness - requisition.width + 1;
}
else
{
/* position right */
x = x - xthickness;
}
/* x is clamped on-screen further down */
}
else if (requisition.width <= monitor.width)
{
/* the menu is too big to fit on either side of the mouse
* cursor, but smaller than the monitor. Position it on
* the side that has the most space
*/
if (space_left > space_right)
{
/* left justify */
x = monitor.x;
}
else
{
/* right justify */
x = monitor.x + monitor.width - requisition.width;
}
}
else /* menu is simply too big for the monitor */
{
if (rtl)
{
/* right justify */
x = monitor.x + monitor.width - requisition.width;
}
else
{
/* left justify */
x = monitor.x;
}
}
/* Position vertically. The algorithm is the same as above, but
* simpler because we don't have to take RTL into account.
*/
needed_height = requisition.height - ythickness;
if (requisition.height > monitor.height)
{
y = monitor.y;
}
else if (needed_height > space_below && needed_height > space_above)
{
if (space_below >= space_above)
y = monitor.y + monitor.height - requisition.height;
else
y = monitor.y;
}
else
{
if (needed_height <= space_below)
y = y - ythickness;
else
y = y + ythickness - requisition.height + 1;
y = CLAMP (y, monitor.y,
monitor.y + monitor.height - requisition.height);
}
}
scroll_offset = 0;
......
......@@ -37,6 +37,8 @@
#define MENU_ITEM_CLASS(w) GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass)
#define MIN_SUBMENU_ITEM_WIDTH 100
enum {
ACTIVATE,
ACTIVATE_ITEM,
......@@ -508,6 +510,8 @@ gtk_menu_item_size_request (GtkWidget *widget,
requisition->width += child_requisition.height;
requisition->width += arrow_spacing;
requisition->width = MAX (requisition->width, MIN_SUBMENU_ITEM_WIDTH);
}
}
else
......
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