From 03d42b5d8253ad2de94df20b12b9fb22ce51eb3d Mon Sep 17 00:00:00 2001 From: Scott Moynes Date: Sat, 10 May 2003 14:51:27 +0000 Subject: [PATCH] Timed menu that reads output from a process while the window is hidden --- openbox/menu.c | 15 +++++++-- openbox/menu.h | 2 ++ plugins/menu/timed_menu.c | 69 +++++++++++++++++++++++++++++---------- 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/openbox/menu.c b/openbox/menu.c index b271cf31..74c23482 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -90,11 +90,11 @@ void menu_startup() 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));*/ + menu_add_entry(t, menu_entry_new("xeyes", a)); + menu_add_entry(m, menu_entry_new_submenu("timed", t)); s = menu_new("empty", "chub", m); menu_add_entry(m, menu_entry_new_submenu("empty", s)); @@ -293,6 +293,17 @@ void menu_hide(Menu *self) { } } +void menu_clear(Menu *self) { + GList *it; + + for (it = self->entries; it; it = it->next) { + MenuEntry *entry = it->data; + menu_entry_free(entry); + } + self->entries = NULL; +} + + MenuEntry *menu_find_entry(Menu *menu, Window win) { GList *it; diff --git a/openbox/menu.h b/openbox/menu.h index 081b3528..43ac054f 100644 --- a/openbox/menu.h +++ b/openbox/menu.h @@ -104,6 +104,8 @@ void menu_show_full(Menu *menu, int x, int y, Client *client); void menu_hide(Menu *self); +void menu_clear(Menu *self); + MenuEntry *menu_entry_new_full(char *label, Action *action, MenuEntryRenderType render_type, gpointer submenu); diff --git a/plugins/menu/timed_menu.c b/plugins/menu/timed_menu.c index 2c264347..34d71e73 100644 --- a/plugins/menu/timed_menu.c +++ b/plugins/menu/timed_menu.c @@ -1,8 +1,12 @@ +#include + #include "kernel/menu.h" #include "kernel/timer.h" #include "timed_menu.h" #include "kernel/action.h" +#define TIMED_MENU(m) ((Menu *)m) +#define TIMED_MENU_DATA(m) ((Timed_Menu_Data *)((Menu *)m)->plugin_data) static char *PLUGIN_NAME = "timed_menu"; typedef enum { @@ -17,6 +21,7 @@ typedef enum { typedef struct { Timed_Menu_Type type; Timer *timer; /* timer code handles free */ + char *command; /* for the PIPE */ } Timed_Menu_Data; @@ -28,24 +33,54 @@ 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; + if (!TIMED_MENU(data)->shown) { + switch (TIMED_MENU_DATA(data)->type) { + case (TIMED_MENU_PIPE): + { + /* if the menu is not shown, run a process and use its output + as menu */ + char *args[] = {"/bin/sh", "-c", "ls", NULL}; + GIOChannel *io; + char *line; + gint child, c_stdout, line_len, terminator_pos; + GIOStatus status; + /* this blocks for now, until the event stuff can handle it */ + if (!g_spawn_async_with_pipes(NULL, + args, + NULL, + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, + &child, NULL, &c_stdout, NULL, + NULL)) { + g_warning("%s: Unable to run timed_menu program", + __FUNCTION__); + break; + } + + io = g_io_channel_unix_new(c_stdout); + if (io == NULL) { + g_error("%s: Unable to get IO channel", __FUNCTION__); + break; + } - for (it = ((Menu *)data)->entries; it; it = it->next) { - MenuEntry *entry = it->data; - menu_entry_free(entry); - } - ((Menu *)data)->entries = NULL; + menu_clear(TIMED_MENU(data)); + + while ( G_IO_STATUS_NORMAL == (status = + g_io_channel_read_line + (io, &line, &line_len, &terminator_pos, NULL)) + ) { + /* the \n looks ugly */ + line[terminator_pos] = '\0'; + menu_add_entry(TIMED_MENU(data), + menu_entry_new_separator(line)); + g_message("%s", line); + g_free(line); + } + break; + } + } } } @@ -67,7 +102,7 @@ void *plugin_create() void plugin_destroy (void *m) { /* this will be freed by timer_* */ - timer_stop( ((Timed_Menu_Data *)((Menu *)m)->plugin_data)->timer); + timer_stop( ((Timed_Menu_Data *)TIMED_MENU(m)->plugin_data)->timer); - g_free( ((Menu *)m)->plugin_data ); + g_free( TIMED_MENU(m)->plugin_data ); } -- 2.39.2