summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-08-28 05:44:13 +0000
committerDana Jansens <danakj@orodu.net>2003-08-28 05:44:13 +0000
commit615cbd96075905d75533f9b615c4ee6a75f4f9a4 (patch)
treed57954f576d41f36ff30df6df1dad2264c13dcbd /openbox
parent9290376bbbb8b29411f59a35e5477f25304fe205 (diff)
change the menu plugin interface, no need for the create/destroy functions any more.
redo the client-menu plugin to work with the new menu api
Diffstat (limited to 'openbox')
-rw-r--r--openbox/client.c6
-rw-r--r--openbox/event.c4
-rw-r--r--openbox/menu.c61
-rw-r--r--openbox/menu.h19
-rw-r--r--openbox/menuframe.c42
-rw-r--r--openbox/menuframe.h10
-rw-r--r--openbox/openbox.c2
-rw-r--r--openbox/plugin.c43
-rw-r--r--openbox/plugin.h5
9 files changed, 107 insertions, 85 deletions
diff --git a/openbox/client.c b/openbox/client.c
index ab7c8049..f17e9724 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -17,7 +17,7 @@
#include "openbox.h"
#include "group.h"
#include "config.h"
-#include "menu.h"
+#include "menuframe.h"
#include "keyboard.h"
#include "mouse.h"
#include "render/render.h"
@@ -406,7 +406,9 @@ void client_unmanage(ObClient *self)
if (moveresize_client == self)
moveresize_end(TRUE);
- /* XXX close any windows that are attached to this window */
+ /* menus can be associated with a client, so close any that are since
+ we are disappearing now */
+ menu_frame_hide_all_client(self);
if (focus_client == self) {
XEvent e;
diff --git a/openbox/event.c b/openbox/event.c
index 6480855e..fc45060c 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -1183,8 +1183,8 @@ static void event_handle_menu(XEvent *ev)
if ((f = menu_frame_under(ev->xmotion.x_root,
ev->xmotion.y_root))) {
menu_frame_move_on_screen(f);
- if (e = menu_entry_frame_under(ev->xmotion.x_root,
- ev->xmotion.y_root))
+ if ((e = menu_entry_frame_under(ev->xmotion.x_root,
+ ev->xmotion.y_root)))
menu_frame_select(f, e);
}
break;
diff --git a/openbox/menu.c b/openbox/menu.c
index 7e8685f0..3e38c0f9 100644
--- a/openbox/menu.c
+++ b/openbox/menu.c
@@ -44,11 +44,11 @@ static void parse_menu_item(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
if (state->menus) {
if (parse_attr_string("label", node, &label)) {
GSList *acts = NULL;
-
+
for (node = node->xmlChildrenNode; node; node = node->next)
if (!xmlStrcasecmp(node->name, (const xmlChar*) "action"))
acts = g_slist_append(acts, action_parse(doc, node));
- menu_add_normal(state->menus->data, label, acts);
+ menu_add_normal(state->menus->data, 0, label, acts);
g_free(label);
}
}
@@ -59,9 +59,9 @@ static void parse_menu_separator(ObParseInst *i,
gpointer data)
{
ObMenuParseState *state = data;
-
+
if (state->menus)
- menu_add_separator(state->menus->data);
+ menu_add_separator(state->menus->data, 0);
}
static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
@@ -85,7 +85,7 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
}
if (state->menus)
- menu_add_submenu(state->menus->data, name);
+ menu_add_submenu(state->menus->data, 0, name);
parse_menu_fail:
g_free(name);
@@ -95,6 +95,7 @@ parse_menu_fail:
void menu_destroy_hash_value(ObMenu *self)
{
+ /* XXX make sure its not visible */
menu_clear_entries_internal(self);
g_free(self->name);
g_free(self->title);
@@ -110,6 +111,7 @@ void menu_shutdown()
{
menu_frame_hide_all();
g_hash_table_destroy(menu_hash);
+ menu_hash = NULL;
}
void menu_parse()
@@ -170,6 +172,14 @@ gboolean menu_new(gchar *name, gchar *title, gpointer data)
return TRUE;
}
+void menu_free(gchar *name)
+{
+ ObMenu *self;
+
+ if (!(self = menu_from_name(name))) return;
+ g_hash_table_remove(menu_hash, self->name);
+}
+
void menu_show(gchar *name, gint x, gint y, ObClient *client)
{
ObMenu *self;
@@ -177,14 +187,12 @@ void menu_show(gchar *name, gint x, gint y, ObClient *client)
if (!(self = menu_from_name(name))) return;
- /* XXX update entries */
-
frame = menu_frame_new(self, client);
menu_frame_move(frame, x, y);
menu_frame_show(frame, NULL);
}
-static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type)
+static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type, gint id)
{
ObMenuEntry *self;
@@ -193,6 +201,7 @@ static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type)
self = g_new0(ObMenuEntry, 1);
self->type = type;
self->menu = menu;
+ self->id = id;
self->enabled = TRUE;
return self;
}
@@ -238,21 +247,21 @@ static void menu_clear_entries_internal(ObMenu *self)
}
}
-void menu_add_normal(gchar *name, gchar *label, GSList *actions)
+void menu_add_normal(gchar *name, gint id, gchar *label, GSList *actions)
{
ObMenu *self;
ObMenuEntry *e;
if (!(self = menu_from_name(name))) return;
- e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_NORMAL);
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_NORMAL, id);
e->data.normal.label = g_strdup(label);
e->data.normal.actions = actions;
self->entries = g_list_append(self->entries, e);
}
-void menu_add_submenu(gchar *name, gchar *submenu)
+void menu_add_submenu(gchar *name, gint id, gchar *submenu)
{
ObMenu *self, *sub;
ObMenuEntry *e;
@@ -260,20 +269,44 @@ void menu_add_submenu(gchar *name, gchar *submenu)
if (!(self = menu_from_name(name))) return;
if (!(sub = menu_from_name(submenu))) return;
- e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SUBMENU);
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SUBMENU, id);
e->data.submenu.submenu = sub;
self->entries = g_list_append(self->entries, e);
}
-void menu_add_separator(gchar *name)
+void menu_add_separator(gchar *name, gint id)
{
ObMenu *self;
ObMenuEntry *e;
if (!(self = menu_from_name(name))) return;
- e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SEPARATOR);
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SEPARATOR, id);
self->entries = g_list_append(self->entries, e);
}
+
+void menu_set_update_func(gchar *name, ObMenuUpdateFunc func)
+{
+ ObMenu *self;
+
+ if (!(self = menu_from_name(name))) return;
+ self->update_func = func;
+}
+
+ObMenuEntry* menu_find_entry_id(ObMenu *self, gint id)
+{
+ ObMenuEntry *ret = NULL;
+ GList *it;
+
+ for (it = self->entries; it; it = g_list_next(it)) {
+ ObMenuEntry *e = it->data;
+
+ if (e->id == id) {
+ ret = e;
+ break;
+ }
+ }
+ return ret;
+}
diff --git a/openbox/menu.h b/openbox/menu.h
index cfbb52de..66390e75 100644
--- a/openbox/menu.h
+++ b/openbox/menu.h
@@ -17,9 +17,9 @@ typedef struct _ObNormalMenuEntry ObNormalMenuEntry;
typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry;
typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry;
-extern GList *menu_visible;
-
+typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data);
+extern GList *menu_visible;
struct _ObMenu
{
@@ -33,6 +33,8 @@ struct _ObMenu
/* plugin data */
gpointer data;
+
+ ObMenuUpdateFunc update_func;
};
typedef enum
@@ -62,6 +64,8 @@ struct _ObMenuEntry
ObMenuEntryType type;
ObMenu *menu;
+ gint id;
+
/* state */
gboolean enabled;
@@ -78,13 +82,18 @@ void menu_shutdown();
void menu_parse();
gboolean menu_new(gchar *name, gchar *title, gpointer data);
+void menu_free(gchar *name);
+
+void menu_set_update_func(gchar *name, ObMenuUpdateFunc func);
void menu_show(gchar *name, gint x, gint y, struct _ObClient *client);
/* functions for building menus */
void menu_clear_entries(gchar *name);
-void menu_add_normal(gchar *name, gchar *label, GSList *actions);
-void menu_add_submenu(gchar *name, gchar *submenu);
-void menu_add_separator(gchar *name);
+void menu_add_normal(gchar *name, gint id, gchar *label, GSList *actions);
+void menu_add_submenu(gchar *name, gint id, gchar *submenu);
+void menu_add_separator(gchar *name, gint id);
+
+ObMenuEntry* menu_find_entry_id(ObMenu *self, gint id);
#endif
diff --git a/openbox/menuframe.c b/openbox/menuframe.c
index 29b9b638..daecd6c4 100644
--- a/openbox/menuframe.c
+++ b/openbox/menuframe.c
@@ -37,6 +37,7 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, ObClient *client)
self->type = Window_Menu;
self->menu = menu;
self->selected = NULL;
+ self->show_title = TRUE;
self->client = client;
attr.event_mask = FRAME_EVENTMASK;
@@ -51,12 +52,16 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, ObClient *client)
self->a_title = RrAppearanceCopy(ob_rr_theme->a_menu_title);
self->a_items = RrAppearanceCopy(ob_rr_theme->a_menu);
+ stacking_add(MENU_AS_WINDOW(self));
+
return self;
}
void menu_frame_free(ObMenuFrame *self)
{
if (self) {
+ stacking_remove(MENU_AS_WINDOW(self));
+
XDestroyWindow(ob_display, self->items);
XDestroyWindow(ob_display, self->title);
XDestroyWindow(ob_display, self->window);
@@ -263,7 +268,7 @@ static void menu_frame_render(ObMenuFrame *self)
XSetWindowBorder(ob_display, self->window,
RrColorPixel(ob_rr_theme->b_color));
- if (!self->parent && self->menu->title) {
+ if (!self->parent && self->show_title) {
XMoveWindow(ob_display, self->title,
-ob_rr_theme->bwidth, h - ob_rr_theme->bwidth);
@@ -344,7 +349,7 @@ static void menu_frame_render(ObMenuFrame *self)
self->inner_w = w;
- if (!self->parent && self->title) {
+ if (!self->parent && self->show_title) {
XResizeWindow(ob_display, self->title,
w, self->title_h - ob_rr_theme->bwidth);
RrPaint(self->a_title, self->title,
@@ -411,6 +416,8 @@ void menu_frame_show(ObMenuFrame *self, ObMenuFrame *parent)
if (!g_list_find(menu_frame_visible, self)) {
menu_frame_visible = g_list_prepend(menu_frame_visible, self);
+ if (self->menu->update_func)
+ self->menu->update_func(self, self->menu->data);
menu_frame_update(self);
}
@@ -443,10 +450,22 @@ void menu_frame_hide(ObMenuFrame *self)
void menu_frame_hide_all()
{
- while (menu_frame_visible)
- menu_frame_hide(menu_frame_visible->data);
+ GList *it = g_list_last(menu_frame_visible);
+ if (it)
+ menu_frame_hide(it->data);
+}
+
+void menu_frame_hide_all_client(ObClient *client)
+{
+ GList *it = g_list_last(menu_frame_visible);
+ if (it) {
+ ObMenuFrame *f = it->data;
+ if (f->client == client)
+ menu_frame_hide(f);
+ }
}
+
ObMenuFrame* menu_frame_under(gint x, gint y)
{
ObMenuFrame *ret = NULL;
@@ -488,6 +507,7 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y)
void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry)
{
ObMenuEntryFrame *old = self->selected;
+ ObMenuFrame *oldchild = self->child;
if (old == entry) return;
@@ -496,11 +516,11 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry)
else
self->selected = NULL;
- if (old) {
+ if (old)
menu_entry_frame_render(old);
- if (old->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)
- menu_frame_hide(self->child);
- }
+ if (oldchild)
+ menu_frame_hide(oldchild);
+
if (self->selected) {
menu_entry_frame_render(self->selected);
@@ -519,7 +539,7 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self)
self->frame->area.x + self->frame->area.width
- ob_rr_theme->menu_overlap,
self->frame->area.y + self->frame->title_h +
- self->area.y);
+ self->area.y + ob_rr_theme->menu_overlap);
menu_frame_show(f, self->frame);
}
@@ -528,6 +548,9 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self)
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))
{
@@ -535,6 +558,5 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self)
act->data.any.c = self->frame->client;
act->func(&act->data);
}
- menu_frame_hide_all();
}
}
diff --git a/openbox/menuframe.h b/openbox/menuframe.h
index f7391444..8cfc837b 100644
--- a/openbox/menuframe.h
+++ b/openbox/menuframe.h
@@ -31,6 +31,12 @@ struct _ObMenuFrame
ObMenuFrame *parent;
ObMenuFrame *child;
+ GList *entries;
+ ObMenuEntryFrame *selected;
+
+ /* If a titlebar is displayed for the menu or not (for top-level menus) */
+ gboolean show_title;
+
/* On-screen area (including borders!) */
Rect area;
gint inner_w; /* inside the borders */
@@ -39,9 +45,6 @@ struct _ObMenuFrame
gint text_x; /* offset at which the text appears in the items */
gint text_w; /* width of the text area in the items */
- GList *entries;
- ObMenuEntryFrame *selected;
-
Window title;
Window items;
@@ -82,6 +85,7 @@ void menu_frame_show(ObMenuFrame *self, ObMenuFrame *parent);
void menu_frame_hide(ObMenuFrame *self);
void menu_frame_hide_all();
+void menu_frame_hide_all_client(struct _ObClient *client);
void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry);
diff --git a/openbox/openbox.c b/openbox/openbox.c
index 6656304a..165d7229 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -266,8 +266,8 @@ int main(int argc, char **argv)
dock_remove_all();
client_unmanage_all();
- menu_shutdown(); /* destroy menus before unloading plugins */
plugin_shutdown(); /* calls all the plugins' shutdown functions */
+ menu_shutdown();
mouse_shutdown();
keyboard_shutdown();
dock_shutdown();
diff --git a/openbox/plugin.c b/openbox/plugin.c
index 411eb6fb..b8d9be4b 100644
--- a/openbox/plugin.c
+++ b/openbox/plugin.c
@@ -11,8 +11,6 @@ typedef struct {
PluginSetupConfig config;
PluginStartup startup;
PluginShutdown shutdown;
- PluginCreate create;
- PluginDestroy destroy;
} Plugin;
static gpointer load_sym(GModule *module, char *name, char *symbol,
@@ -58,9 +56,6 @@ static Plugin *plugin_new(char *name)
FALSE);
p->shutdown = (PluginShutdown)load_sym(p->module, name, "plugin_shutdown",
FALSE);
- p->create = (PluginCreate)load_sym(p->module, name, "plugin_create", TRUE);
- p->destroy = (PluginDestroy)load_sym(p->module, name, "plugin_destroy",
- TRUE);
if (p->config == NULL || p->startup == NULL || p->shutdown == NULL) {
g_module_close(p->module);
@@ -174,41 +169,3 @@ void plugin_loadall(ObParseInst *i)
g_io_channel_unref(io);
}
}
-
-void *plugin_create(char *name, void *data)
-{
- Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name);
-
- if (p == NULL) {
- g_warning("Unable to find plugin for create: %s", name);
- return NULL;
- }
-
- if (p->create == NULL || p->destroy == NULL) {
- g_critical("Unsupported create/destroy: %s", name);
- return NULL;
- }
-
- return p->create(data);
-}
-
-void plugin_destroy(char *name, void *data)
-{
- Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name);
-
- if (p == NULL) {
- g_critical("Unable to find plugin for destroy: %s", name);
- /* really shouldn't happen, but attempt to free something anyway? */
- g_free(data);
- return;
- }
-
- if (p->destroy == NULL || p->create == NULL) {
- g_critical("Unsupported create/destroy: %s", name);
- /* really, really shouldn't happen, but attempt to free anyway? */
- g_free(data);
- return;
- }
-
- p->destroy(data);
-}
diff --git a/openbox/plugin.h b/openbox/plugin.h
index 6d14c64c..7ef004bf 100644
--- a/openbox/plugin.h
+++ b/openbox/plugin.h
@@ -15,9 +15,4 @@ gboolean plugin_open(char *name, struct _ObParseInst *i);
gboolean plugin_open_reopen(char *name, struct _ObParseInst *i);
void plugin_close(char *name);
-/* call plugin's generic constructor */
-void *plugin_create(char *name, void *data);
-/* free memory allocated by plugin_create() */
-void plugin_destroy(char *name, void *object);
-
#endif