]> Dogcows Code - chaz/openbox/commitdiff
make client-list-menu work too
authorDana Jansens <danakj@orodu.net>
Thu, 28 Aug 2003 07:34:03 +0000 (07:34 +0000)
committerDana Jansens <danakj@orodu.net>
Thu, 28 Aug 2003 07:34:03 +0000 (07:34 +0000)
more menu cleanups

12 files changed:
Makefile.am
data/menu
openbox/action.c
openbox/action.h
openbox/config.c
openbox/event.c
openbox/menu.c
openbox/menu.h
openbox/menuframe.c
openbox/menuframe.h
plugins/menu/client_list_menu.c
plugins/menu/client_menu.c

index c056e25f4d9a62739d1272b177b6d0e01de5edfa..4b162ed471c8af8f2c3a91da04eecd368e0e6cf1 100644 (file)
@@ -27,11 +27,11 @@ bin_PROGRAMS = \
 
 plugin_LTLIBRARIES = \
        plugins/placement/placement.la \
-       plugins/menu/client_menu.la
+       plugins/menu/client_menu.la \
+       plugins/menu/client_list_menu.la
 #      plugins/menu/timed_menu.la \
 #      plugins/menu/fifo_menu.la \
 #      plugins/menu/include_menu.la \
-#      plugins/menu/client_list_menu.la
 
 if OBCONF
 bin_PROGRAMS += \
index ef8b31451160477261dfe1aa27baa1b23d6d7a30..230a3346e017e9634d2b127a4c5ee64cc773de19 100644 (file)
--- a/data/menu
+++ b/data/menu
@@ -28,6 +28,7 @@
 </menu>
 
 <menu id="client-menu" plugin="client_menu" />
+<menu id="client-list-menu" plugin="client_list_menu" />
 
 <menu id="root-menu" label="Openbox 3">
   <menu id="apps-menu" />
@@ -35,6 +36,8 @@
   <separator />
   <menu id="client-menu" plugin="client_menu" />
   <separator />
+  <menu id="client-list-menu" plugin="client_list_menu" />
+  <separator />
   <item label="Restart">
     <action name="restart" />
   </item>
index 0025187b8d989b1bda52de4f5f43393c15435e90..2f7c5c7d54f01702bf229d579b2d346f9b0c4791 100644 (file)
@@ -693,7 +693,7 @@ ObAction *action_from_string(char *name)
     return a;
 }
 
