Menu uber patch Since we have no menu parser see menu_startup() to customize
Scott Moynes smoynes@nexus.carleton.ca
12 files changed,
874 insertions(+),
86 deletions(-)
M
configure.ac
→
configure.ac
@@ -72,6 +72,7 @@ plugins/Makefile
plugins/placement/Makefile plugins/mouse/Makefile plugins/keyboard/Makefile + plugins/menu/Makefile]) tools/Makefile tools/slit/Makefile]) AC_OUTPUT
M
openbox/event.c
→
openbox/event.c
@@ -378,6 +378,7 @@
window = event_get_window(e); if (!(client = g_hash_table_lookup(client_map, &window))) menu = g_hash_table_lookup(menu_map, &window); + event_set_lasttime(e); event_hack_mods(e); if (event_ignore(e, client))@@ -858,10 +859,12 @@
g_message("EVENT %d", e->type); switch (e->type) { case ButtonPress: + g_message("BUTTON PRESS"); if (e->xbutton.button == 3) menu_hide(menu); break; case ButtonRelease: + g_message("BUTTON RELEASED"); if (!menu->shown) break; /* grab_pointer_window(FALSE, None, menu->frame);*/@@ -879,16 +882,21 @@ e->xbutton.x < (signed)(w+b) &&
e->xbutton.y < (signed)(h+b)) { menu_entry_fire(entry); } - } + break; case EnterNotify: case LeaveNotify: g_message("enter/leave"); entry = menu_find_entry(menu, e->xcrossing.window); if (entry) { - entry->hilite = e->type == EnterNotify; + if (menu->mouseover) + menu->mouseover(entry, e->type == EnterNotify); + else + menu_control_mouseover(entry, e->type == EnterNotify); + menu_entry_render(entry); } break; + } } }
M
openbox/plugin.c
→
openbox/plugin.c
@@ -4,6 +4,8 @@
typedef void (*PluginSetupConfig)(); typedef void (*PluginStartup)(); typedef void (*PluginShutdown)(); +typedef void *(*PluginCreate)(/* TODO */); +typedef void (*PluginDestroy)(void *); typedef struct { GModule *module;@@ -12,14 +14,18 @@
PluginSetupConfig config; PluginStartup startup; PluginShutdown shutdown; + PluginCreate create; + PluginDestroy destroy; } Plugin; -static gpointer load_sym(GModule *module, char *name, char *symbol) +static gpointer load_sym(GModule *module, char *name, char *symbol, + gboolean allow_fail) { gpointer var; if (!g_module_symbol(module, symbol, &var)) { - g_warning("Failed to load symbol '%s' from plugin '%s'", - symbol, name); + if (!allow_fail) + g_warning("Failed to load symbol '%s' from plugin '%s'", + symbol, name); var = NULL; } return var;@@ -50,9 +56,14 @@ return NULL;
} p->config = (PluginSetupConfig)load_sym(p->module, name, - "plugin_setup_config"); - p->startup = (PluginStartup)load_sym(p->module, name, "plugin_startup"); - p->shutdown = (PluginShutdown)load_sym(p->module, name, "plugin_shutdown"); + "plugin_setup_config", FALSE); + p->startup = (PluginStartup)load_sym(p->module, name, "plugin_startup", + FALSE); + p->shutdown = (PluginShutdown)load_sym(p->module, name, "plugin_shutdown", + FALSE); + p->create = (PluginCreate)load_sym(p->module, name, "plugin_create", TRUE); + p->destroy = (PluginDestroy)load_sym(p->module, name, "plugin_destroy", + TRUE); if (p->config == NULL || p->startup == NULL || p->shutdown == NULL) { g_module_close(p->module);@@ -85,12 +96,13 @@ {
g_datalist_clear(&plugins); } -gboolean plugin_open(char *name) +gboolean plugin_open_full(char *name, gboolean reopen) { Plugin *p; if (g_datalist_get_data(&plugins, name) != NULL) { - g_warning("plugin '%s' already loaded, can't load again", name); + if (!reopen) + g_warning("plugin '%s' already loaded, can't load again", name); return TRUE; }@@ -105,6 +117,14 @@ g_datalist_set_data_full(&plugins, name, p, (GDestroyNotify) plugin_free);
return TRUE; } +gboolean plugin_open(char *name) { + return plugin_open_full(name, FALSE); +} + +gboolean plugin_open_reopen(char *name) { + return plugin_open_full(name, TRUE); +} + void plugin_close(char *name) { g_datalist_remove_data(&plugins, name);@@ -156,3 +176,41 @@ }
g_io_channel_unref(io); } } + +void *plugin_create(char *name /* TODO */) +{ + Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name); + + if (p == NULL) { + g_warning("Unable to find plugin for create: %s", name); + return NULL; + } + + if (p->create == NULL || p->destroy == NULL) { + g_critical("Unsupported create/destroy: %s", name); + return NULL; + } + + return p->create(); +} + +void plugin_destroy(char *name, void *data) +{ + Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name); + + if (p == NULL) { + g_critical("Unable to find plugin for destroy: %s", name); + /* really shouldn't happen, but attempt to free something anyway? */ + g_free(data); + return; + } + + if (p->destroy == NULL || p->create == NULL) { + g_critical("Unsupported create/destroy: %s", name); + /* really, really shouldn't happen, but attempt to free anyway? */ + g_free(data); + return; + } + + p->destroy(data); +}
M
openbox/plugin.h
→
openbox/plugin.h
@@ -7,7 +7,15 @@
void plugin_loadall(); void plugin_startall(); +/* default plugin */ gboolean plugin_open(char *name); +/* load a plugin, but don't warn about reopens. for menus */ +gboolean plugin_open_reopen(char *name); void plugin_close(char *name); + +/* call plugin's generic constructor */ +void *plugin_create(char *name /* TODO */); +/* free memory allocated by plugin_create() */ +void plugin_destroy(char *name, void *object); #endif
M
openbox/timer.c
→
openbox/timer.c
@@ -15,7 +15,7 @@ {
long r; if ((r = b->tv_sec - a->tv_sec)) return r; - return b->tv_usec - a->tv_sec; + return b->tv_usec - a->tv_usec; }@@ -108,7 +108,7 @@ }
/* the queue is sorted, so if this timer shouldn't fire, none are ready */ - if (timecompare(&now, &NEAREST_TIMEOUT) <= 0) + if (timecompare(&NEAREST_TIMEOUT, &now) <= 0) break; /* we set the last fired time to delay msec after the previous firing,
M
plugins/Makefile.am
→
plugins/Makefile.am
@@ -1,6 +1,6 @@
-plugindir=$(libdir)/openbox/plugins +XFplugindir=$(libdir)/openbox/plugins -SUBDIRS = keyboard mouse placement +SUBDIRS = keyboard mouse placement menu CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \ -DPLUGINDIR=\"$(plugindir)\"