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.c
gtk_menu_position() starts at line 4680
There is mention about a hint at line 4721,
* 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:
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.
* Positioning in the vertical direction is similar: first try below
* mouse cursor, then above.
Line 4828 is the vertical 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;
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;
y = monitor.y;
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.