From: Scott Moynes Date: Fri, 9 May 2003 23:15:28 +0000 (+0000) Subject: Menu uber patch X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=a8a4a2cca30602b66b7a7f68bb9f3fffd34e92c9;p=chaz%2Fopenbox Menu uber patch Since we have no menu parser see menu_startup() to customize --- diff --git a/configure.ac b/configure.ac index 9b914efa..23c8ca40 100644 --- a/configure.ac +++ b/configure.ac @@ -72,6 +72,7 @@ AC_CONFIG_FILES([Makefile plugins/placement/Makefile plugins/mouse/Makefile plugins/keyboard/Makefile + plugins/menu/Makefile]) tools/Makefile tools/slit/Makefile]) AC_OUTPUT diff --git a/openbox/event.c b/openbox/event.c index 2e2d5c0c..5dd1f705 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -378,6 +378,7 @@ static void event_process(XEvent *e) 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 @@ static void event_handle_menu(Menu *menu, XEvent *e) 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 @@ static void event_handle_menu(Menu *menu, XEvent *e) 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; + } } } diff --git a/openbox/menu.c b/openbox/menu.c index 88eef9c5..b271cf31 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -3,11 +3,15 @@ #include "stacking.h" #include "grab.h" #include "render/theme.h" +#include "screen.h" +#include "geom.h" +#include "plugin.h" static GHashTable *menu_hash = NULL; GHashTable *menu_map = NULL; -#define FRAME_EVENTMASK (ButtonMotionMask | EnterWindowMask | LeaveWindowMask) +#define FRAME_EVENTMASK (ButtonPressMask |ButtonMotionMask | EnterWindowMask | \ + LeaveWindowMask) #define TITLE_EVENTMASK (ButtonPressMask | ButtonMotionMask) #define ENTRY_EVENTMASK (EnterWindowMask | LeaveWindowMask | \ ButtonPressMask | ButtonReleaseMask) @@ -60,6 +64,8 @@ void menu_entry_free(MenuEntry *self) void menu_startup() { Menu *m; + Menu *s; + Menu *t; Action *a; menu_hash = g_hash_table_new_full(g_str_hash, g_str_equal, @@ -67,15 +73,50 @@ void menu_startup() (GDestroyNotify)menu_destroy_hash_value); menu_map = g_hash_table_new(g_int_hash, g_int_equal); - m = menu_new("sex menu", "root", NULL); + m = menu_new(NULL, "root", NULL); + a = action_from_string("execute"); a->data.execute.path = g_strdup("xterm"); menu_add_entry(m, menu_entry_new("xterm", a)); a = action_from_string("restart"); menu_add_entry(m, menu_entry_new("restart", a)); - menu_add_entry(m, menu_entry_new("--", NULL)); + menu_add_entry(m, menu_entry_new_separator("--")); a = action_from_string("exit"); menu_add_entry(m, menu_entry_new("exit", a)); + s = menu_new("subsex menu", "submenu", m); + a = action_from_string("execute"); + a->data.execute.path = g_strdup("xclock"); + menu_add_entry(s, menu_entry_new("xclock", a)); + + menu_add_entry(m, menu_entry_new_submenu("subz", s)); + + /* + t = (Menu *)plugin_create("timed_menu"); + a = action_from_string("execute"); + a->data.execute.path = g_strdup("xeyes"); + menu_add_entry(t, menu_entry_new("xeyes", a));*/ + + s = menu_new("empty", "chub", m); + menu_add_entry(m, menu_entry_new_submenu("empty", s)); + + s = menu_new("", "s-club", m); + menu_add_entry(m, menu_entry_new_submenu("empty", s)); + + s = menu_new(NULL, "h-club", m); + menu_add_entry(m, menu_entry_new_submenu("empty", s)); + + s = menu_new(NULL, "g-club", m); + + a = action_from_string("execute"); + a->data.execute.path = g_strdup("xterm"); + menu_add_entry(s, menu_entry_new("xterm", a)); + a = action_from_string("restart"); + menu_add_entry(s, menu_entry_new("restart", a)); + menu_add_entry(s, menu_entry_new_separator("--")); + a = action_from_string("exit"); + menu_add_entry(s, menu_entry_new("exit", a)); + + menu_add_entry(m, menu_entry_new_submenu("long", s)); m = menu_new("client menu", "client", NULL); a = action_from_string("iconify"); @@ -86,6 +127,7 @@ void menu_startup() menu_add_entry(m, menu_entry_new("(un)maximize", a)); a = action_from_string("close"); menu_add_entry(m, menu_entry_new("close", a)); + } void menu_shutdown() @@ -113,18 +155,22 @@ Menu *menu_new_full(char *label, char *name, Menu *parent, self->label = g_strdup(label); self->name = g_strdup(name); self->parent = parent; + self->open_submenu = NULL; self->entries = NULL; self->shown = FALSE; - self->invalid = FALSE; - /* default controllers? */ - + self->invalid = TRUE; + + /* default controllers */ self->show = show; self->hide = NULL; self->update = update; self->mouseover = NULL; self->selected = NULL; + self->plugin = NULL; + self->plugin_data = NULL; + attrib.override_redirect = TRUE; attrib.event_mask = FRAME_EVENTMASK; self->frame = createWindow(ob_root, CWOverrideRedirect|CWEventMask, &attrib); @@ -133,6 +179,7 @@ Menu *menu_new_full(char *label, char *name, Menu *parent, self->items = createWindow(self->frame, 0, &attrib); XSetWindowBorderWidth(ob_display, self->frame, theme_bwidth); + XSetWindowBackground(ob_display, self->frame, theme_b_color->pixel); XSetWindowBorderWidth(ob_display, self->title, theme_bwidth); XSetWindowBorder(ob_display, self->frame, theme_b_color->pixel); XSetWindowBorder(ob_display, self->title, theme_b_color->pixel); @@ -207,35 +254,42 @@ void menu_add_entry(Menu *menu, MenuEntry *entry) void menu_show(char *name, int x, int y, Client *client) { Menu *self; - + self = g_hash_table_lookup(menu_hash, name); if (!self) { g_warning("Attempted to show menu '%s' but it does not exist.", name); return; } + + menu_show_full(self, x, y, client); +} - if (self->invalid) { - if (self->update) { - self->update(self); - } else { - menu_render(self); - } - } +void menu_show_full(Menu *self, int x, int y, Client *client) +{ + g_assert(self != NULL); + + menu_render(self); self->client = client; if (self->show) { - self->show(self, x, y, client); + self->show(self, x, y, client); } else { menu_control_show(self, x, y, client); } } + void menu_hide(Menu *self) { if (self->shown) { XUnmapWindow(ob_display, self->frame); self->shown = FALSE; + if (self->open_submenu) + menu_hide(self->open_submenu); + if (self->parent && self->parent->open_submenu == self) + self->parent->open_submenu = NULL; + } } @@ -251,29 +305,6 @@ MenuEntry *menu_find_entry(Menu *menu, Window win) return NULL; } -void menu_entry_render(MenuEntry *self) -{ - Menu *menu = self->parent; - Appearance *a; - - a = !self->enabled ? self->a_disabled : - (self->hilite && self->action ? self->a_hilite : self->a_item); - - RECT_SET(a->area, 0, 0, menu->width, - menu->item_h); - RECT_SET(a->texture[0].position, menu->bullet_w, - 0, menu->width - 2 * menu->bullet_w, - menu->item_h); - - XMoveResizeWindow(ob_display, self->item, 0, self->y, - menu->width, menu->item_h); - a->surface.data.planar.parent = menu->a_items; - a->surface.data.planar.parentx = 0; - a->surface.data.planar.parenty = self->y; - - paint(self->item, a); -} - void menu_entry_fire(MenuEntry *self) { Menu *m; @@ -294,11 +325,52 @@ void menu_entry_fire(MenuEntry *self) */ void menu_control_show(Menu *self, int x, int y, Client *client) { - XMoveWindow(ob_display, self->frame, x, y); + g_assert(!self->invalid); + + XMoveWindow(ob_display, self->frame, + MIN(x, screen_physical_size.width - self->size.width), + MIN(y, screen_physical_size.height - self->size.height)); + POINT_SET(self->location, + MIN(x, screen_physical_size.width - self->size.width), + MIN(y, screen_physical_size.height - self->size.height)); + + if (!self->shown) { + stacking_raise_internal(self->frame); + XMapWindow(ob_display, self->frame); + self->shown = TRUE; + } else if (self->shown && self->open_submenu) { + menu_hide(self->open_submenu); + } +} - if (!self->shown) { - stacking_raise_internal(self->frame); - XMapWindow(ob_display, self->frame); - self->shown = TRUE; - } +void menu_control_mouseover(MenuEntry *self, gboolean enter) { + int x; + self->hilite = enter; + + if (enter) { + if (self->parent->open_submenu && self->submenu + != self->parent->open_submenu) + menu_hide(self->parent->open_submenu); + + if (self->submenu) { + self->parent->open_submenu = self->submenu; + + /* shouldn't be invalid since it must be displayed */ + g_assert(!self->parent->invalid); + /* TODO: I don't understand why these bevels should be here. + Something must be wrong in the width calculation */ + x = self->parent->location.x + self->parent->size.width + + theme_bevel; + + /* need to get the width. is this bad?*/ + menu_render(self->submenu); + + if (self->submenu->size.width + x > screen_physical_size.width) + x = self->parent->location.x - self->submenu->size.width - + theme_bevel; + + menu_show_full(self->submenu, x, + self->parent->location.y + self->y, NULL); + } + } } diff --git a/openbox/menu.h b/openbox/menu.h index 1a3f002a..081b3528 100644 --- a/openbox/menu.h +++ b/openbox/menu.h @@ -3,15 +3,19 @@ #include "action.h" #include "render/render.h" +#include "geom.h" #include extern GHashTable *menu_map; struct Menu; +struct MenuEntry; typedef void(*menu_controller_show)(struct Menu *self, int x, int y, Client *); typedef void(*menu_controller_update)(struct Menu *self); +typedef void(*menu_controller_mouseover)(struct MenuEntry *self, + gboolean enter); typedef struct Menu { char *label; @@ -23,6 +27,8 @@ typedef struct Menu { gboolean invalid; struct Menu *parent; + + struct Menu *open_submenu; /* place a menu on screen */ menu_controller_show show; @@ -30,7 +36,7 @@ typedef struct Menu { /* render a menu */ menu_controller_update update; - void (*mouseover)( /* some bummu */); + menu_controller_mouseover mouseover; void (*selected)( /* some bummu */); @@ -44,7 +50,12 @@ typedef struct Menu { Appearance *a_items; int bullet_w; int item_h; - int width; + Point location; + Size size; + + /* plugin stuff */ + char *plugin; + void *plugin_data; } Menu; typedef enum MenuEntryRenderType { @@ -89,6 +100,8 @@ Menu *menu_new_full(char *label, char *name, Menu *parent, void menu_free(char *name); void menu_show(char *name, int x, int y, Client *client); +void menu_show_full(Menu *menu, int x, int y, Client *client); + void menu_hide(Menu *self); MenuEntry *menu_entry_new_full(char *label, Action *action, @@ -96,7 +109,16 @@ MenuEntry *menu_entry_new_full(char *label, Action *action, gpointer submenu); #define menu_entry_new(label, action) \ - menu_entry_new_full(label, action, MenuEntryRenderType_None, NULL) +menu_entry_new_full(label, action, MenuEntryRenderType_None, NULL) + +#define menu_entry_new_separator(label) \ +menu_entry_new_full(label, NULL, MenuEntryRenderType_Separator, NULL) + +#define menu_entry_new_submenu(label, submenu) \ +menu_entry_new_full(label, NULL, MenuEntryRenderType_Submenu, submenu) + +#define menu_entry_new_boolean(label, action) \ +menu_entry_new_full(label, action, MenuEntryRenderType_Boolean, NULL) void menu_entry_free(MenuEntry *entry); @@ -112,4 +134,5 @@ void menu_entry_fire(MenuEntry *self); void menu_render(Menu *self); +void menu_control_mouseover(MenuEntry *entry, gboolean enter); #endif diff --git a/openbox/menu_render.c b/openbox/menu_render.c index cf961f24..6a95fcbb 100644 --- a/openbox/menu_render.c +++ b/openbox/menu_render.c @@ -4,21 +4,36 @@ #include "openbox.h" #include "render/theme.h" +void menu_render_full(Menu *self); + void menu_render(Menu *self) { + if (self->invalid) { + if (self->update) { + self->update(self); + } else { + menu_render_full(self); + } + } +} + + +void menu_render_full(Menu *self) { GList *it; - int items_h; + int items_h = 0; int nitems = 0; /* each item, only one is used */ int item_y; - self->width = 1; - self->item_h = 0; + self->size.width = 1; + self->item_h = 1; /* set texture data and size them mofos out */ - self->a_title->texture[0].data.text.string = self->label; - appearance_minsize(self->a_title, &self->title_min_w, &self->title_h); - self->title_min_w += theme_bevel * 2; - self->title_h += theme_bevel * 2; - self->width = MAX(self->width, self->title_min_w); + if (self->label) { + self->a_title->texture[0].data.text.string = self->label; + appearance_minsize(self->a_title, &self->title_min_w, &self->title_h); + self->title_min_w += theme_bevel * 2; + self->title_h += theme_bevel * 2; + self->size.width = MAX(self->size.width, self->title_min_w); + } for (it = self->entries; it; it = it->next) { MenuEntry *e = it->data; @@ -26,39 +41,44 @@ void menu_render(Menu *self) { e->a_item->texture[0].data.text.string = e->label; appearance_minsize(e->a_item, &e->min_w, &self->item_h); - self->width = MAX(self->width, e->min_w); + self->size.width = MAX(self->size.width, e->min_w); e->a_disabled->texture[0].data.text.string = e->label; appearance_minsize(e->a_disabled, &e->min_w, &h); self->item_h = MAX(self->item_h, h); - self->width = MAX(self->width, e->min_w); - + self->size.width = MAX(self->size.width, e->min_w); + e->a_hilite->texture[0].data.text.string = e->label; appearance_minsize(e->a_hilite, &e->min_w, &h); self->item_h = MAX(self->item_h, h); - self->width = MAX(self->width, e->min_w); + self->size.width = MAX(self->size.width, e->min_w); e->min_w += theme_bevel * 2; ++nitems; } self->bullet_w = self->item_h + theme_bevel; - self->width += 2 * self->bullet_w; + self->size.width += 2 * self->bullet_w + 2 * theme_bevel; self->item_h += theme_bevel * 2; - items_h = self->item_h * nitems; + items_h = self->item_h * MAX(nitems, 1); + + if (self->label) { + RECT_SET(self->a_title->area, 0, 0, self->size.width, self->title_h); + RECT_SET(self->a_title->texture[0].position, 0, 0, self->size.width, + self->title_h); + } - RECT_SET(self->a_title->area, 0, 0, self->width, self->title_h); - RECT_SET(self->a_title->texture[0].position, 0, 0, self->width, - self->title_h); - RECT_SET(self->a_items->area, 0, 0, self->width, items_h); + RECT_SET(self->a_items->area, 0, 0, self->size.width, items_h); - XResizeWindow(ob_display, self->frame, self->width, - self->title_h + items_h); - XMoveResizeWindow(ob_display, self->title, -theme_bwidth, -theme_bwidth, - self->width, self->title_h); + XResizeWindow(ob_display, self->frame, self->size.width, + MAX(self->title_h + items_h, 1)); + if (self->label) + XMoveResizeWindow(ob_display, self->title, -theme_bwidth, + -theme_bwidth, self->size.width, self->title_h); XMoveResizeWindow(ob_display, self->items, 0, self->title_h + theme_bwidth, - self->width, items_h); + self->size.width, items_h); - paint(self->title, self->a_title); + if (self->label) + paint(self->title, self->a_title); paint(self->items, self->a_items); item_y = 0; @@ -67,6 +87,52 @@ void menu_render(Menu *self) { menu_entry_render(it->data); item_y += self->item_h; } - + + self->size.height = item_y; self->invalid = FALSE; } + +void menu_entry_render(MenuEntry *self) +{ + Menu *menu = self->parent; + Appearance *a; + + switch (self->render_type) { + case MenuEntryRenderType_Submenu: + /* TODO: submenu mask */ + case MenuEntryRenderType_Boolean: + /* TODO: boolean check */ + a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item) + : self->a_disabled; + break; + case MenuEntryRenderType_None: + a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item ) + : self->a_disabled; + break; + case MenuEntryRenderType_Separator: + a = self->a_item; + break; + + default: + g_message("unhandled render_type"); + a = !self->enabled ? self->a_disabled : + (self->hilite && + (self->action || self->render_type == MenuEntryRenderType_Submenu) ? + self->a_hilite : self->a_item); + break; + } + + RECT_SET(a->area, 0, 0, menu->size.width, + menu->item_h); + RECT_SET(a->texture[0].position, menu->bullet_w, + 0, menu->size.width - 2 * menu->bullet_w, + menu->item_h); + + XMoveResizeWindow(ob_display, self->item, 0, self->y, + menu->size.width, menu->item_h); + a->surface.data.planar.parent = menu->a_items; + a->surface.data.planar.parentx = 0; + a->surface.data.planar.parenty = self->y; + + paint(self->item, a); +} diff --git a/openbox/plugin.c b/openbox/plugin.c index c3e21ec4..a5055de9 100644 --- a/openbox/plugin.c +++ b/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 @@ typedef struct { 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 @@ static Plugin *plugin_new(char *name) } 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 @@ void plugin_shutdown() 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 @@ gboolean plugin_open(char *name) 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 @@ void plugin_loadall() 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); +} diff --git a/openbox/plugin.h b/openbox/plugin.h index 8595fbac..733f564b 100644 --- a/openbox/plugin.h +++ b/openbox/plugin.h @@ -7,7 +7,15 @@ void plugin_shutdown(); 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 diff --git a/openbox/timer.c b/openbox/timer.c index b6a82cd3..e4591544 100644 --- a/openbox/timer.c +++ b/openbox/timer.c @@ -15,7 +15,7 @@ static long timecompare(GTimeVal *a, GTimeVal *b) 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 @@ void timer_dispatch(GTimeVal **wait) /* 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, diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 2ef58f15..37863dbe 100644 --- a/plugins/Makefile.am +++ b/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)\" diff --git a/plugins/menu/Makefile.in b/plugins/menu/Makefile.in new file mode 100644 index 00000000..ce9b31e7 --- /dev/null +++ b/plugins/menu/Makefile.in @@ -0,0 +1,475 @@ +# Makefile.in generated by automake 1.7.4 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../.. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BISON = @BISON@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ + +CPPFLAGS = $(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \ + -DG_LOG_DOMAIN=\"Plugin-Timed-Menu\" + +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FLEX = @FLEX@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VIDMODE_CFLAGS = @VIDMODE_CFLAGS@ +VIDMODE_LIBS = @VIDMODE_LIBS@ +XFT_CFLAGS = @XFT_CFLAGS@ +XFT_LIBS = @XFT_LIBS@ +XGETTEXT = @XGETTEXT@ +XINERAMA_LIBS = @XINERAMA_LIBS@ +XKB_CFLAGS = @XKB_CFLAGS@ +XKB_LIBS = @XKB_LIBS@ +XRANDR_CFLAGS = @XRANDR_CFLAGS@ +XRANDR_LIBS = @XRANDR_LIBS@ +XSHAPE_CFLAGS = @XSHAPE_CFLAGS@ +XSHAPE_LIBS = @XSHAPE_LIBS@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +plugindir = $(libdir)/openbox/plugins + +INCLUDES = -I../.. + +plugin_LTLIBRARIES = timed_menu.la + +timed_menu_la_LDFLAGS = -module -avoid-version +timed_menu_la_SOURCES = timed_menu.c + +noinst_HEADERS = timed_menu.h + +MAINTAINERCLEANFILES = Makefile.in +subdir = plugins/menu +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(plugin_LTLIBRARIES) + +timed_menu_la_LIBADD = +am_timed_menu_la_OBJECTS = timed_menu.lo +timed_menu_la_OBJECTS = $(am_timed_menu_la_OBJECTS) + +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/timed_menu.Plo +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ + $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(timed_menu_la_SOURCES) +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in +SOURCES = $(timed_menu_la_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign plugins/menu/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) +pluginLTLIBRARIES_INSTALL = $(INSTALL) +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(plugindir) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(plugindir)/$$f"; \ + $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(plugindir)/$$f; \ + else :; fi; \ + done + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + p="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(plugindir)/$$p"; \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(plugindir)/$$p; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" = "$$p" && dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +timed_menu.la: $(timed_menu_la_OBJECTS) $(timed_menu_la_DEPENDENCIES) + $(LINK) -rpath $(plugindir) $(timed_menu_la_LDFLAGS) $(timed_menu_la_OBJECTS) $(timed_menu_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timed_menu.Plo@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = ../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(plugindir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-local \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-pluginLTLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES ctags distclean \ + distclean-compile distclean-depend distclean-generic \ + distclean-libtool distclean-local distclean-tags distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-pluginLTLIBRARIES \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool pdf \ + pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am \ + uninstall-pluginLTLIBRARIES + + +distclean-local: + $(RM) *\~ *.orig *.rej .\#* +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plugins/menu/timed_menu.c b/plugins/menu/timed_menu.c new file mode 100644 index 00000000..2c264347 --- /dev/null +++ b/plugins/menu/timed_menu.c @@ -0,0 +1,73 @@ +#include "kernel/menu.h" +#include "kernel/timer.h" +#include "timed_menu.h" +#include "kernel/action.h" + +static char *PLUGIN_NAME = "timed_menu"; + +typedef enum { + TIMED_MENU_PIPE +} Timed_Menu_Type; + +/* we can use various GIO channels to support reading menus (can we add them to + the event loop? ) + stat() based update + exec() based read +*/ +typedef struct { + Timed_Menu_Type type; + Timer *timer; /* timer code handles free */ +} Timed_Menu_Data; + + +void plugin_setup_config() { } +void plugin_startup() +{ } +void plugin_shutdown() { } + +void timed_menu_timeout_handler(void *data) +{ + Action *a; + printf("woop timer %s\n", ((Menu *)data)->name); + ((Menu *)data)->invalid = TRUE; + + if (((Menu *)data)->shown) { + a = action_from_string("execute"); + a->data.execute.path = g_strdup("xeyes"); + menu_add_entry((Menu *)data, menu_entry_new("xeyes", a)); + + menu_show_full( (Menu *)data, ((Menu *)data)->location.x, + ((Menu *)data)->location.y, NULL); + } else { + GList *it; + + for (it = ((Menu *)data)->entries; it; it = it->next) { + MenuEntry *entry = it->data; + menu_entry_free(entry); + } + ((Menu *)data)->entries = NULL; + } +} + +void *plugin_create() +{ + Timed_Menu_Data *d = g_new(Timed_Menu_Data, 1); + Menu *m = menu_new("", PLUGIN_NAME, NULL); + + m->plugin = PLUGIN_NAME; + + d->type = TIMED_MENU_PIPE; + d->timer = timer_start(1000000, &timed_menu_timeout_handler, m); + + m->plugin_data = (void *)d; + + return (void *)m; +} + +void plugin_destroy (void *m) +{ + /* this will be freed by timer_* */ + timer_stop( ((Timed_Menu_Data *)((Menu *)m)->plugin_data)->timer); + + g_free( ((Menu *)m)->plugin_data ); +} diff --git a/plugins/menu/timed_menu.h b/plugins/menu/timed_menu.h new file mode 100644 index 00000000..a7d16c15 --- /dev/null +++ b/plugins/menu/timed_menu.h @@ -0,0 +1,4 @@ +#ifndef __TIMED_MENU_H +#define __TIMED_MENU_H + +#endif // __TIMED_MENU_H