-ObAction *action_parse(xmlDocPtr doc, xmlNodePtr node)
+ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
 {
     char *actname;
     ObAction *act = NULL;
@@ -705,8 +705,13 @@ ObAction *action_parse(xmlDocPtr doc, xmlNodePtr node)
                 if ((n = parse_find_node("execute", node->xmlChildrenNode)))
                     act->data.execute.path = parse_string(doc, n);
             } else if (act->func == action_showmenu) {
-                if ((n = parse_find_node("menu", node->xmlChildrenNode)))
+                if ((n = parse_find_node("menu", node->xmlChildrenNode))) {
+                    gchar *plugin;
+
                     act->data.showmenu.name = parse_string(doc, n);
+                    if (parse_attr_string("plugin", n, &plugin))
+                        menu_open_plugin(i, act->data.showmenu.name, plugin);
+                }
             } else if (act->func == action_desktop) {
                 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
                     act->data.desktop.desk = parse_int(doc, n);
index 2f57cb87673c3155b869d02ddc1647bf55ef6bff..bacd4b5cba6baee57757266f6113fb4448e6b10a 100644 (file)
@@ -137,7 +137,7 @@ ObAction *action_new(void (*func)(union ActionData *data));
 */
 
 ObAction *action_from_string(char *name);
-ObAction *action_parse(xmlDocPtr doc, xmlNodePtr node);
+ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
 void action_free(ObAction *a);
 
 /* Execute */
index d03ba0312b36d8c8bdf855904e19c2d8a7ededa7..f0b78d7d6f0defe59affcc8610694d7b798475de 100644 (file)
@@ -92,7 +92,7 @@ static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
     if (keylist) {
         nact = parse_find_node("action", node);
         while (nact) {
-            if ((action = action_parse(doc, nact))) {
+            if ((action = action_parse(i, doc, nact))) {
                 /* validate that its okay for a key binding */
                 if (action->func == action_moveresize &&
                     action->data.moveresize.corner !=
@@ -165,7 +165,7 @@ static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
                 goto next_nbut;
             nact = parse_find_node("action", nbut->xmlChildrenNode);
             while (nact) {
-                if ((action = action_parse(doc, nact))) {
+                if ((action = action_parse(i, doc, nact))) {
                     /* validate that its okay for a mouse binding*/
                     if (mact == OB_MOUSE_ACTION_MOTION) {
                         if (action->func != action_moveresize ||
index fc45060c45b3366c9a94e284a666c359049246f4..bbde397e7789c90efbb157e3ac9e5630a1525f37 100644 (file)
@@ -1170,13 +1170,14 @@ static void event_handle_menu(XEvent *ev)
 
     switch (ev->type) {
     case ButtonRelease:
-        if (!(f = menu_frame_under(ev->xmotion.x_root,
-                                   ev->xmotion.y_root)))
+        if (!(f = menu_frame_under(ev->xbutton.x_root,
+                                   ev->xbutton.y_root)))
             menu_frame_hide_all();
         else {
-            if ((e = menu_entry_frame_under(ev->xmotion.x_root,
-                                            ev->xmotion.y_root)))
-                menu_entry_frame_execute(e);
+            if ((e = menu_entry_frame_under(ev->xbutton.x_root,
+                                            ev->xbutton.y_root)))
+                menu_entry_frame_execute(e,
+                                         !(ev->xbutton.state & ControlMask));
         }
         break;
     case MotionNotify:
index 5efb0c353ded4d1499e13a612e60fa19e9f210ab..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,6 +64,21 @@ 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)
 {
@@ -75,13 +90,7 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 
     if (!g_hash_table_lookup(menu_hash, name)) {
         if (parse_attr_string("plugin", node, &plugin)) {
-            if (!plugin_open(plugin, i))
-                goto parse_menu_fail;
-            plugin_start(plugin);
-            if (!g_hash_table_lookup(menu_hash, name))
-                g_warning("Specified plugin '%s' did not provide the "
-                          "menu '%s'", plugin, name);
-                goto parse_menu_fail;
+            menu_open_plugin(i, name, plugin);
         } else {
             if (!parse_attr_string("label", node, &title))
                 goto parse_menu_fail;
@@ -107,6 +116,10 @@ parse_menu_fail:
 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);
@@ -315,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;
index a33322805a912f43524f17f0557f9310466744f3..c4c9deeabbd8a2d40c5705fadc6c5e8bd2bb3f0b 100644 (file)
@@ -3,13 +3,15 @@
 
 #include "action.h"
 #include "window.h"
-#include "render/render.h"
 #include "geom.h"
+#include "render/render.h"
+#include "parser/parse.h"
 
 #include <glib.h>
 
 struct _ObClient;
 struct _ObMenuFrame;
+struct _ObMenuEntryFrame;
 
 typedef struct _ObMenu ObMenu;
 typedef struct _ObMenuEntry ObMenuEntry;
@@ -18,6 +20,9 @@ typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry;
 typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry;
 
 typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data);
+typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntryFrame *frame,
+                                  gpointer data);
+typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
 
 extern GList *menu_visible;
 
@@ -35,6 +40,8 @@ struct _ObMenu
     gpointer data;
 
     ObMenuUpdateFunc update_func;
+    ObMenuExecuteFunc execute_func;
+    ObMenuDestroyFunc destroy_func;
 };
 
 typedef enum
@@ -84,7 +91,11 @@ void menu_parse();
 gboolean menu_new(gchar *name, gchar *title, gpointer data);
 void menu_free(gchar *name);
 
+gboolean menu_open_plugin(ObParseInst *i, gchar *name, gchar *plugin);
+
 void menu_set_update_func(gchar *name, ObMenuUpdateFunc func);
+void menu_set_execute_func(gchar *name, ObMenuExecuteFunc func);
+void menu_set_destroy_func(gchar *name, ObMenuDestroyFunc func);
 
 void menu_show(gchar *name, gint x, gint y, struct _ObClient *client);
 
index 832f49af0ff63fbafc9ab75f90e815a647780e78..ea7f254c6ef95007e38ded3addb6ee2c3e3b98d9 100644 (file)
@@ -344,8 +344,10 @@ 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);
@@ -546,20 +548,24 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self)
     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;
-
         /* release grabs before executing the shit */
         menu_frame_hide_all();
 
-        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);
+        if (self->frame->menu->execute_func)
+            self->frame->menu->execute_func(self, self->frame->menu->data);
+        else {
+            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);
+            }
         }
     }
 }
index 8cfc837b27085caeed7a315b4b19fe36eff10ad6..7c744fee196dcfe2b9e0b11f723abe9d6606aee1 100644 (file)
@@ -94,6 +94,6 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y);
 
 void menu_entry_frame_show_submenu(ObMenuEntryFrame *self);
 
-void menu_entry_frame_execute(ObMenuEntryFrame *self);
+void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide);
 
 #endif
index 166ac71d937f9670b95fb6948841837cb46aac5f..2f5c5f9fb8e24a3b880e368c32db40db5ca1490c 100644 (file)
 #include "kernel/openbox.h"
 #include "kernel/menu.h"
+#include "kernel/menuframe.h"
 #include "kernel/action.h"
 #include "kernel/screen.h"
 #include "kernel/client.h"
 #include "kernel/focus.h"
+#include "gettext.h"
 
 #include "render/theme.h"
 
 #include <glib.h>
 
-static char *PLUGIN_NAME = "client_list_menu";
+#define MENU_NAME "client-list-menu"
 
 typedef struct {
-    GSList *submenus;
-} Client_List_Menu_Data;
+    /* how many desktop menus we've made */
+    guint desktops;
+} MenuData;
 
 typedef struct {
     guint desktop;
-} Client_List_Desktop_Menu_Data;
-
-#define CLIENT_LIST_MENU(m) ((ObMenu *)m)
-#define CLIENT_LIST_MENU_DATA(m) ((Client_List_Menu_Data *)((ObMenu *)m)->plugin_data)
-
-#define CLIENT_LIST_DESKTOP_MENU(m) ((ObMenu *)m)
-#define CLIENT_LIST_DESKTOP_MENU_DATA(m) ((Client_List_Desktop_Menu_Data *)((ObMenu *)m)->plugin_data)
-
-static void self_update(ObMenu *self);
-static void self_destroy(ObMenu *self);
+} DesktopData;
 
 void plugin_setup_config() { }
