add pipe-menus

This commit is contained in:
Dana Jansens 2003-08-30 05:15:12 +00:00
parent 3ff8eb037e
commit c3b02749d7
2 changed files with 71 additions and 31 deletions

View file

@ -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)

View file

@ -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);