summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
Diffstat (limited to 'openbox')
-rw-r--r--openbox/action.c9
-rw-r--r--openbox/action.h2
-rw-r--r--openbox/config.c4
-rw-r--r--openbox/event.c11
-rw-r--r--openbox/menu.c45
-rw-r--r--openbox/menu.h13
-rw-r--r--openbox/menuframe.c28
-rw-r--r--openbox/menuframe.h2
8 files changed, 83 insertions, 31 deletions
diff --git a/openbox/action.c b/openbox/action.c
index 0025187b..2f7c5c7d 100644
--- a/openbox/action.c
+++ b/openbox/action.c
@@ -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);
diff --git a/openbox/action.h b/openbox/action.h
index 2f57cb87..bacd4b5c 100644
--- a/openbox/action.h
+++ b/openbox/action.h
@@ -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 */
diff --git a/openbox/config.c b/openbox/config.c
index d03ba031..f0b78d7d 100644
--- a/openbox/config.c
+++ b/openbox/config.c
@@ -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 ||
diff --git a/openbox/event.c b/openbox/event.c
index fc45060c..bbde397e 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -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:
diff --git a/openbox/menu.c b/openbox/menu.c
index 5efb0c35..324b3629 100644
--- a/openbox/menu.c
+++ b/openbox/menu.c
@@ -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;
diff --git a/openbox/menu.h b/openbox/menu.h
index a3332280..c4c9deea 100644
--- a/openbox/menu.h
+++ b/openbox/menu.h
@@ -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);
diff --git a/openbox/menuframe.c b/openbox/menuframe.c
index 832f49af..ea7f254c 100644
--- a/openbox/menuframe.c
+++ b/openbox/menuframe.c
@@ -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);
+ }
}
}
}
diff --git a/openbox/menuframe.h b/openbox/menuframe.h
index 8cfc837b..7c744fee 100644
--- a/openbox/menuframe.h
+++ b/openbox/menuframe.h
@@ -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