+ return TRUE;
+}
+
+gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y)
+{
+ gint dx, dy;
+ guint i;
+
+ if (menu_frame_is_visible(self))
+ return TRUE;
+ if (!menu_frame_show(self))
+ return FALSE;
+
+ menu_frame_place_topmenu(self, x, y);
+
+ /* find the monitor the menu is on */
+ for (i = 0; i < screen_num_monitors; ++i) {
+ Rect *a = screen_physical_area_monitor(i);
+ if (RECT_CONTAINS(*a, x, y)) {
+ self->monitor = i;
+ break;
+ }
+ }
+
+ menu_frame_move_on_screen(self, &dx, &dy);
+ menu_frame_move(self, self->area.x + dx, self->area.y + dy);
+
+ XMapWindow(ob_display, self->window);
+
+ return TRUE;
+}
+
+gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
+ ObMenuEntryFrame *parent_entry)
+{
+ ObMenuEntryFrame *e;
+ gint dx, dy;
+
+ if (menu_frame_is_visible(self))
+ return TRUE;
+
+ self->monitor = parent->monitor;
+ self->parent = parent;
+ self->parent_entry = parent_entry;
+
+ /* set up parent's child to be us */
+ if (parent->child)
+ menu_frame_hide(parent->child);
+ parent->child = self;
+
+ if (!menu_frame_show(self))
+ return FALSE;
+
+ menu_frame_place_submenu(self);
+ menu_frame_move_on_screen(self, &dx, &dy);
+
+ if (dx == 0) {
+ menu_frame_move(self, self->area.x, self->area.y + dy);
+ } else {
+ gboolean dir;
+
+ /* flip the direction in which we're placing submenus */
+ if (dx > 0)
+ dir = TRUE;
+ else
+ dir = FALSE;
+
+ /* if it changed, then replace the menu on the opposite side,
+ and try keep it on the screen too */
+ if (dir != self->direction_right) {
+ self->direction_right = dir;
+ menu_frame_place_submenu(self);
+ menu_frame_move_on_screen(self, &dx, &dy);
+ menu_frame_move(self, self->area.x + dx, self->area.y + dy);
+ }
+ }