X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fmenuframe.c;h=979e834ff60d0f2c8f8edb1db3f04b255e302747;hb=2b8b5da04b14af1639143cc332874c7e1a03a8bb;hp=f87c3c0bb6da15404faa6dcf705207437d09218e;hpb=526560b8a0871cd93f27c32442b3e470ec42ecb3;p=chaz%2Fopenbox diff --git a/openbox/menuframe.c b/openbox/menuframe.c index f87c3c0b..979e834f 100644 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@ -21,6 +21,7 @@ #include "client.h" #include "menu.h" #include "screen.h" +#include "actions.h" #include "grab.h" #include "openbox.h" #include "mainloop.h" @@ -31,6 +32,8 @@ #define SEPARATOR_HEIGHT 3 #define MAX_MENU_WIDTH 400 +#define ITEM_HEIGHT (ob_rr_theme->menu_font_height + 2*PADDING) + #define FRAME_EVENTMASK (ButtonPressMask |ButtonMotionMask | EnterWindowMask |\ LeaveWindowMask) #define ENTRY_EVENTMASK (EnterWindowMask | LeaveWindowMask | \ @@ -41,9 +44,9 @@ GList *menu_frame_visible; static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry, ObMenuFrame *frame); static void menu_entry_frame_free(ObMenuEntryFrame *self); -static void menu_frame_render(ObMenuFrame *self); static void menu_frame_update(ObMenuFrame *self); static gboolean menu_entry_frame_submenu_timeout(gpointer data); +static void menu_frame_hide(ObMenuFrame *self); static Window createWindow(Window parent, gulong mask, XSetWindowAttributes *attrib) @@ -69,7 +72,7 @@ void menu_frame_shutdown(gboolean reconfig) g_hash_table_destroy(menu_frame_map); } -ObMenuFrame* menu_frame_new(ObMenu *menu, ObClient *client) +ObMenuFrame* menu_frame_new(ObMenu *menu, guint show_from, ObClient *client) { ObMenuFrame *self; XSetWindowAttributes attr; @@ -80,11 +83,16 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, ObClient *client) self->selected = NULL; self->client = client; self->direction_right = TRUE; + self->show_from = show_from; attr.event_mask = FRAME_EVENTMASK; self->window = createWindow(RootWindow(ob_display, ob_screen), CWEventMask, &attr); + XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->mbwidth); + XSetWindowBorder(ob_display, self->window, + RrColorPixel(ob_rr_theme->menu_border_color)); + self->a_title = RrAppearanceCopy(ob_rr_theme->a_menu_title); self->a_items = RrAppearanceCopy(ob_rr_theme->a_menu); @@ -122,6 +130,8 @@ static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry, self->entry = entry; self->frame = frame; + menu_entry_ref(entry); + attr.event_mask = ENTRY_EVENTMASK; self->window = createWindow(self->frame->window, CWEventMask, &attr); self->text = createWindow(self->window, 0, NULL); @@ -176,6 +186,8 @@ static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry, static void menu_entry_frame_free(ObMenuEntryFrame *self) { if (self) { + menu_entry_unref(self->entry); + XDestroyWindow(ob_display, self->text); XDestroyWindow(ob_display, self->window); g_hash_table_remove(menu_frame_map, &self->text); @@ -300,7 +312,7 @@ static void menu_frame_place_submenu(ObMenuFrame *self, gint *x, gint *y) *y = self->parent->area.y + self->parent_entry->area.y; if (config_menu_middle) - *y -= (self->area.height - (bwidth * 2) - self->item_h) / 2; + *y -= (self->area.height - (bwidth * 2) - ITEM_HEIGHT) / 2; else *y += overlap; } @@ -332,6 +344,8 @@ void menu_frame_move_on_screen(ObMenuFrame *self, gint x, gint y, *dx = MAX(*dx, a->x - x); *dy = MAX(*dy, a->y - y); } + + g_free(a); } static void menu_entry_frame_render(ObMenuEntryFrame *self) @@ -352,7 +366,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) /* enabled */ (self == self->frame->selected ? self->a_selected : self->a_normal)); - th = self->frame->item_h; + th = ITEM_HEIGHT; break; case OB_MENU_ENTRY_TYPE_SEPARATOR: if (self->entry->data.separator.label) { @@ -387,6 +401,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) text_a->texture[0].data.text.string = self->entry->data.normal.label; if (self->entry->data.normal.shortcut && (self->frame->menu->show_all_shortcuts || + self->entry->data.normal.shortcut_always_show || self->entry->data.normal.shortcut_position > 0)) { text_a->texture[0].data.text.shortcut = TRUE; @@ -402,6 +417,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) sub = self->entry->data.submenu.submenu; text_a->texture[0].data.text.string = sub ? sub->title : ""; if (sub->shortcut && (self->frame->menu->show_all_shortcuts || + sub->shortcut_always_show || sub->shortcut_position > 0)) { text_a->texture[0].data.text.shortcut = TRUE; @@ -422,23 +438,23 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) XMoveResizeWindow(ob_display, self->text, self->frame->text_x, PADDING, self->frame->text_w, - self->frame->item_h - 2*PADDING); + ITEM_HEIGHT - 2*PADDING); text_a->surface.parent = item_a; text_a->surface.parentx = self->frame->text_x; text_a->surface.parenty = PADDING; RrPaint(text_a, self->text, self->frame->text_w, - self->frame->item_h - 2*PADDING); + ITEM_HEIGHT - 2*PADDING); break; case OB_MENU_ENTRY_TYPE_SUBMENU: XMoveResizeWindow(ob_display, self->text, self->frame->text_x, PADDING, - self->frame->text_w - self->frame->item_h, - self->frame->item_h - 2*PADDING); + self->frame->text_w - ITEM_HEIGHT, + ITEM_HEIGHT - 2*PADDING); text_a->surface.parent = item_a; text_a->surface.parentx = self->frame->text_x; text_a->surface.parenty = PADDING; - RrPaint(text_a, self->text, self->frame->text_w - self->frame->item_h, - self->frame->item_h - 2*PADDING); + RrPaint(text_a, self->text, self->frame->text_w - ITEM_HEIGHT, + ITEM_HEIGHT - 2*PADDING); break; case OB_MENU_ENTRY_TYPE_SEPARATOR: if (self->entry->data.separator.label != NULL) { @@ -480,23 +496,25 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) { XMoveResizeWindow(ob_display, self->icon, PADDING, frame->item_margin.top, - self->frame->item_h - frame->item_margin.top + ITEM_HEIGHT - frame->item_margin.top - frame->item_margin.bottom, - self->frame->item_h - frame->item_margin.top + ITEM_HEIGHT - frame->item_margin.top - frame->item_margin.bottom); self->a_icon->texture[0].data.rgba.width = self->entry->data.normal.icon_width; self->a_icon->texture[0].data.rgba.height = self->entry->data.normal.icon_height; + self->a_icon->texture[0].data.rgba.alpha = + self->entry->data.normal.icon_alpha; self->a_icon->texture[0].data.rgba.data = self->entry->data.normal.icon_data; self->a_icon->surface.parent = item_a; self->a_icon->surface.parentx = PADDING; self->a_icon->surface.parenty = frame->item_margin.top; RrPaint(self->a_icon, self->icon, - self->frame->item_h - frame->item_margin.top + ITEM_HEIGHT - frame->item_margin.top - frame->item_margin.bottom, - self->frame->item_h - frame->item_margin.top + ITEM_HEIGHT - frame->item_margin.top - frame->item_margin.bottom); XMapWindow(ob_display, self->icon); } else if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && @@ -506,9 +524,9 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) XMoveResizeWindow(ob_display, self->icon, PADDING, frame->item_margin.top, - self->frame->item_h - frame->item_margin.top + ITEM_HEIGHT - frame->item_margin.top - frame->item_margin.bottom, - self->frame->item_h - frame->item_margin.top + ITEM_HEIGHT - frame->item_margin.top - frame->item_margin.bottom); self->a_mask->texture[0].data.mask.mask = self->entry->data.normal.mask; @@ -529,9 +547,9 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) self->a_mask->surface.parentx = PADDING; self->a_mask->surface.parenty = frame->item_margin.top; RrPaint(self->a_mask, self->icon, - self->frame->item_h - frame->item_margin.top + ITEM_HEIGHT - frame->item_margin.top - frame->item_margin.bottom, - self->frame->item_h - frame->item_margin.top + ITEM_HEIGHT - frame->item_margin.top - frame->item_margin.bottom); XMapWindow(ob_display, self->icon); } else @@ -540,21 +558,20 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) if (self->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) { RrAppearance *bullet_a; XMoveResizeWindow(ob_display, self->bullet, - self->frame->text_x + self->frame->text_w - - self->frame->item_h + PADDING, PADDING, - self->frame->item_h - 2*PADDING, - self->frame->item_h - 2*PADDING); + self->frame->text_x + self->frame->text_w - + ITEM_HEIGHT + PADDING, PADDING, + ITEM_HEIGHT - 2*PADDING, + ITEM_HEIGHT - 2*PADDING); bullet_a = (self == self->frame->selected ? self->a_bullet_selected : self->a_bullet_normal); bullet_a->surface.parent = item_a; bullet_a->surface.parentx = - self->frame->text_x + self->frame->text_w - self->frame->item_h - + PADDING; + self->frame->text_x + self->frame->text_w - ITEM_HEIGHT + PADDING; bullet_a->surface.parenty = PADDING; RrPaint(bullet_a, self->bullet, - self->frame->item_h - 2*PADDING, - self->frame->item_h - 2*PADDING); + ITEM_HEIGHT - 2*PADDING, + ITEM_HEIGHT - 2*PADDING); XMapWindow(ob_display, self->bullet); } else XUnmapWindow(ob_display, self->bullet); @@ -562,7 +579,51 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) XFlush(ob_display); } -static void menu_frame_render(ObMenuFrame *self) +/*! this code is taken from the menu_frame_render. if that changes, this won't + work.. */ +static gint menu_entry_frame_get_height(ObMenuEntryFrame *self, + gboolean first_entry, + gboolean last_entry) +{ + ObMenuEntryType t; + gint h = 0; + + h += 2*PADDING; + + if (self) + t = self->entry->type; + else + /* this is the More... entry, it's NORMAL type */ + t = OB_MENU_ENTRY_TYPE_NORMAL; + + switch (t) { + case OB_MENU_ENTRY_TYPE_NORMAL: + case OB_MENU_ENTRY_TYPE_SUBMENU: + h += ob_rr_theme->menu_font_height; + break; + case OB_MENU_ENTRY_TYPE_SEPARATOR: + if (self->entry->data.separator.label != NULL) { + h += ob_rr_theme->menu_title_height + + (ob_rr_theme->mbwidth - PADDING) * 2; + + /* if the first entry is a labeled separator, then make its border + overlap with the menu's outside border */ + if (first_entry) + h -= ob_rr_theme->mbwidth; + /* if the last entry is a labeled separator, then make its border + overlap with the menu's outside border */ + if (last_entry) + h -= ob_rr_theme->mbwidth; + } else { + h += SEPARATOR_HEIGHT; + } + break; + } + + return h; +} + +void menu_frame_render(ObMenuFrame *self) { gint w = 0, h = 0; gint tw, th; /* temps */ @@ -571,23 +632,19 @@ static void menu_frame_render(ObMenuFrame *self) ObMenu *sub; ObMenuEntryFrame *e; - XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->mbwidth); - XSetWindowBorder(ob_display, self->window, - RrColorPixel(ob_rr_theme->menu_b_color)); - /* find text dimensions */ STRUT_SET(self->item_margin, 0, 0, 0, 0); if (self->entries) { - ObMenuEntryFrame *e = self->entries->data; gint l, t, r, b; + e = self->entries->data; e->a_text_normal->texture[0].data.text.string = ""; - RrMinSize(e->a_text_normal, &tw, &th); + tw = RrMinWidth(e->a_text_normal); tw += 2*PADDING; - th += 2*PADDING; - self->item_h = th; + + th = ITEM_HEIGHT; RrMargins(e->a_normal, &l, &t, &r, &b); STRUT_SET(self->item_margin, @@ -613,8 +670,7 @@ static void menu_frame_render(ObMenuFrame *self) MAX(self->item_margin.top, t), MAX(self->item_margin.right, r), MAX(self->item_margin.bottom, b)); - } else - self->item_h = 0; + } /* render the entries */ @@ -638,10 +694,11 @@ static void menu_frame_render(ObMenuFrame *self) } RECT_SET_POINT(e->area, 0, h+e->border); - XMoveWindow(ob_display, e->window, e->area.x-e->border, e->area.y-e->border); + XMoveWindow(ob_display, e->window, + e->area.x-e->border, e->area.y-e->border); XSetWindowBorderWidth(ob_display, e->window, e->border); XSetWindowBorder(ob_display, e->window, - RrColorPixel(ob_rr_theme->menu_b_color)); + RrColorPixel(ob_rr_theme->menu_border_color)); text_a = (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && @@ -655,8 +712,9 @@ static void menu_frame_render(ObMenuFrame *self) switch (e->entry->type) { case OB_MENU_ENTRY_TYPE_NORMAL: text_a->texture[0].data.text.string = e->entry->data.normal.label; - RrMinSize(text_a, &tw, &th); + tw = RrMinWidth(text_a); tw = MIN(tw, MAX_MENU_WIDTH); + th = ob_rr_theme->menu_font_height; if (e->entry->data.normal.icon_data || e->entry->data.normal.mask) @@ -665,20 +723,21 @@ static void menu_frame_render(ObMenuFrame *self) case OB_MENU_ENTRY_TYPE_SUBMENU: sub = e->entry->data.submenu.submenu; text_a->texture[0].data.text.string = sub ? sub->title : ""; - RrMinSize(text_a, &tw, &th); + tw = RrMinWidth(text_a); tw = MIN(tw, MAX_MENU_WIDTH); + th = ob_rr_theme->menu_font_height; if (e->entry->data.normal.icon_data || e->entry->data.normal.mask) has_icon = TRUE; - tw += self->item_h - PADDING; + tw += ITEM_HEIGHT - PADDING; break; case OB_MENU_ENTRY_TYPE_SEPARATOR: if (e->entry->data.separator.label != NULL) { e->a_text_title->texture[0].data.text.string = e->entry->data.separator.label; - RrMinSize(e->a_text_title, &tw, &th); + tw = RrMinWidth(e->a_text_title) + 2*ob_rr_theme->paddingx; tw = MIN(tw, MAX_MENU_WIDTH); th = ob_rr_theme->menu_title_height + (ob_rr_theme->mbwidth - PADDING) *2; @@ -709,8 +768,8 @@ static void menu_frame_render(ObMenuFrame *self) if (self->entries) { if (has_icon) { - w += self->item_h + PADDING; - self->text_x += self->item_h + PADDING; + w += ITEM_HEIGHT + PADDING; + self->text_x += ITEM_HEIGHT + PADDING; } } @@ -737,25 +796,35 @@ static void menu_frame_render(ObMenuFrame *self) static void menu_frame_update(ObMenuFrame *self) { GList *mit, *fit; + Rect *a; + gint h; menu_pipe_execute(self->menu); menu_find_submenus(self->menu); self->selected = NULL; - for (mit = self->menu->entries, fit = self->entries; mit && fit; + /* start at show_from */ + mit = g_list_nth(self->menu->entries, self->show_from); + + /* go through the menu's and frame's entries and connect the frame entries + to the menu entries */ + for (fit = self->entries; mit && fit; mit = g_list_next(mit), fit = g_list_next(fit)) { ObMenuEntryFrame *f = fit->data; f->entry = mit->data; } + /* if there are more menu entries than in the frame, add them */ while (mit) { ObMenuEntryFrame *e = menu_entry_frame_new(mit->data, self); self->entries = g_list_append(self->entries, e); mit = g_list_next(mit); } - + + /* if there are more frame entries than menu entries then get rid of + them */ while (fit) { GList *n = g_list_next(fit); menu_entry_frame_free(fit->data); @@ -763,6 +832,70 @@ static void menu_frame_update(ObMenuFrame *self) fit = n; } + /* * make the menu fit on the screen */ + + /* calculate the height of the menu */ + h = 0; + for (fit = self->entries; fit; fit = g_list_next(fit)) + h += menu_entry_frame_get_height(fit->data, + fit == self->entries, + g_list_next(fit) == NULL); + /* add the border at the top and bottom */ + h += ob_rr_theme->mbwidth * 2; + + a = screen_physical_area_monitor(self->monitor); + + if (h > a->height) { + GList *flast, *tmp; + gboolean last_entry = TRUE; + + /* take the height of our More... entry into account */ + h += menu_entry_frame_get_height(NULL, FALSE, TRUE); + + /* start at the end of the entries */ + flast = g_list_last(self->entries); + + /* pull out all the entries from the frame that don't + fit on the screen, leaving at least 1 though */ + while (h > a->height && g_list_previous(flast) != NULL) { + /* update the height, without this entry */ + h -= menu_entry_frame_get_height(flast->data, FALSE, last_entry); + + /* destroy the entry we're not displaying */ + tmp = flast; + flast = g_list_previous(flast); + menu_entry_frame_free(tmp->data); + self->entries = g_list_delete_link(self->entries, tmp); + + /* only the first one that we see is the last entry in the menu */ + last_entry = FALSE; + }; + + { + ObMenuEntry *more_entry; + ObMenuEntryFrame *more_frame; + /* make the More... menu entry frame which will display in this + frame. + if self->menu->more_menu is NULL that means that this is already + More... menu, so just use ourself. + */ + more_entry = menu_get_more((self->menu->more_menu ? + self->menu->more_menu : + self->menu), + /* continue where we left off */ + self->show_from + + g_list_length(self->entries)); + more_frame = menu_entry_frame_new(more_entry, self); + /* make it get deleted when the menu frame goes away */ + menu_entry_unref(more_entry); + + /* add our More... entry to the frame */ + self->entries = g_list_append(self->entries, more_frame); + } + } + + g_free(a); + menu_frame_render(self); } @@ -789,10 +922,13 @@ static gboolean menu_frame_show(ObMenuFrame *self) if (menu_frame_visible == NULL) { /* no menus shown yet */ - if (!grab_pointer(TRUE, TRUE, OB_CURSOR_POINTER)) + + /* grab the pointer in such a way as to pass through "owner events" + so that we can get enter/leave notifies in the menu. */ + if (!grab_pointer(TRUE, FALSE, OB_CURSOR_POINTER)) return FALSE; - if (!grab_keyboard(TRUE)) { - grab_pointer(FALSE, TRUE, OB_CURSOR_POINTER); + if (!grab_keyboard()) { + ungrab_pointer(); return FALSE; } } @@ -801,12 +937,16 @@ static gboolean menu_frame_show(ObMenuFrame *self) menu_frame_visible = g_list_prepend(menu_frame_visible, self); + if (self->menu->show_func) + self->menu->show_func(self, self->menu->data); + return TRUE; } gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y, - gint button) + gboolean mouse) { + gint px, py; guint i; if (menu_frame_is_visible(self)) @@ -817,14 +957,16 @@ gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint 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)) { + gboolean contains = RECT_CONTAINS(*a, x, y); + g_free(a); + if (contains) { self->monitor = i; break; } } if (self->menu->place_func) - self->menu->place_func(self, &x, &y, button, self->menu->data); + self->menu->place_func(self, &x, &y, mouse, self->menu->data); else menu_frame_place_topmenu(self, &x, &y); @@ -832,14 +974,20 @@ gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y, XMapWindow(ob_display, self->window); + if (screen_pointer_pos(&px, &py)) { + ObMenuEntryFrame *e = menu_entry_frame_under(px, py); + if (e && e->frame == self) + e->ignore_enters++; + } + return TRUE; } gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent, ObMenuEntryFrame *parent_entry) { - ObMenuEntryFrame *e; gint x, y, dx, dy; + gint px, py; if (menu_frame_is_visible(self)) return TRUE; @@ -869,20 +1017,25 @@ gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent, XMapWindow(ob_display, self->window); - if (screen_pointer_pos(&dx, &dy) && (e = menu_entry_frame_under(dx, dy)) && - e->frame == self) - ++e->ignore_enters; + if (screen_pointer_pos(&px, &py)) { + ObMenuEntryFrame *e = menu_entry_frame_under(px, py); + if (e && e->frame == self) + e->ignore_enters++; + } return TRUE; } -void menu_frame_hide(ObMenuFrame *self) +static void menu_frame_hide(ObMenuFrame *self) { GList *it = g_list_find(menu_frame_visible, self); if (!it) return; + if (self->menu->hide_func) + self->menu->hide_func(self, self->menu->data); + if (self->child) menu_frame_hide(self->child); @@ -895,8 +1048,8 @@ void menu_frame_hide(ObMenuFrame *self) if (menu_frame_visible == NULL) { /* last menu shown */ - grab_pointer(FALSE, TRUE, OB_CURSOR_NONE); - grab_keyboard(FALSE); + ungrab_pointer(); + ungrab_keyboard(); } XUnmapWindow(ob_display, self->window); @@ -904,7 +1057,7 @@ void menu_frame_hide(ObMenuFrame *self) menu_frame_free(self); } -void menu_frame_hide_all() +void menu_frame_hide_all(void) { GList *it; @@ -922,8 +1075,14 @@ void menu_frame_hide_all_client(ObClient *client) GList *it = g_list_last(menu_frame_visible); if (it) { ObMenuFrame *f = it->data; - if (f->client == client) + if (f->client == client) { + if (config_submenu_show_delay) { + /* remove any submenu open requests */ + ob_main_loop_timeout_remove(ob_main_loop, + menu_entry_frame_submenu_timeout); + } menu_frame_hide(f); + } } } @@ -958,7 +1117,7 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y) ObMenuEntryFrame *e = it->data; if (RECT_CONTAINS(e->area, x, y)) { - ret = e; + ret = e; break; } } @@ -968,6 +1127,7 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y) static gboolean menu_entry_frame_submenu_timeout(gpointer data) { + g_assert(menu_frame_visible); menu_entry_frame_show_submenu((ObMenuEntryFrame*)data); return FALSE; } @@ -982,8 +1142,8 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry, entry = old; if (old == entry) return; - - if (config_submenu_show_delay) { + + if (config_submenu_show_delay) { /* remove any submenu open requests */ ob_main_loop_timeout_remove(ob_main_loop, menu_entry_frame_submenu_timeout); @@ -1021,6 +1181,7 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self) if (!self->entry->data.submenu.submenu) return; f = menu_frame_new(self->entry->data.submenu.submenu, + self->entry->data.submenu.show_from, self->frame->client); /* pass our direction on to our child */ f->direction_right = self->frame->direction_right; @@ -1028,7 +1189,7 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self) menu_frame_show_submenu(f, self->frame, self); } -void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state, Time time) +void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state) { if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && self->entry->data.normal.enabled) @@ -1040,15 +1201,19 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state, Time time) gpointer data = self->frame->menu->data; GSList *acts = self->entry->data.normal.actions; ObClient *client = self->frame->client; + ObMenuFrame *frame = self->frame; /* release grabs before executing the shit */ - if (!(state & ControlMask)) + if (!(state & ControlMask)) { menu_frame_hide_all(); + frame = NULL; + } if (func) - func(entry, state, data, time); + func(entry, frame, client, state, data); else - action_run(acts, client, state, time); + actions_run_acts(acts, OB_USER_ACTION_MENU_SELECTION, + state, -1, -1, 0, OB_FRAME_CONTEXT_NONE, client); } }