fix for using freed memory to exec stuff
This commit is contained in:
parent
5efc7236a6
commit
9e85e930da
4 changed files with 56 additions and 38 deletions
|
@ -12,7 +12,9 @@
|
|||
#include "misc.h"
|
||||
#include "parser/parse.h"
|
||||
|
||||
GHashTable *menu_hash = NULL;
|
||||
static GHashTable *menu_hash = NULL;
|
||||
|
||||
ObParseInst *menu_parse_inst;
|
||||
|
||||
typedef struct _ObMenuParseState ObMenuParseState;
|
||||
|
||||
|
@ -129,69 +131,80 @@ void menu_startup(ObParseInst *i)
|
|||
{
|
||||
menu_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
|
||||
(GDestroyNotify)menu_destroy_hash_value);
|
||||
menu_parse_inst = parse_startup();
|
||||
}
|
||||
|
||||
void menu_shutdown()
|
||||
{
|
||||
parse_shutdown(menu_parse_inst);
|
||||
menu_parse_inst = NULL;
|
||||
|
||||
menu_frame_hide_all();
|
||||
g_hash_table_destroy(menu_hash);
|
||||
menu_hash = NULL;
|
||||
}
|
||||
|
||||
gboolean menu_open(gchar *file, xmlDocPtr *doc, xmlNodePtr *node)
|
||||
{
|
||||
gboolean loaded = TRUE;
|
||||
gchar *p;
|
||||
|
||||
p = g_build_filename(g_get_home_dir(), ".openbox", file, NULL);
|
||||
if (!parse_load(p, "openbox_menu", doc, node)) {
|
||||
g_free(p);
|
||||
p = g_build_filename(RCDIR, file, NULL);
|
||||
if (!parse_load(p, "openbox_menu", doc, node)) {
|
||||
g_free(p);
|
||||
p = g_strdup(file);
|
||||
if (!parse_load(p, "openbox_menu", doc, node)) {
|
||||
g_warning("Failed to load menu from '%s'", file);
|
||||
loaded = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_free(p);
|
||||
return loaded;
|
||||
}
|
||||
|
||||
void menu_parse()
|
||||
{
|
||||
ObParseInst *i;
|
||||
ObMenuParseState parse_state;
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
gchar *p;
|
||||
gboolean loaded = FALSE;
|
||||
GSList *it;
|
||||
|
||||
i = parse_startup();
|
||||
for (it = config_menu_files; it; it = g_slist_next(it)) {
|
||||
if (menu_open(it->data, &doc, &node))
|
||||
loaded = TRUE;
|
||||
|
||||
if (config_menu_path)
|
||||
if (!(loaded =
|
||||
parse_load(config_menu_path, "openbox_menu", &doc, &node)))
|
||||
g_warning("Failed to load menu from '%s'", config_menu_path);
|
||||
if (!loaded) {
|
||||
p = g_build_filename(g_get_home_dir(), ".openbox", "menu", NULL);
|
||||
if (!(loaded =
|
||||
parse_load(p, "openbox_menu", &doc, &node)))
|
||||
g_warning("Failed to load menu from '%s'", p);
|
||||
g_free(p);
|
||||
}
|
||||
if (!loaded) {
|
||||
p = g_build_filename(RCDIR, "menu", NULL);
|
||||
if (!(loaded =
|
||||
parse_load(p, "openbox_menu", &doc, &node)))
|
||||
g_warning("Failed to load menu from '%s'", p);
|
||||
g_free(p);
|
||||
}
|
||||
if (!loaded)
|
||||
loaded = menu_open("menu", &doc, &node);
|
||||
|
||||
if (loaded) {
|
||||
parse_state.menus = NULL;
|
||||
|
||||
parse_register(i, "menu", parse_menu, &parse_state);
|
||||
parse_register(i, "item", parse_menu_item, &parse_state);
|
||||
parse_register(i, "separator", parse_menu_separator, &parse_state);
|
||||
parse_tree(i, doc, node->xmlChildrenNode);
|
||||
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, "separator",
|
||||
parse_menu_separator, &parse_state);
|
||||
parse_tree(menu_parse_inst, doc, node->xmlChildrenNode);
|
||||
}
|
||||
|
||||
parse_shutdown(i);
|
||||
}
|
||||
|
||||
gboolean menu_new(gchar *name, gchar *title, gpointer data)
|
||||
{
|
||||
ObMenu *self;
|
||||
|
||||
if (g_hash_table_lookup(menu_hash, name)) return FALSE;
|
||||
/*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_insert(menu_hash, self->name, self);
|
||||
g_hash_table_replace(menu_hash, self->name, self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -20,11 +20,10 @@ typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry;
|
|||
typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry;
|
||||
|
||||
typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data);
|
||||
typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntryFrame *frame,
|
||||
gpointer data);
|
||||
typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry, gpointer data);
|
||||
typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
|
||||
|
||||
extern GList *menu_visible;
|
||||
extern ObParseInst *menu_parse_inst;
|
||||
|
||||
struct _ObMenu
|
||||
{
|
||||
|
|
|
@ -572,16 +572,22 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self)
|
|||
void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide)
|
||||
{
|
||||
if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
|
||||
/* grab all this shizzle, cuz when the menu gets hidden, 'self'
|
||||
gets freed */
|
||||
ObMenuEntry *entry = self->entry;
|
||||
ObMenuExecuteFunc func = self->frame->menu->execute_func;
|
||||
gpointer data = self->frame->menu->data;
|
||||
GSList *acts = self->entry->data.normal.actions;
|
||||
|
||||
/* release grabs before executing the shit */
|
||||
menu_frame_hide_all();
|
||||
|
||||
if (self->frame->menu->execute_func)
|
||||
self->frame->menu->execute_func(self, self->frame->menu->data);
|
||||
if (func)
|
||||
func(entry, data);
|
||||
else {
|
||||
GSList *it;
|
||||
|
||||
for (it = self->entry->data.normal.actions; it;
|
||||
it = g_slist_next(it))
|
||||
for (it = acts; it; it = g_slist_next(it))
|
||||
{
|
||||
ObAction *act = it->data;
|
||||
act->data.any.c = self->frame->client;
|
||||
|
|
|
@ -60,11 +60,11 @@ static void desk_menu_update(ObMenuFrame *frame, gpointer data)
|
|||
|
||||
/* executes it without changing the client in the actions, since we set that
|
||||
when we make the actions! */
|
||||
static void desk_menu_execute(ObMenuEntryFrame *self, gpointer data)
|
||||
static void desk_menu_execute(ObMenuEntry *self, gpointer data)
|
||||
{
|
||||
GSList *it;
|
||||
|
||||
for (it = self->entry->data.normal.actions; it; it = g_slist_next(it))
|
||||
for (it = self->data.normal.actions; it; it = g_slist_next(it))
|
||||
{
|
||||
ObAction *act = it->data;
|
||||
act->func(&act->data);
|
||||
|
|
Loading…
Reference in a new issue