-void plugin_shutdown() { }
-void plugin_destroy (ObMenu *m) { }
 
-void *plugin_create()
-{
-    ObMenu *menu = menu_new_full("Desktops", "client-list-menu", NULL,
-                                 NULL, self_update, NULL,
-                                 NULL, NULL, self_destroy);
-
-    menu->plugin = PLUGIN_NAME;
-    menu->plugin_data = g_new(Client_List_Menu_Data, 1);
-    CLIENT_LIST_MENU_DATA(menu)->submenus = NULL;
-
-    return (void *)menu;
-}
-
-void plugin_startup()
-{
-    plugin_create("client_list_menu");
-}
-
-
-static void desk_update(ObMenu *self)
+static void desk_menu_update(ObMenuFrame *frame, gpointer data)
 {
+    ObMenu *menu = frame->menu;
+    DesktopData *d = data;
     GList *it;
-    guint desk;
-
-    menu_clear(self);
 
-    desk = CLIENT_LIST_DESKTOP_MENU_DATA(self)->desktop;
+    menu_clear_entries(menu->name);
 
-    for (it = focus_order[desk]; it; it = g_list_next(it)) {
-        ObClient *c = (ObClient *)it->data;
+    for (it = focus_order[d->desktop]; it; it = g_list_next(it)) {
+        ObClient *c = it->data;
         if (client_normal(c)) {
-            ObAction* a = action_from_string("activate");
-            a->data.activate.c = c;
-            menu_add_entry(self, menu_entry_new((c->iconic ?
-                                                 c->icon_title :
-                                                 c->title), a));
+            GSList *acts;
+            ObAction* act;
+
+            act = action_from_string("activate");
+            act->data.activate.c = c;
+            acts = g_slist_prepend(NULL, act);
+            menu_add_normal(menu->name, 0,
+                            (c->iconic ? c->icon_title : c->title), acts);
         }
     }
-
-    menu_render(self);
+    
 }
 
-static void desk_selected(ObMenuEntry *entry,
-                          unsigned int button, unsigned int x, unsigned int y)
+/* executes it without changing the client in the actions, since we set that
+   when we make the actions! */
+static void desk_menu_execute(ObMenuEntryFrame *self, gpointer data)
 {
-    entry->action->data.activate.here = (button == 2);
-    entry->parent->client = entry->action->data.activate.c;
-    menu_entry_fire(entry, button, x, y);
+    GSList *it;
+
+    for (it = self->entry->data.normal.actions; it; it = g_slist_next(it))
+    {
+        ObAction *act = it->data;
+        act->func(&act->data);
+    }
 }
 
-static void desk_destroy(ObMenu *self)
+static void desk_menu_destroy(ObMenu *menu, gpointer data)
 {
-    g_free(self->plugin_data);
+    DesktopData *d = data;
+
+    g_free(d);
 }
 
-static void self_update(ObMenu *self)
+static void self_update(ObMenuFrame *frame, gpointer data)
 {
-    guint i, n;
-    ObMenu *deskmenu;
-    gchar *s;
-    GList *eit, *enext;
-    GSList *sit, *snext;
-
-    n = g_slist_length(CLIENT_LIST_MENU_DATA(self)->submenus);
+    guint i;
+    MenuData *d = data;
+    
+    menu_clear_entries(MENU_NAME);
 
     for (i = 0; i < screen_num_desktops; ++i) {
-        if (i >= n) {
-            s = g_strdup_printf("client-list-menu-desktop-%d", i);
-            deskmenu = menu_new_full(screen_desktop_names[i], s, self,
-                                     NULL,
-                                     desk_update, desk_selected, NULL, NULL,
-                                     desk_destroy);
-            g_free(s);
-
-            deskmenu->plugin = PLUGIN_NAME;
-            deskmenu->plugin_data = g_new(Client_List_Desktop_Menu_Data, 1);
-            CLIENT_LIST_DESKTOP_MENU_DATA(deskmenu)->desktop = i;
-
-            CLIENT_LIST_MENU_DATA(self)->submenus =
-                g_slist_append(CLIENT_LIST_MENU_DATA(self)->submenus,
-                               deskmenu);
-        }
+        gchar *name = g_strdup_printf("%s-%u", MENU_NAME, i);
+        DesktopData *data = g_new(DesktopData, 1);
 
-        menu_add_entry(self, menu_entry_new_submenu(screen_desktop_names[i],
-                                                    deskmenu));
-    }
+        data->desktop = i;
+        menu_new(name, screen_desktop_names[i], data);
+        menu_set_update_func(name, desk_menu_update);
+        menu_set_execute_func(name, desk_menu_execute);
+        menu_set_destroy_func(name, desk_menu_destroy);
 
-    for (eit = g_list_nth(self->entries, i); eit; eit = enext) {
-        enext = g_list_next(eit);
-       menu_entry_free(eit->data);
-        self->entries = g_list_delete_link(self->entries, eit);
+        menu_add_submenu(MENU_NAME, 0, name);
+
+        g_free(name);
     }
 
-    for (sit = g_slist_nth(CLIENT_LIST_MENU_DATA(self)->submenus, i);
-         sit; sit = snext) {
-        snext = g_slist_next(sit);
-        menu_free(sit->data);
-        CLIENT_LIST_MENU_DATA(self)->submenus = 
-            g_slist_delete_link(CLIENT_LIST_MENU_DATA(self)->submenus, sit);
+    d->desktops = MAX(d->desktops, screen_num_desktops);
+}
+
+static void self_destroy(ObMenu *menu, gpointer data)
+{
+    MenuData *d = data;
+    guint i;
+
+    for (i = 0; i < d->desktops; ++i) {
+        gchar *name = g_strdup_printf("%s-%u", MENU_NAME, i);
+        menu_free(name);
+        g_free(name);
     }
+    g_free(d);
+}
+
+void plugin_startup()
+{
+    MenuData *data;
 
-    menu_render(self);
+    data = g_new(MenuData, 1);
+    data->desktops = 0;
+    menu_new(MENU_NAME, _("Desktops"), data);
+    menu_set_update_func(MENU_NAME, self_update);
+    menu_set_destroy_func(MENU_NAME, self_destroy);
 }
 
-static void self_destroy(ObMenu *self)
+void plugin_shutdown()
 {
-    g_free(self->plugin_data);
+    menu_free(MENU_NAME);
 }
index c9ec591654d8d757d12f25b1a828e57d83a76c6e..32277047c2da05c4e43e6660eb46072eca84cf62 100644 (file)
@@ -82,6 +82,15 @@ static void layer_update(ObMenuFrame *frame, gpointer data)
         if (e->type == OB_MENU_ENTRY_TYPE_NORMAL)
             e->data.normal.enabled = !!frame->client;
     }
+
+    e = menu_find_entry_id(menu, LAYER_TOP);
+    e->data.normal.enabled = !frame->client->above;
+
+    e = menu_find_entry_id(menu, LAYER_NORMAL);
+    e->data.normal.enabled = !(frame->client->above || frame->client->below);
+
+    e = menu_find_entry_id(menu, LAYER_BOTTOM);
+    e->data.normal.enabled = !frame->client->below;
 }
 
 static void send_to_update(ObMenuFrame *frame, gpointer data)
This page took 0.048315 seconds and 4 git commands to generate.