]> Dogcows Code - chaz/openbox/blobdiff - openbox/menu.c
make client-list-menu work too
[chaz/openbox] / openbox / menu.c
index 3e38c0f99ddfb3ae5b8b653924b697750b045c97..324b3629f438dfaa9735e083b76b5416bf5eea40 100644 (file)
@@ -47,7 +47,7 @@ static void parse_menu_item(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 
             for (node = node->xmlChildrenNode; node; node = node->next)
                 if (!xmlStrcasecmp(node->name, (const xmlChar*) "action"))
-                    acts = g_slist_append(acts, action_parse(doc, node));
+                    acts = g_slist_append(acts, action_parse(i, doc, node));
             menu_add_normal(state->menus->data, 0, label, acts);
             g_free(label);
         }
@@ -64,23 +64,42 @@ static void parse_menu_separator(ObParseInst *i,
         menu_add_separator(state->menus->data, 0);
 }
 
+gboolean menu_open_plugin(ObParseInst *i, gchar *name, gchar *plugin)
+{
+    gboolean ret = FALSE;
+
+    if (plugin_open(plugin, i)) {
+        plugin_start(plugin);
+        if (g_hash_table_lookup(menu_hash, name))
+            ret = TRUE;
+        else
+            g_warning("Specified plugin '%s' did not provide the "
+                      "menu '%s'", plugin, name);
+    }
+    return ret;
+}
+
 static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
                        gpointer data)
 {
     ObMenuParseState *state = data;
-    gchar *name = NULL, *title = NULL;
+    gchar *name = NULL, *title = NULL, *plugin = NULL;
 
     if (!parse_attr_string("id", node, &name))
         goto parse_menu_fail;
 
     if (!g_hash_table_lookup(menu_hash, name)) {
-        if (!parse_attr_string("label", node, &title))
-            goto parse_menu_fail;
-
-        if (menu_new(name, title, NULL)) {
-            state->menus = g_slist_prepend(state->menus, name);
-            parse_tree(i, doc, node->xmlChildrenNode);
-            state->menus = g_slist_delete_link(state->menus, state->menus);
+        if (parse_attr_string("plugin", node, &plugin)) {
+            menu_open_plugin(i, name, plugin);
+        } else {
+            if (!parse_attr_string("label", node, &title))
+                goto parse_menu_fail;
+
+            if (menu_new(name, title, NULL)) {
+                state->menus = g_slist_prepend(state->menus, name);
+                parse_tree(i, doc, node->xmlChildrenNode);
+                state->menus = g_slist_delete_link(state->menus, state->menus);
+            }
         }
     }
 
@@ -90,12 +109,17 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 parse_menu_fail:
     g_free(name);
     g_free(title);
+    g_free(plugin);
 }
 
 
 void menu_destroy_hash_value(ObMenu *self)
 {
     /* XXX make sure its not visible */
+
+    if (self->destroy_func)
+        self->destroy_func(self, self->data);
+
     menu_clear_entries_internal(self);
     g_free(self->name);
     g_free(self->title);
@@ -202,7 +226,16 @@ static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type, gint id)
     self->type = type;
     self->menu = menu;
     self->id = id;
-    self->enabled = TRUE;
+
+    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;
+    }
+
     return self;
 }
 
@@ -295,6 +328,22 @@ void menu_set_update_func(gchar *name, ObMenuUpdateFunc func)
     self->update_func = func;
 }
 
+void menu_set_execute_func(gchar *name, ObMenuExecuteFunc func)
+{
+    ObMenu *self;
+
+    if (!(self = menu_from_name(name))) return;
+    self->execute_func = func;
+}
+
+void menu_set_destroy_func(gchar *name, ObMenuDestroyFunc func)
+{
+    ObMenu *self;
+
+    if (!(self = menu_from_name(name))) return;
+    self->destroy_func = func;
+}
+
 ObMenuEntry* menu_find_entry_id(ObMenu *self, gint id)
 {
     ObMenuEntry *ret = NULL;
This page took 0.024199 seconds and 4 git commands to generate.