- self = g_new0(Menu, 1);
- self->obwin.type = Window_Menu;
- self->label = g_strdup(label);
- self->name = g_strdup(name);
- self->parent = parent;
- self->open_submenu = NULL;
-
- self->entries = NULL;
- self->shown = FALSE;
- self->invalid = TRUE;
-
- /* default controllers */
- self->show = show;
- self->hide = NULL;
- self->update = update;
- self->mouseover = NULL;
- self->selected = NULL;
-
- self->plugin = NULL;
- self->plugin_data = NULL;
-
- attrib.override_redirect = TRUE;
- attrib.event_mask = FRAME_EVENTMASK;
- self->frame = createWindow(ob_root, CWOverrideRedirect|CWEventMask, &attrib);
- attrib.event_mask = TITLE_EVENTMASK;
- self->title = createWindow(self->frame, CWEventMask, &attrib);
- self->items = createWindow(self->frame, 0, &attrib);
-
- XSetWindowBorderWidth(ob_display, self->frame, theme_bwidth);
- XSetWindowBackground(ob_display, self->frame, theme_b_color->pixel);
- XSetWindowBorderWidth(ob_display, self->title, theme_bwidth);
- XSetWindowBorder(ob_display, self->frame, theme_b_color->pixel);
- XSetWindowBorder(ob_display, self->title, theme_b_color->pixel);
-
- XMapWindow(ob_display, self->title);
- XMapWindow(ob_display, self->items);
-
- self->a_title = appearance_copy(theme_a_menu_title);
- self->a_items = appearance_copy(theme_a_menu);
-
- g_hash_table_insert(window_map, &self->frame, self);
- g_hash_table_insert(window_map, &self->title, self);
- g_hash_table_insert(window_map, &self->items, self);
- g_hash_table_insert(menu_hash, g_strdup(name), self);
-
- stacking_add(MENU_AS_WINDOW(self));
- stacking_raise(MENU_AS_WINDOW(self));
+ menu_frame_hide_all();
+
+ frame = menu_frame_new(self, 0, client);
+ if (!menu_frame_show_topmenu(frame, x, y, button))
+ menu_frame_free(frame);
+ else if (!button) {
+ /* select the first entry if it's not a submenu and we opened
+ * the menu with the keyboard, and skip all headers */
+ GList *it = frame->entries;
+ while (it) {
+ ObMenuEntryFrame *e = it->data;
+ if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
+ menu_frame_select(frame, e, FALSE);
+ break;
+ } else if (e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR)
+ it = g_list_next(it);
+ else
+ break;
+ }
+ }
+}
+
+static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type, gint id)
+{
+ ObMenuEntry *self;
+
+ g_assert(menu);
+
+ self = g_new0(ObMenuEntry, 1);
+ self->ref = 1;
+ self->type = type;
+ self->menu = menu;
+ self->id = id;
+
+ switch (type) {
+ case OB_MENU_ENTRY_TYPE_NORMAL:
+ self->data.normal.enabled = TRUE;
+ break;
+ case OB_MENU_ENTRY_TYPE_SUBMENU:
+ case OB_MENU_ENTRY_TYPE_SEPARATOR:
+ break;
+ }