for (f = self; f; f = f->parent)
menu_frame_move(f, f->area.x + dx, f->area.y + dy);
+ for (f = self->child; f; f = f->child)
+ menu_frame_move(f, f->area.x + dx, f->area.y + dy);
XWarpPointer(ob_display, None, None, 0, 0, 0, 0, dx, dy);
}
}
void menu_frame_show(ObMenuFrame *self, ObMenuFrame *parent)
{
+ GList *it;
+
+ if (g_list_find(menu_frame_visible, self))
+ return;
+
if (parent) {
if (parent->child)
menu_frame_hide(parent->child);
grab_keyboard(TRUE);
}
- if (!g_list_find(menu_frame_visible, self)) {
- menu_frame_visible = g_list_prepend(menu_frame_visible, self);
-
+ /* determine if the underlying menu is already visible */
+ for (it = menu_frame_visible; it; it = g_list_next(it)) {
+ ObMenuFrame *f = it->data;
+ if (f->menu == self->menu)
+ break;
+ }
+ if (!it) {
if (self->menu->update_func)
self->menu->update_func(self, self->menu->data);
- menu_frame_update(self);
}
+ menu_frame_visible = g_list_prepend(menu_frame_visible, self);
+ menu_frame_update(self);
+
menu_frame_move_on_screen(self);
XMapWindow(ob_display, self->window);
void menu_frame_hide(ObMenuFrame *self)
{
- menu_frame_visible = g_list_remove(menu_frame_visible, self);
+ GList *it = g_list_find(menu_frame_visible, self);
+
+ if (!it)
+ return;
+
+ menu_frame_visible = g_list_delete_link(menu_frame_visible, it);
if (self->child)
menu_frame_hide(self->child);
void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide)
{
- if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
+ if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
+ self->entry->data.normal.enabled)
+ {
+ /* grab all this shizzle, cuz when the menu gets hidden, 'self'
+ gets freed */
+ ObMenuEntry *entry = self->entry;
+ ObMenuExecuteFunc func = self->frame->menu->execute_func;
+ gpointer data = self->frame->menu->data;
+ GSList *acts = self->entry->data.normal.actions;
+ ObClient *client = self->frame->client;
+
/* release grabs before executing the shit */
menu_frame_hide_all();
- if (self->frame->menu->execute_func)
- self->frame->menu->execute_func(self, self->frame->menu->data);
+ if (func)
+ func(entry, data);
else {
GSList *it;
- for (it = self->entry->data.normal.actions; it;
- it = g_slist_next(it))
+ for (it = acts; it; it = g_slist_next(it))
{
ObAction *act = it->data;
- act->data.any.c = self->frame->client;
+ act->data.any.c = client;
act->func(&act->data);
}
}