]> Dogcows Code - chaz/openbox/blobdiff - openbox/menu.c
offset of 1 is default
[chaz/openbox] / openbox / menu.c
index 00a2bc2b221ab4b44dda1d9e5a26772c9acd1fda..c66a1b0d711bc644a190a57e05dba4a42a77da52 100644 (file)
@@ -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,20 +20,24 @@ GList *menu_visible = NULL;
 #define ENTRY_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
                          ButtonPressMask | ButtonReleaseMask)
 
-static void parse_menu(xmlDocPtr doc, xmlNodePtr node, void *data)
+void menu_control_show(ObMenu *self, int x, int y, ObClient *client);
+
+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;
-    ObMenu *menu = NULL, *parent;
+    ObMenu *menu = NULL, *parent = NULL;
 
     if (newmenu == TRUE) {
         if (!parse_attr_string("id", node, &id))
@@ -42,17 +48,18 @@ 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))
-                parent = plugin_create(plugin, &data);
+            if (plugin_open_reopen(plugin, i))
+                menu = plugin_create(plugin, &data);
             g_free(plugin);
         } else
             menu = menu_new(title, id, data ? *((ObMenu**)data) : NULL);
             
-        if (data)
+        if (data && menu)
             *((ObMenu**)data) = menu;
     } else {
         menu = (ObMenu *)data;
@@ -67,15 +74,17 @@ 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);
+            }
+
+            if (parent)
                 menu_add_entry(menu, menu_entry_new_submenu(parent->label,
                                                             parent));
-            }
 
         }
         else if (!xmlStrcasecmp(node->name, (const xmlChar*) "item")) {
@@ -99,8 +108,6 @@ parse_menu_fail:
     g_free(title);
 }
 
-void menu_control_show(ObMenu *self, int x, int y, ObClient *client);
-
 void menu_destroy_hash_key(ObMenu *menu)
 {
     g_free(menu);
@@ -110,6 +117,8 @@ void menu_destroy_hash_value(ObMenu *self)
 {
     GList *it;
 
+    if (self->destroy) self->destroy(self);
+
     for (it = self->entries; it; it = it->next)
         menu_entry_free(it->data);
     g_list_free(self->entries);
@@ -147,15 +156,12 @@ void menu_entry_free(ObMenuEntry *self)
     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()
@@ -163,6 +169,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)
 {
@@ -176,7 +219,8 @@ ObMenu *menu_new_full(char *label, char *name, ObMenu *parent,
                       menu_controller_show show, menu_controller_update update,
                       menu_controller_selected selected,
                       menu_controller_hide hide,
-                      menu_controller_mouseover mouseover)
+                      menu_controller_mouseover mouseover,
+                      menu_controller_destroy destroy)
 {
     XSetWindowAttributes attrib;
     ObMenu *self;
@@ -194,6 +238,7 @@ ObMenu *menu_new_full(char *label, char *name, ObMenu *parent,
     self->invalid = TRUE;
 
     /* default controllers */
+    self->destroy = destroy;
     self->show = (show != NULL ? show : menu_show_full);
     self->hide = (hide != NULL ? hide : menu_hide);
     self->update = (update != NULL ? update : menu_render);
@@ -233,7 +278,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)
 {
@@ -474,15 +519,16 @@ void menu_control_mouseover(ObMenuEntry *self, gboolean enter)
                ob_rr_theme->bwidth - ob_rr_theme->menu_overlap;
 
            /* need to get the width. is this bad?*/
-           self->parent->update(self->submenu);
+           self->submenu->update(self->submenu);
 
             a = screen_physical_area_monitor(self->parent->xin_area);
 
-           if (self->submenu->size.width + x >= a->x + a->width) {
+           if (self->submenu->size.width + x + ob_rr_theme->bwidth >=
+                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->bwidth * 2
                     - ob_rr_theme->menu_overlap;
                 
                 x = a->x + a->width - self->submenu->size.width
@@ -495,7 +541,8 @@ void menu_control_mouseover(ObMenuEntry *self, gboolean enter)
             }
            
            menu_show_full(self->submenu, x,
-                          self->parent->location.y + self->y,
+                          self->parent->location.y + self->y +
+                           self->parent->title_h + ob_rr_theme->bwidth,
                            self->parent->client);
        }
         self->hilite = TRUE;
This page took 0.025619 seconds and 4 git commands to generate.