load menu plugins automatically from whats in the menu file
menu fixups move enabled into the 'normal menu item' specific data stuff
This commit is contained in:
parent
615cbd9607
commit
ffba11aeb0
10 changed files with 101 additions and 68 deletions
|
@ -27,10 +27,14 @@
|
|||
</item>
|
||||
</menu>
|
||||
|
||||
<menu id="client-menu" plugin="client_menu" />
|
||||
|
||||
<menu id="root-menu" label="Openbox 3">
|
||||
<menu id="apps-menu" />
|
||||
<menu id="games-menu" />
|
||||
<separator />
|
||||
<menu id="client-menu" plugin="client_menu" />
|
||||
<separator />
|
||||
<item label="Restart">
|
||||
<action name="restart" />
|
||||
</item>
|
||||
|
|
|
@ -68,12 +68,21 @@ 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("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;
|
||||
} else {
|
||||
if (!parse_attr_string("label", node, &title))
|
||||
goto parse_menu_fail;
|
||||
|
||||
|
@ -83,6 +92,7 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
|||
state->menus = g_slist_delete_link(state->menus, state->menus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state->menus)
|
||||
menu_add_submenu(state->menus->data, 0, name);
|
||||
|
@ -90,6 +100,7 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
|||
parse_menu_fail:
|
||||
g_free(name);
|
||||
g_free(title);
|
||||
g_free(plugin);
|
||||
}
|
||||
|
||||
|
||||
|
@ -202,7 +213,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,9 @@ typedef enum
|
|||
struct _ObNormalMenuEntry {
|
||||
gchar *label;
|
||||
|
||||
/* state */
|
||||
gboolean enabled;
|
||||
|
||||
/* List of ObActions */
|
||||
GSList *actions;
|
||||
};
|
||||
|
@ -66,9 +69,6 @@ struct _ObMenuEntry
|
|||
|
||||
gint id;
|
||||
|
||||
/* state */
|
||||
gboolean enabled;
|
||||
|
||||
union u {
|
||||
ObNormalMenuEntry normal;
|
||||
ObSubmenuMenuEntry submenu;
|
||||
|
|
|
@ -171,7 +171,8 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
|
|||
RrAppearance *item_a, *text_a;
|
||||
gint th; /* temp */
|
||||
|
||||
item_a = (!self->entry->enabled ?
|
||||
item_a = ((self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
|
||||
!self->entry->data.normal.enabled) ?
|
||||
self->a_disabled :
|
||||
(self == self->frame->selected ?
|
||||
self->a_selected :
|
||||
|
@ -193,7 +194,8 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
|
|||
item_a->surface.parenty = self->area.y;
|
||||
RrPaint(item_a, self->window, self->area.width, self->area.height);
|
||||
|
||||
text_a = (!self->entry->enabled ?
|
||||
text_a = ((self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
|
||||
!self->entry->data.normal.enabled) ?
|
||||
self->a_text_disabled :
|
||||
(self == self->frame->selected ?
|
||||
self->a_text_selected :
|
||||
|
@ -299,7 +301,8 @@ static void menu_frame_render(ObMenuFrame *self)
|
|||
RECT_SET_POINT(e->area, 0, allitems_h);
|
||||
XMoveWindow(ob_display, e->window, 0, e->area.y);
|
||||
|
||||
text_a = (!e->entry->enabled ?
|
||||
text_a = ((e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
|
||||
!e->entry->data.normal.enabled) ?
|
||||
e->a_text_disabled :
|
||||
(e == self->selected ?
|
||||
e->a_text_selected :
|
||||
|
|
|
@ -6,14 +6,16 @@
|
|||
|
||||
typedef struct {
|
||||
GModule *module;
|
||||
char *name;
|
||||
gchar *name;
|
||||
|
||||
gboolean started;
|
||||
|
||||
PluginSetupConfig config;
|
||||
PluginStartup startup;
|
||||
PluginShutdown shutdown;
|
||||
} Plugin;
|
||||
|
||||
static gpointer load_sym(GModule *module, char *name, char *symbol,
|
||||
static gpointer load_sym(GModule *module, gchar *name, gchar *symbol,
|
||||
gboolean allow_fail)
|
||||
{
|
||||
gpointer var;
|
||||
|
@ -26,12 +28,13 @@ static gpointer load_sym(GModule *module, char *name, char *symbol,
|
|||
return var;
|
||||
}
|
||||
|
||||
static Plugin *plugin_new(char *name)
|
||||
static Plugin *plugin_new(gchar *name)
|
||||
{
|
||||
Plugin *p;
|
||||
char *path;
|
||||
gchar *path;
|
||||
|
||||
p = g_new(Plugin, 1);
|
||||
p->started = FALSE;
|
||||
|
||||
path = g_build_filename(g_get_home_dir(), ".openbox", "plugins", name,
|
||||
NULL);
|
||||
|
@ -88,15 +91,12 @@ void plugin_shutdown()
|
|||
g_datalist_clear(&plugins);
|
||||
}
|
||||
|
||||
gboolean plugin_open_full(char *name, gboolean reopen, ObParseInst *i)
|
||||
gboolean plugin_open(gchar *name, ObParseInst *i)
|
||||
{
|
||||
Plugin *p;
|
||||
|
||||
if (g_datalist_get_data(&plugins, name) != NULL) {
|
||||
if (!reopen)
|
||||
g_warning("plugin '%s' already loaded, can't load again", name);
|
||||
if (g_datalist_get_data(&plugins, name) != NULL)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
p = plugin_new(name);
|
||||
if (p == NULL) {
|
||||
|
@ -109,22 +109,12 @@ gboolean plugin_open_full(char *name, gboolean reopen, ObParseInst *i)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean plugin_open(char *name, ObParseInst *i) {
|
||||
return plugin_open_full(name, FALSE, i);
|
||||
}
|
||||
|
||||
gboolean plugin_open_reopen(char *name, ObParseInst *i) {
|
||||
return plugin_open_full(name, TRUE, i);
|
||||
}
|
||||
|
||||
void plugin_close(char *name)
|
||||
{
|
||||
g_datalist_remove_data(&plugins, name);
|
||||
}
|
||||
|
||||
static void foreach_start(GQuark key, Plugin *p, gpointer *foo)
|
||||
{
|
||||
if (!p->started) {
|
||||
p->startup();
|
||||
p->started = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void plugin_startall()
|
||||
|
@ -132,11 +122,25 @@ void plugin_startall()
|
|||
g_datalist_foreach(&plugins, (GDataForeachFunc)foreach_start, NULL);
|
||||
}
|
||||
|
||||
void plugin_start(gchar *name)
|
||||
{
|
||||
Plugin *p;
|
||||
|
||||
if (!(p = g_datalist_get_data(&plugins, name))) {
|
||||
g_warning("Tried to start plugin '%s' but it is not loaded", name);
|
||||
return;
|
||||
}
|
||||
if (!p->started) {
|
||||
p->startup();
|
||||
p->started = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void plugin_loadall(ObParseInst *i)
|
||||
{
|
||||
GIOChannel *io;
|
||||
GError *err;
|
||||
char *path, *name;
|
||||
gchar *path, *name;
|
||||
|
||||
path = g_build_filename(g_get_home_dir(), ".openbox", "pluginrc", NULL);
|
||||
err = NULL;
|
||||
|
@ -153,10 +157,6 @@ void plugin_loadall(ObParseInst *i)
|
|||
if (io == NULL) {
|
||||
/* load the default plugins */
|
||||
plugin_open("placement", i);
|
||||
|
||||
/* XXX rm me when the parser loads me magically */
|
||||
plugin_open("client_menu", i);
|
||||
plugin_open("client_list_menu", i);
|
||||
} else {
|
||||
/* load the plugins in the rc file */
|
||||
while (g_io_channel_read_line(io, &name, NULL, NULL, &err) ==
|
||||
|
|
|
@ -10,9 +10,8 @@ void plugin_loadall(struct _ObParseInst *i);
|
|||
void plugin_startall();
|
||||
|
||||
/* default plugin */
|
||||
gboolean plugin_open(char *name, struct _ObParseInst *i);
|
||||
/* load a plugin, but don't warn about reopens. for menus */
|
||||
gboolean plugin_open_reopen(char *name, struct _ObParseInst *i);
|
||||
void plugin_close(char *name);
|
||||
gboolean plugin_open(gchar *name, struct _ObParseInst *i);
|
||||
void plugin_start(gchar *name);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -179,8 +179,6 @@ gboolean screen_annex()
|
|||
}
|
||||
|
||||
|
||||
ob_debug("Managing screen %d\n", ob_screen);
|
||||
|
||||
set_root_cursor();
|
||||
|
||||
/* set the OPENBOX_PID hint */
|
||||
|
|
|
@ -194,8 +194,6 @@ void session_startup(int argc, char **argv)
|
|||
g_free(val_uid.value);
|
||||
|
||||
save_commands();
|
||||
|
||||
ob_debug("Connected to session manager with id %s\n", ob_sm_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,8 +74,6 @@ gboolean parse_load_rc(xmlDocPtr *doc, xmlNodePtr *root)
|
|||
gboolean parse_load(const char *path, const char *rootname,
|
||||
xmlDocPtr *doc, xmlNodePtr *root)
|
||||
{
|
||||
xmlLineNumbersDefault(1);
|
||||
|
||||
if ((*doc = xmlParseFile(path))) {
|
||||
*root = xmlDocGetRootElement(*doc);
|
||||
if (!*root) {
|
||||
|
@ -99,8 +97,6 @@ gboolean parse_load(const char *path, const char *rootname,
|
|||
gboolean parse_load_mem(gpointer data, guint len, const char *rootname,
|
||||
xmlDocPtr *doc, xmlNodePtr *root)
|
||||
{
|
||||
xmlLineNumbersDefault(1);
|
||||
|
||||
if ((*doc = xmlParseMemory(data, len))) {
|
||||
*root = xmlDocGetRootElement(*doc);
|
||||
if (!*root) {
|
||||
|
|
|
@ -39,36 +39,49 @@ static void client_update(ObMenuFrame *frame, gpointer data)
|
|||
{
|
||||
ObMenu *menu = frame->menu;
|
||||
ObMenuEntry *e;
|
||||
GList *it;
|
||||
|
||||
frame->show_title = FALSE;
|
||||
|
||||
if (!frame->client) {
|
||||
for (it = menu->entries; it; it = g_list_next(it)) {
|
||||
e = it->data;
|
||||
if (e->type == OB_MENU_ENTRY_TYPE_NORMAL)
|
||||
e->data.normal.enabled = !!frame->client;
|
||||
}
|
||||
|
||||
if (!frame->client)
|
||||
return;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_ICONIFY);
|
||||
e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_ICONIFY;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_MAXIMIZE);
|
||||
e->data.normal.enabled =frame->client->functions & OB_CLIENT_FUNC_MAXIMIZE;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_SHADE);
|
||||
e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_SHADE;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_MOVE);
|
||||
e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_MOVE;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_RESIZE);
|
||||
e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_RESIZE;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_CLOSE);
|
||||
e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_CLOSE;
|
||||
}
|
||||
|
||||
static void layer_update(ObMenuFrame *frame, gpointer data)
|
||||
{
|
||||
ObMenu *menu = frame->menu;
|
||||
ObMenuEntry *e;
|
||||
GList *it;
|
||||
|
||||
for (it = menu->entries; it; it = g_list_next(it)) {
|
||||
ObMenuEntry *e = it->data;
|
||||
e->enabled = FALSE;
|
||||
e = it->data;
|
||||
if (e->type == OB_MENU_ENTRY_TYPE_NORMAL)
|
||||
e->data.normal.enabled = !!frame->client;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_ICONIFY);
|
||||
e->enabled = frame->client->functions & OB_CLIENT_FUNC_ICONIFY;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_MAXIMIZE);
|
||||
e->enabled = frame->client->functions & OB_CLIENT_FUNC_MAXIMIZE;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_SHADE);
|
||||
e->enabled = frame->client->functions & OB_CLIENT_FUNC_SHADE;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_MOVE);
|
||||
e->enabled = frame->client->functions & OB_CLIENT_FUNC_MOVE;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_RESIZE);
|
||||
e->enabled = frame->client->functions & OB_CLIENT_FUNC_RESIZE;
|
||||
|
||||
e = menu_find_entry_id(menu, CLIENT_CLOSE);
|
||||
e->enabled = frame->client->functions & OB_CLIENT_FUNC_CLOSE;
|
||||
}
|
||||
|
||||
static void send_to_update(ObMenuFrame *frame, gpointer data)
|
||||
|
@ -104,7 +117,7 @@ static void send_to_update(ObMenuFrame *frame, gpointer data)
|
|||
if (frame->client->desktop == desk) {
|
||||
ObMenuEntry *e = menu_find_entry_id(menu, desk);
|
||||
g_assert(e);
|
||||
e->enabled = FALSE;
|
||||
e->data.normal.enabled = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,6 +127,7 @@ void plugin_startup()
|
|||
GSList *acts;
|
||||
|
||||
menu_new(LAYER_MENU_NAME, _("Layer"), NULL);
|
||||
menu_set_update_func(LAYER_MENU_NAME, layer_update);
|
||||
|
||||
acts = g_slist_prepend(NULL, action_from_string("SendToTopLayer"));
|
||||
menu_add_normal(LAYER_MENU_NAME, LAYER_TOP, _("Always on top"), acts);
|
||||
|
@ -128,6 +142,7 @@ void plugin_startup()
|
|||
menu_new(SEND_TO_MENU_NAME, _("Send to desktop"), NULL);
|
||||
menu_set_update_func(SEND_TO_MENU_NAME, send_to_update);
|
||||
|
||||
|
||||
menu_new(CLIENT_MENU_NAME, _("Client menu"), NULL);
|
||||
menu_set_update_func(CLIENT_MENU_NAME, client_update);
|
||||
|
||||
|
|
Loading…
Reference in a new issue