add pipe-menus
This commit is contained in:
parent
3ff8eb037e
commit
c3b02749d7
2 changed files with 71 additions and 31 deletions
|
@ -13,10 +13,6 @@
|
|||
#include "client_list_menu.h"
|
||||
#include "parser/parse.h"
|
||||
|
||||
static GHashTable *menu_hash = NULL;
|
||||
|
||||
ObParseInst *menu_parse_inst;
|
||||
|
||||
typedef struct _ObMenuParseState ObMenuParseState;
|
||||
|
||||
struct _ObMenuParseState
|
||||
|
@ -24,6 +20,10 @@ struct _ObMenuParseState
|
|||
GSList *menus;
|
||||
};
|
||||
|
||||
static GHashTable *menu_hash = NULL;
|
||||
static ObParseInst *menu_parse_inst;
|
||||
static ObMenuParseState menu_parse_state;
|
||||
|
||||
static void menu_destroy_hash_value(ObMenu *self);
|
||||
static void parse_menu_item(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||
gpointer data);
|
||||
|
@ -57,7 +57,6 @@ static gboolean menu_open(gchar *file, xmlDocPtr *doc, xmlNodePtr *node)
|
|||
|
||||
void menu_startup()
|
||||
{
|
||||
ObMenuParseState parse_state;
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
gboolean loaded = FALSE;
|
||||
|
@ -80,14 +79,17 @@ void menu_startup()
|
|||
loaded = menu_open("menu", &doc, &node);
|
||||
|
||||
if (loaded) {
|
||||
parse_state.menus = NULL;
|
||||
menu_parse_state.menus = NULL;
|
||||
|
||||
parse_register(menu_parse_inst, "menu", parse_menu, &parse_state);
|
||||
parse_register(menu_parse_inst, "item", parse_menu_item, &parse_state);
|
||||
parse_register(menu_parse_inst, "menu", parse_menu, &menu_parse_state);
|
||||
parse_register(menu_parse_inst, "item", parse_menu_item,
|
||||
&menu_parse_state);
|
||||
parse_register(menu_parse_inst, "separator",
|
||||
parse_menu_separator, &parse_state);
|
||||
parse_menu_separator, &menu_parse_state);
|
||||
parse_tree(menu_parse_inst, doc, node->xmlChildrenNode);
|
||||
xmlFreeDoc(doc);
|
||||
|
||||
g_assert(menu_parse_state.menus == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,6 +103,37 @@ void menu_shutdown()
|
|||
menu_hash = NULL;
|
||||
}
|
||||
|
||||
void menu_pipe_execute(ObMenu *self)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
gchar *output;
|
||||
GError *err = NULL;
|
||||
|
||||
if (!self->execute)
|
||||
return;
|
||||
|
||||
if (!g_spawn_command_line_sync(self->execute, &output, NULL, NULL, &err))
|
||||
{
|
||||
g_warning("Failed to execute command for pipe-menu: %s", err->message);
|
||||
g_error_free(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (parse_load_mem(output, strlen(output),
|
||||
"openbox_pipe_menu", &doc, &node))
|
||||
{
|
||||
menu_clear_entries(self);
|
||||
|
||||
menu_parse_state.menus = g_slist_prepend(NULL, self);
|
||||
parse_tree(menu_parse_inst, doc, node->xmlChildrenNode);
|
||||
menu_parse_state.menus = g_slist_remove(menu_parse_state.menus, self);
|
||||
xmlFreeDoc(doc);
|
||||
|
||||
g_assert(menu_parse_state.menus == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static ObMenu* menu_from_name(gchar *name)
|
||||
{
|
||||
ObMenu *self = NULL;
|
||||
|
@ -146,7 +179,7 @@ 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, *script = NULL;
|
||||
ObMenu *menu;
|
||||
|
||||
if (!parse_attr_string("id", node, &name))
|
||||
|
@ -157,11 +190,15 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
|||
goto parse_menu_fail;
|
||||
|
||||
if ((menu = menu_new(name, title, NULL))) {
|
||||
if (parse_attr_string("execute", node, &script)) {
|
||||
menu->execute = g_strdup(script);
|
||||
} else {
|
||||
state->menus = g_slist_prepend(state->menus, menu);
|
||||
parse_tree(i, doc, node->xmlChildrenNode);
|
||||
state->menus = g_slist_delete_link(state->menus, state->menus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state->menus)
|
||||
menu_add_submenu(state->menus->data, -1, name);
|
||||
|
@ -169,8 +206,22 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
|||
parse_menu_fail:
|
||||
g_free(name);
|
||||
g_free(title);
|
||||
g_free(script);
|
||||
}
|
||||
|
||||
ObMenu* menu_new(gchar *name, gchar *title, gpointer data)
|
||||
{
|
||||
ObMenu *self;
|
||||
|
||||
self = g_new0(ObMenu, 1);
|
||||
self->name = g_strdup(name);
|
||||
self->title = g_strdup(title);
|
||||
self->data = data;
|
||||
|
||||
g_hash_table_replace(menu_hash, self->name, self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void menu_destroy_hash_value(ObMenu *self)
|
||||
{
|
||||
|
@ -182,22 +233,7 @@ static void menu_destroy_hash_value(ObMenu *self)
|
|||
menu_clear_entries(self);
|
||||
g_free(self->name);
|
||||
g_free(self->title);
|
||||
}
|
||||
|
||||
ObMenu* menu_new(gchar *name, gchar *title, gpointer data)
|
||||
{
|
||||
ObMenu *self;
|
||||
|
||||
/*if (g_hash_table_lookup(menu_hash, name)) return FALSE;*/
|
||||
|
||||
self = g_new0(ObMenu, 1);
|
||||
self->name = g_strdup(name);
|
||||
self->title = g_strdup(title);
|
||||
self->data = data;
|
||||
|
||||
g_hash_table_replace(menu_hash, self->name, self);
|
||||
|
||||
return self;
|
||||
g_free(self->execute);
|
||||
}
|
||||
|
||||
void menu_free(ObMenu *menu)
|
||||
|
|
|
@ -23,8 +23,6 @@ typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data);
|
|||
typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry, gpointer data);
|
||||
typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
|
||||
|
||||
extern ObParseInst *menu_parse_inst;
|
||||
|
||||
struct _ObMenu
|
||||
{
|
||||
/* Name of the menu. Used in the showmenu action. */
|
||||
|
@ -32,6 +30,9 @@ struct _ObMenu
|
|||
/* Displayed title */
|
||||
gchar *title;
|
||||
|
||||
/* Command to execute to rebuild the menu */
|
||||
gchar *execute;
|
||||
|
||||
/* ObMenuEntry list */
|
||||
GList *entries;
|
||||
|
||||
|
@ -94,6 +95,9 @@ void menu_shutdown();
|
|||
ObMenu* menu_new(gchar *name, gchar *title, gpointer data);
|
||||
void menu_free(ObMenu *menu);
|
||||
|
||||
/* Repopulate a pipe-menu by running its command */
|
||||
void menu_pipe_execute(ObMenu *self);
|
||||
|
||||
void menu_show(gchar *name, gint x, gint y, struct _ObClient *client);
|
||||
|
||||
void menu_set_update_func(ObMenu *menu, ObMenuUpdateFunc func);
|
||||
|
|
Loading…
Reference in a new issue