diff options
| author | Dana Jansens <danakj@orodu.net> | 2003-08-28 05:44:13 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2003-08-28 05:44:13 +0000 |
| commit | 615cbd96075905d75533f9b615c4ee6a75f4f9a4 (patch) | |
| tree | d57954f576d41f36ff30df6df1dad2264c13dcbd /openbox | |
| parent | 9290376bbbb8b29411f59a35e5477f25304fe205 (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.c | 6 | ||||
| -rw-r--r-- | openbox/event.c | 4 | ||||
| -rw-r--r-- | openbox/menu.c | 61 | ||||
| -rw-r--r-- | openbox/menu.h | 19 | ||||
| -rw-r--r-- | openbox/menuframe.c | 42 | ||||
| -rw-r--r-- | openbox/menuframe.h | 10 | ||||
| -rw-r--r-- | openbox/openbox.c | 2 | ||||
| -rw-r--r-- | openbox/plugin.c | 43 | ||||
| -rw-r--r-- | openbox/plugin.h | 5 |
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 |
