This is something I'm going to need to do in a few weeks and I'm not sure if it can be done without any tricks. One idea is to cap menu with a clipping region below the pointer to force the menu above, but i think this is more work than the manual approach.
Looking for hints:
http://git.gnome.org/browse/gtk+/tree/gtk/gtkmenu.cgtk_menu_position() starts at line 4680
There is mention about a hint at line 4721,
Code:
* Set the type hint here to allow custom position functions
* to set a different hint
*/
if (!gtk_widget_get_visible (priv->toplevel))
gtk_window_set_type_hint (GTK_WINDOW (priv->toplevel), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
Around line 4744 we see:
Code:
gboolean rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
So, it is possible to change RTL and LTR packing, probably using gtk_widget_set_direction(), but that's still no good for us.
Line 4763:
Code:
* Positioning in the vertical direction is similar: first try below
* mouse cursor, then above.
Line 4828 is the vertical code:
Code:
/* 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 - padding.top;
if (needed_height <= space_above ||
needed_height <= space_below)
{
if (needed_height <= space_below)
y = y - padding.top;
else
y = y + padding.bottom - requisition.height + 1;
y = CLAMP (y, monitor.y,
monitor.y + monitor.height - requisition.height);
}
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
{
y = monitor.y;
}
If we are lucky there is a function that will clamp space_below to 0
if we are not lucky...
Hopefully a solution shows up.