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 "client_list_menu.h"
|
||||||
#include "parser/parse.h"
|
#include "parser/parse.h"
|
||||||
|
|
||||||
static GHashTable *menu_hash = NULL;
|
|
||||||
|
|
||||||
ObParseInst *menu_parse_inst;
|
|
||||||
|
|
||||||
typedef struct _ObMenuParseState ObMenuParseState;
|
typedef struct _ObMenuParseState ObMenuParseState;
|
||||||
|
|
||||||
struct _ObMenuParseState
|
struct _ObMenuParseState
|
||||||
|
@ -24,6 +20,10 @@ struct _ObMenuParseState
|
||||||
GSList *menus;
|
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 menu_destroy_hash_value(ObMenu *self);
|
||||||
static void parse_menu_item(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
static void parse_menu_item(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
@ -57,7 +57,6 @@ static gboolean menu_open(gchar *file, xmlDocPtr *doc, xmlNodePtr *node)
|
||||||
|
|
||||||
void menu_startup()
|
void menu_startup()
|
||||||
{
|
{
|
||||||
ObMenuParseState parse_state;
|
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
gboolean loaded = FALSE;
|
gboolean loaded = FALSE;
|
||||||
|
@ -80,14 +79,17 @@ void menu_startup()
|
||||||
loaded = menu_open("menu", &doc, &node);
|
loaded = menu_open("menu", &doc, &node);
|
||||||
|
|
||||||
if (loaded) {
|
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, "menu", parse_menu, &menu_parse_state);
|
||||||
parse_register(menu_parse_inst, "item", parse_menu_item, &parse_state);
|
parse_register(menu_parse_inst, "item", parse_menu_item,
|
||||||
|
&menu_parse_state);
|
||||||
parse_register(menu_parse_inst, "separator",
|
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);
|
parse_tree(menu_parse_inst, doc, node->xmlChildrenNode);
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
|
|
||||||
|
g_assert(menu_parse_state.menus == NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +103,37 @@ void menu_shutdown()
|
||||||
menu_hash = NULL;
|
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)
|
static ObMenu* menu_from_name(gchar *name)
|
||||||
{
|
{
|
||||||
ObMenu *self = NULL;
|
ObMenu *self = NULL;
|
||||||
|
@ -146,7 +179,7 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
ObMenuParseState *state = data;
|
ObMenuParseState *state = data;
|
||||||
gchar *name = NULL, *title = NULL;
|
gchar *name = NULL, *title = NULL, *script = NULL;
|
||||||
ObMenu *menu;
|
ObMenu *menu;
|
||||||
|
|
||||||
if (!parse_attr_string("id", node, &name))
|
if (!parse_attr_string("id", node, &name))
|
||||||
|
@ -157,9 +190,13 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||||
goto parse_menu_fail;
|
goto parse_menu_fail;
|
||||||
|
|
||||||
if ((menu = menu_new(name, title, NULL))) {
|
if ((menu = menu_new(name, title, NULL))) {
|
||||||
state->menus = g_slist_prepend(state->menus, menu);
|
if (parse_attr_string("execute", node, &script)) {
|
||||||
parse_tree(i, doc, node->xmlChildrenNode);
|
menu->execute = g_strdup(script);
|
||||||
state->menus = g_slist_delete_link(state->menus, state->menus);
|
} 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,8 +206,22 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||||
parse_menu_fail:
|
parse_menu_fail:
|
||||||
g_free(name);
|
g_free(name);
|
||||||
g_free(title);
|
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)
|
static void menu_destroy_hash_value(ObMenu *self)
|
||||||
{
|
{
|
||||||
|
@ -182,22 +233,7 @@ static void menu_destroy_hash_value(ObMenu *self)
|
||||||
menu_clear_entries(self);
|
menu_clear_entries(self);
|
||||||
g_free(self->name);
|
g_free(self->name);
|
||||||
g_free(self->title);
|
g_free(self->title);
|
||||||
}
|
g_free(self->execute);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_free(ObMenu *menu)
|
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 (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry, gpointer data);
|
||||||
typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
|
typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
|
||||||
|
|
||||||
extern ObParseInst *menu_parse_inst;
|
|
||||||
|
|
||||||
struct _ObMenu
|
struct _ObMenu
|
||||||
{
|
{
|
||||||
/* Name of the menu. Used in the showmenu action. */
|
/* Name of the menu. Used in the showmenu action. */
|
||||||
|
@ -32,6 +30,9 @@ struct _ObMenu
|
||||||
/* Displayed title */
|
/* Displayed title */
|
||||||
gchar *title;
|
gchar *title;
|
||||||
|
|
||||||
|
/* Command to execute to rebuild the menu */
|
||||||
|
gchar *execute;
|
||||||
|
|
||||||
/* ObMenuEntry list */
|
/* ObMenuEntry list */
|
||||||
GList *entries;
|
GList *entries;
|
||||||
|
|
||||||
|
@ -94,6 +95,9 @@ void menu_shutdown();
|
||||||
ObMenu* menu_new(gchar *name, gchar *title, gpointer data);
|
ObMenu* menu_new(gchar *name, gchar *title, gpointer data);
|
||||||
void menu_free(ObMenu *menu);
|
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_show(gchar *name, gint x, gint y, struct _ObClient *client);
|
||||||
|
|
||||||
void menu_set_update_func(ObMenu *menu, ObMenuUpdateFunc func);
|
void menu_set_update_func(ObMenu *menu, ObMenuUpdateFunc func);
|
||||||
|
|
Loading…
Reference in a new issue