+ }
+ return TRUE; /* show the menu */
+}
+
+static void desktop_change_callback(ObClient *c, gpointer data)
+{
+ ObMenuFrame *frame = data;
+ if (c == frame->client) {
+ /* adding/removing entries while it's shown is not fun, so just hide
+ the menu and reshow it */
+ if (frame->parent) {
+ ObMenuEntryFrame *me = frame->parent_entry;
+ ObMenuFrame *parent = frame->parent;
+ menu_frame_select(parent, NULL, TRUE);
+ menu_frame_select(parent, me, TRUE);
+ } else
+ menu_frame_hide(frame);
+ }
+}
+
+static void show_callback(ObMenuFrame *frame, gpointer data)
+{
+ client_add_desktop_notify(desktop_change_callback, frame);
+}
+
+static void hide_callback(ObMenuFrame *frame, gpointer data)
+{
+ client_remove_desktop_notify(desktop_change_callback);
+}
+
+static void client_menu_place(ObMenuFrame *frame, gint *x, gint *y,
+ gint button, gpointer data)
+{
+ gint dx, dy;
+
+ if (button == 0 && frame->client) {
+ *x = frame->client->frame->area.x;
+
+ /* try below the titlebar */
+ *y = frame->client->frame->area.y + frame->client->frame->size.top -
+ frame->client->frame->bwidth;
+ menu_frame_move_on_screen(frame, *x, *y, &dx, &dy);
+ if (dy != 0) {
+ /* try above the titlebar */
+ *y = frame->client->frame->area.y + frame->client->frame->bwidth -
+ frame->area.height;
+ menu_frame_move_on_screen(frame, *x, *y, &dx, &dy);
+ }
+ if (dy != 0) {
+ /* didnt fit either way, use move on screen's values */
+ *y = frame->client->frame->area.y + frame->client->frame->size.top;
+ menu_frame_move_on_screen(frame, *x, *y, &dx, &dy);