X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fmenu.c;h=b29594d75434c2ac0c2c67acab579008691c8571;hb=e531f6900672fc278481b7ebf664fe2221517909;hp=99043cd52caeca139a0084999e6fab6fc9977a59;hpb=dd33644de425ce545f17e9fc0f8ead05aa5bc01f;p=chaz%2Fopenbox diff --git a/openbox/menu.c b/openbox/menu.c index 99043cd5..b29594d7 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -4,10 +4,12 @@ #include "stacking.h" #include "client.h" #include "grab.h" +#include "config.h" #include "screen.h" #include "geom.h" #include "plugin.h" #include "misc.h" +#include "parser/parse.h" GHashTable *menu_hash = NULL; GList *menu_visible = NULL; @@ -18,16 +20,18 @@ GList *menu_visible = NULL; #define ENTRY_EVENTMASK (EnterWindowMask | LeaveWindowMask | \ ButtonPressMask | ButtonReleaseMask) -static void parse_menu(xmlDocPtr doc, xmlNodePtr node, void *data) +static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, + gpointer data) { - parse_menu_full(doc, node, data, TRUE); + g_message("%s", __FUNCTION__); + parse_menu_full(i, doc, node, data, TRUE); } -void parse_menu_full(xmlDocPtr doc, xmlNodePtr node, void *data, - gboolean newmenu) +void parse_menu_full(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, + gpointer data, gboolean newmenu) { - Action *act; + ObAction *act; xmlNodePtr nact; gchar *id = NULL, *title = NULL, *label = NULL, *plugin; @@ -42,11 +46,12 @@ void parse_menu_full(xmlDocPtr doc, xmlNodePtr node, void *data, if (parse_attr_string("plugin", node, &plugin)) { PluginMenuCreateData data; + data.parse_inst = i; data.doc = doc; data.node = node; data.parent = menu; - if (plugin_open_reopen(plugin)) + if (plugin_open_reopen(plugin, i)) parent = plugin_create(plugin, &data); g_free(plugin); } else @@ -67,12 +72,12 @@ void parse_menu_full(xmlDocPtr doc, xmlNodePtr node, void *data, data.doc = doc; data.node = node; data.parent = menu; - if (plugin_open_reopen(plugin)) + if (plugin_open_reopen(plugin, i)) parent = plugin_create(plugin, &data); g_free(plugin); } else { parent = menu; - parse_menu(doc, node, &parent); + parse_menu(i, doc, node, &parent); menu_add_entry(menu, menu_entry_new_submenu(parent->label, parent)); } @@ -142,19 +147,17 @@ void menu_entry_free(ObMenuEntry *self) RrAppearanceFree(self->a_item); RrAppearanceFree(self->a_disabled); RrAppearanceFree(self->a_hilite); + RrAppearanceFree(self->a_submenu); XDestroyWindow(ob_display, self->item); - + XDestroyWindow(ob_display, self->submenu_pic); g_free(self); } - -void menu_startup() + +void menu_startup(ObParseInst *i) { menu_hash = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)menu_destroy_hash_key, (GDestroyNotify)menu_destroy_hash_value); - - parse_register("menu", parse_menu, NULL); - } void menu_shutdown() @@ -162,6 +165,43 @@ void menu_shutdown() g_hash_table_destroy(menu_hash); } +void menu_parse() +{ + ObParseInst *i; + xmlDocPtr doc; + xmlNodePtr node; + gchar *p; + gboolean loaded = FALSE; + + i = parse_startup(); + + if (config_menu_path) + if (!(loaded = + parse_load(config_menu_path, "openbox_menu", &doc, &node))) + g_warning("Failed to load menu from '%s'", config_menu_path); + if (!loaded) { + p = g_build_filename(g_get_home_dir(), ".openbox", "menu", NULL); + if (!(loaded = + parse_load(p, "openbox_menu", &doc, &node))) + g_warning("Failed to load menu from '%s'", p); + g_free(p); + } + if (!loaded) { + p = g_build_filename(RCDIR, "menu", NULL); + if (!(loaded = + parse_load(p, "openbox_menu", &doc, &node))) + g_warning("Failed to load menu from '%s'", p); + g_free(p); + } + + if (loaded) { + parse_register(i, "menu", parse_menu, NULL); + parse_tree(i, doc, node->xmlChildrenNode); + } + + parse_shutdown(i); +} + static Window createWindow(Window parent, unsigned long mask, XSetWindowAttributes *attrib) { @@ -232,7 +272,7 @@ void menu_free(char *name) g_hash_table_remove(menu_hash, name); } -ObMenuEntry *menu_entry_new_full(char *label, Action *action, +ObMenuEntry *menu_entry_new_full(char *label, ObAction *action, ObMenuEntryRenderType render_type, gpointer submenu) { @@ -273,13 +313,17 @@ void menu_add_entry(ObMenu *menu, ObMenuEntry *entry) attrib.event_mask = ENTRY_EVENTMASK; entry->item = createWindow(menu->items, CWEventMask, &attrib); + entry->submenu_pic = createWindow(menu->items, CWEventMask, &attrib); XMapWindow(ob_display, entry->item); + XMapWindow(ob_display, entry->submenu_pic); - entry->a_item = entry->a_disabled = entry->a_hilite = NULL; + entry->a_item = entry->a_disabled = entry->a_hilite = entry->a_submenu + = NULL; menu->invalid = TRUE; g_hash_table_insert(window_map, &entry->item, menu); + g_hash_table_insert(window_map, &entry->submenu_pic, menu); } void menu_show(char *name, int x, int y, ObClient *client) @@ -392,7 +436,8 @@ void menu_entry_fire(ObMenuEntry *self, unsigned int button, unsigned int x, { ObMenu *m; - if (button > 3) return; + /* ignore wheel scrolling */ + if (button == 4 || button == 5) return; if (self->action) { self->action->data.any.c = self->parent->client; @@ -472,9 +517,21 @@ void menu_control_mouseover(ObMenuEntry *self, gboolean enter) a = screen_physical_area_monitor(self->parent->xin_area); - if (self->submenu->size.width + x >= a->x + a->width) - x = self->parent->location.x - self->submenu->size.width - - ob_rr_theme->bwidth + ob_rr_theme->menu_overlap; + if (self->submenu->size.width + x >= a->x + a->width) { + int newparentx = a->x + a->width + - self->submenu->size.width + - self->parent->size.width + - ob_rr_theme->bwidth + - ob_rr_theme->menu_overlap; + + x = a->x + a->width - self->submenu->size.width + - ob_rr_theme->menu_overlap; + XWarpPointer(ob_display, None, None, 0, 0, 0, 0, + newparentx - self->parent->location.x, 0); + + menu_show_full(self->parent, newparentx, + self->parent->location.y, self->parent->client); + } menu_show_full(self->submenu, x, self->parent->location.y + self->y, @@ -582,6 +639,7 @@ void menu_control_keyboard_nav(unsigned int key) } default: ((ObMenu *)menu_visible->data)->hide(menu_visible->data); + current_menu = NULL; } return; }