X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fmenuframe.c;h=725b1a18b732047284a392a1e436cab57a8dbc90;hb=9e85e930da614ebef4e714ec890644d6e7241871;hp=29b9b638f51ead4d001c3b1401c4f7fef740be43;hpb=c34ef4028e504b8ce862b9c2e47b284ab66717dd;p=chaz%2Fopenbox diff --git a/openbox/menuframe.c b/openbox/menuframe.c index 29b9b638..725b1a18 100644 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@ -16,6 +16,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); @@ -37,6 +40,7 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, ObClient *client) self->type = Window_Menu; self->menu = menu; self->selected = NULL; + self->show_title = TRUE; self->client = client; attr.event_mask = FRAME_EVENTMASK; @@ -51,12 +55,21 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, ObClient *client) self->a_title = RrAppearanceCopy(ob_rr_theme->a_menu_title); self->a_items = RrAppearanceCopy(ob_rr_theme->a_menu); + stacking_add(MENU_AS_WINDOW(self)); + return self; } void menu_frame_free(ObMenuFrame *self) { if (self) { + while (self->entries) { + menu_entry_frame_free(self->entries->data); + self->entries = g_list_delete_link(self->entries, self->entries); + } + + stacking_remove(MENU_AS_WINDOW(self)); + XDestroyWindow(ob_display, self->items); XDestroyWindow(ob_display, self->title); XDestroyWindow(ob_display, self->window); @@ -68,7 +81,8 @@ void menu_frame_free(ObMenuFrame *self) } } -ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry, ObMenuFrame *frame) +static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry, + ObMenuFrame *frame) { ObMenuEntryFrame *self; XSetWindowAttributes attr; @@ -105,7 +119,7 @@ ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry, ObMenuFrame *frame) return self; } -void menu_entry_frame_free(ObMenuEntryFrame *self) +static void menu_entry_frame_free(ObMenuEntryFrame *self) { if (self) { XDestroyWindow(ob_display, self->icon); @@ -129,7 +143,6 @@ void menu_entry_frame_free(ObMenuEntryFrame *self) void menu_frame_move(ObMenuFrame *self, gint x, gint y) { - /* XXX screen constraints */ RECT_SET_POINT(self->area, x, y); XMoveWindow(ob_display, self->window, self->area.x, self->area.y); } @@ -165,8 +178,10 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) { RrAppearance *item_a, *text_a; gint th; /* temp */ + ObMenu *sub; - item_a = (!self->entry->enabled ? + item_a = ((self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && + !self->entry->data.normal.enabled) ? self->a_disabled : (self == self->frame->selected ? self->a_selected : @@ -188,7 +203,8 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) item_a->surface.parenty = self->area.y; RrPaint(item_a, self->window, self->area.width, self->area.height); - text_a = (!self->entry->enabled ? + text_a = ((self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && + !self->entry->data.normal.enabled) ? self->a_text_disabled : (self == self->frame->selected ? self->a_text_selected : @@ -198,8 +214,8 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) text_a->texture[0].data.text.string = self->entry->data.normal.label; break; case OB_MENU_ENTRY_TYPE_SUBMENU: - text_a->texture[0].data.text.string = - self->entry->data.submenu.submenu->title; + sub = self->entry->data.submenu.submenu; + text_a->texture[0].data.text.string = sub ? sub->title : ""; break; case OB_MENU_ENTRY_TYPE_SEPARATOR: break; @@ -222,11 +238,17 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) break; } - /* XXX draw icons */ - if (0) { + if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && + self->entry->data.normal.icon_data) + { XMoveResizeWindow(ob_display, self->icon, 0, 0, self->frame->item_h, self->frame->item_h); - /* XXX set the RGBA surface stuff */ + 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.data = + self->entry->data.normal.icon_data; self->a_icon->surface.parent = item_a; self->a_icon->surface.parentx = 0; self->a_icon->surface.parenty = 0; @@ -258,12 +280,13 @@ static void menu_frame_render(ObMenuFrame *self) gint tw, th; /* temps */ GList *it; gboolean has_icon = FALSE, has_bullet = FALSE; + ObMenu *sub; XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->bwidth); XSetWindowBorder(ob_display, self->window, RrColorPixel(ob_rr_theme->b_color)); - if (!self->parent && self->menu->title) { + if (!self->parent && self->show_title) { XMoveWindow(ob_display, self->title, -ob_rr_theme->bwidth, h - ob_rr_theme->bwidth); @@ -294,7 +317,8 @@ static void menu_frame_render(ObMenuFrame *self) RECT_SET_POINT(e->area, 0, allitems_h); XMoveWindow(ob_display, e->window, 0, e->area.y); - text_a = (!e->entry->enabled ? + text_a = ((e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && + !e->entry->data.normal.enabled) ? e->a_text_disabled : (e == self->selected ? e->a_text_selected : @@ -304,11 +328,12 @@ static void menu_frame_render(ObMenuFrame *self) text_a->texture[0].data.text.string = e->entry->data.normal.label; RrMinsize(text_a, &tw, &th); - /* XXX has_icon = TRUE; */ + if (e->entry->data.normal.icon_data) + has_icon = TRUE; break; case OB_MENU_ENTRY_TYPE_SUBMENU: - text_a->texture[0].data.text.string = - e->entry->data.submenu.submenu->title; + sub = e->entry->data.submenu.submenu; + text_a->texture[0].data.text.string = sub ? sub->title : ""; RrMinsize(text_a, &tw, &th); has_bullet = TRUE; @@ -336,15 +361,17 @@ static void menu_frame_render(ObMenuFrame *self) } if (!w) w = 10; - if (!allitems_h) allitems_h = 3; - if (!h) h = 3; + if (!allitems_h) { + allitems_h = 3; + h += 3; + } XResizeWindow(ob_display, self->window, w, h); XResizeWindow(ob_display, self->items, w, allitems_h); self->inner_w = w; - if (!self->parent && self->title) { + if (!self->parent && self->show_title) { XResizeWindow(ob_display, self->title, w, self->title_h - ob_rr_theme->bwidth); RrPaint(self->a_title, self->title, @@ -368,6 +395,8 @@ static void menu_frame_update(ObMenuFrame *self) { GList *mit, *fit; + menu_find_submenus(self->menu); + self->selected = NULL; for (mit = self->menu->entries, fit = self->entries; mit && fit; @@ -411,6 +440,8 @@ void menu_frame_show(ObMenuFrame *self, ObMenuFrame *parent) if (!g_list_find(menu_frame_visible, self)) { menu_frame_visible = g_list_prepend(menu_frame_visible, self); + if (self->menu->update_func) + self->menu->update_func(self, self->menu->data); menu_frame_update(self); } @@ -443,10 +474,22 @@ void menu_frame_hide(ObMenuFrame *self) void menu_frame_hide_all() { - while (menu_frame_visible) - menu_frame_hide(menu_frame_visible->data); + GList *it = g_list_last(menu_frame_visible); + if (it) + menu_frame_hide(it->data); } +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) + menu_frame_hide(f); + } +} + + ObMenuFrame* menu_frame_under(gint x, gint y) { ObMenuFrame *ret = NULL; @@ -488,6 +531,7 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y) void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry) { ObMenuEntryFrame *old = self->selected; + ObMenuFrame *oldchild = self->child; if (old == entry) return; @@ -496,11 +540,11 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry) else self->selected = NULL; - if (old) { + if (old) menu_entry_frame_render(old); - if (old->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) - menu_frame_hide(self->child); - } + if (oldchild) + menu_frame_hide(oldchild); + if (self->selected) { menu_entry_frame_render(self->selected); @@ -513,28 +557,42 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self) { ObMenuFrame *f; + if (!self->entry->data.submenu.submenu) return; + f = menu_frame_new(self->entry->data.submenu.submenu, self->frame->client); menu_frame_move(f, self->frame->area.x + self->frame->area.width - ob_rr_theme->menu_overlap, self->frame->area.y + self->frame->title_h + - self->area.y); + self->area.y + ob_rr_theme->menu_overlap); menu_frame_show(f, self->frame); } -void menu_entry_frame_execute(ObMenuEntryFrame *self) +void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide) { if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) { - GSList *it; - - for (it = self->entry->data.normal.actions; it; - it = g_slist_next(it)) - { - ObAction *act = it->data; - act->data.any.c = self->frame->client; - act->func(&act->data); - } + /* 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; + + /* release grabs before executing the shit */ menu_frame_hide_all(); + + if (func) + func(entry, data); + else { + GSList *it; + + for (it = acts; it; it = g_slist_next(it)) + { + ObAction *act = it->data; + act->data.any.c = self->frame->client; + act->func(&act->data); + } + } } }