From 280529221e9349aa07c6c498df6b80b3a8951198 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 7 May 2007 23:26:22 +0000 Subject: [PATCH] add a notifier for clients changing desktops. use it to update the send-to menu if it changes. it does this by closing/opening the menu.. thats about the best we can do tho with this menu code without huge changes --- openbox/client.c | 48 +++++++++++++++++++++++++++++++++++-------- openbox/client.h | 13 +++++++++--- openbox/client_menu.c | 30 ++++++++++++++++++++++++++- openbox/menu.c | 10 +++++++++ openbox/menu.h | 6 ++++++ openbox/menuframe.c | 6 ++++++ 6 files changed, 100 insertions(+), 13 deletions(-) diff --git a/openbox/client.c b/openbox/client.c index 47bfcabc..0d74882c 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -57,13 +57,14 @@ typedef struct { - ObClientDestructor func; + ObClientCallback func; gpointer data; -} Destructor; +} ClientCallback; -GList *client_list = NULL; +GList *client_list = NULL; -static GSList *client_destructors = NULL; +static GSList *client_destructors = NULL; +static GSList *client_desktop_notifies = NULL; static void client_get_all(ObClient *self); static void client_toggle_border(ObClient *self, gboolean show); @@ -105,20 +106,20 @@ void client_shutdown(gboolean reconfig) { } -void client_add_destructor(ObClientDestructor func, gpointer data) +void client_add_destructor(ObClientCallback func, gpointer data) { - Destructor *d = g_new(Destructor, 1); + ClientCallback *d = g_new(ClientCallback, 1); d->func = func; d->data = data; client_destructors = g_slist_prepend(client_destructors, d); } -void client_remove_destructor(ObClientDestructor func) +void client_remove_destructor(ObClientCallback func) { GSList *it; for (it = client_destructors; it; it = g_slist_next(it)) { - Destructor *d = it->data; + ClientCallback *d = it->data; if (d->func == func) { g_free(d); client_destructors = g_slist_delete_link(client_destructors, it); @@ -127,6 +128,29 @@ void client_remove_destructor(ObClientDestructor func) } } +void client_add_desktop_notify(ObClientCallback func, gpointer data) +{ + ClientCallback *d = g_new(ClientCallback, 1); + d->func = func; + d->data = data; + client_desktop_notifies = g_slist_prepend(client_desktop_notifies, d); +} + +void client_remove_desktop_notify(ObClientCallback func) +{ + GSList *it; + + for (it = client_desktop_notifies; it; it = g_slist_next(it)) { + ClientCallback *d = it->data; + if (d->func == func) { + g_free(d); + client_desktop_notifies = + g_slist_delete_link(client_desktop_notifies, it); + break; + } + } +} + void client_set_list() { Window *windows, *win_it; @@ -533,7 +557,7 @@ void client_unmanage(ObClient *self) screen_update_areas(); for (it = client_destructors; it; it = g_slist_next(it)) { - Destructor *d = it->data; + ClientCallback *d = it->data; d->func(self, d->data); } @@ -3001,6 +3025,12 @@ void client_set_desktop_recursive(ObClient *self, focus_order_to_top(self); else focus_order_to_bottom(self); + + /* call the notifies */ + for (it = client_desktop_notifies; it; it = g_slist_next(it)) { + ClientCallback *d = it->data; + d->func(self, d->data); + } } /* move all transients */ diff --git a/openbox/client.h b/openbox/client.h index b046e665..d902f72a 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -300,10 +300,17 @@ extern GList *client_list; void client_startup(gboolean reconfig); void client_shutdown(gboolean reconfig); -typedef void (*ObClientDestructor)(ObClient *client, gpointer data); +typedef void (*ObClientCallback)(ObClient *client, gpointer data); -void client_add_destructor(ObClientDestructor func, gpointer data); -void client_remove_destructor(ObClientDestructor func); +/* Callback functions */ + +/*! Get notified when the client is unmanaged */ +void client_add_destructor(ObClientCallback func, gpointer data); +void client_remove_destructor(ObClientCallback func); + +/*! Get notified when the client changes desktop */ +void client_add_desktop_notify(ObClientCallback func, gpointer data); +void client_remove_desktop_notify(ObClientCallback func); /*! Manages all existing windows */ void client_manage_all(); diff --git a/openbox/client_menu.c b/openbox/client_menu.c index da6ac2d9..acb52530 100644 --- a/openbox/client_menu.c +++ b/openbox/client_menu.c @@ -125,7 +125,7 @@ static gboolean send_to_update(ObMenuFrame *frame, gpointer data) guint i; GSList *acts; ObAction *act; - ObMenuEntry *e;; + ObMenuEntry *e; menu_clear_entries(menu); @@ -169,6 +169,32 @@ static gboolean send_to_update(ObMenuFrame *frame, gpointer data) return TRUE; /* show the menu */ } +static void desktop_change_callback(ObClient *c, gpointer data) +{ + ObMenuFrame *frame = data; + if (c == frame->client) { + /* adding/removing entries while it's shown is not fun, so just hide + the menu and reshow it */ + if (frame->parent) { + ObMenuEntryFrame *me = frame->parent_entry; + ObMenuFrame *parent = frame->parent; + menu_frame_select(parent, NULL, TRUE); + menu_frame_select(parent, me, TRUE); + } else + menu_frame_hide(frame); + } +} + +static void show_callback(ObMenuFrame *frame, gpointer data) +{ + client_add_desktop_notify(desktop_change_callback, frame); +} + +static void hide_callback(ObMenuFrame *frame, gpointer data) +{ + client_remove_desktop_notify(desktop_change_callback); +} + static void client_menu_place(ObMenuFrame *frame, gint *x, gint *y, gint button, gpointer data) { @@ -259,6 +285,8 @@ void client_menu_startup() menu = menu_new(SEND_TO_MENU_NAME, _("&Send to desktop"), TRUE, NULL); menu_set_update_func(menu, send_to_update); + menu_set_show_func(menu, show_callback); + menu_set_hide_func(menu, hide_callback); menu = menu_new(CLIENT_MENU_NAME, _("Client menu"), TRUE, NULL); diff --git a/openbox/menu.c b/openbox/menu.c index 4782bad3..da9ba6b8 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -528,6 +528,16 @@ ObMenuEntry* menu_add_separator(ObMenu *self, gint id, const gchar *label) return e; } +void menu_set_show_func(ObMenu *self, ObMenuShowFunc func) +{ + self->show_func = func; +} + +void menu_set_hide_func(ObMenu *self, ObMenuHideFunc func) +{ + self->hide_func = func; +} + void menu_set_update_func(ObMenu *self, ObMenuUpdateFunc func) { self->update_func = func; diff --git a/openbox/menu.h b/openbox/menu.h index f66e423e..9fc84bb8 100644 --- a/openbox/menu.h +++ b/openbox/menu.h @@ -37,6 +37,8 @@ typedef struct _ObNormalMenuEntry ObNormalMenuEntry; typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry; typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry; +typedef void (*ObMenuShowFunc)(struct _ObMenuFrame *frame, gpointer data); +typedef void (*ObMenuHideFunc)(struct _ObMenuFrame *frame, gpointer data); typedef gboolean (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data); typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry, @@ -75,6 +77,8 @@ struct _ObMenu /* plugin data */ gpointer data; + ObMenuShowFunc show_func; + ObMenuHideFunc hide_func; ObMenuUpdateFunc update_func; ObMenuExecuteFunc execute_func; ObMenuDestroyFunc destroy_func; @@ -166,6 +170,8 @@ void menu_show_all_shortcuts(ObMenu *self, gboolean show); void menu_show(gchar *name, gint x, gint y, gint button, struct _ObClient *client); +void menu_set_show_func(ObMenu *menu, ObMenuShowFunc func); +void menu_set_hide_func(ObMenu *menu, ObMenuHideFunc func); void menu_set_update_func(ObMenu *menu, ObMenuUpdateFunc func); void menu_set_execute_func(ObMenu *menu, ObMenuExecuteFunc func); void menu_set_destroy_func(ObMenu *menu, ObMenuDestroyFunc func); diff --git a/openbox/menuframe.c b/openbox/menuframe.c index 476f3373..768176ab 100644 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@ -924,6 +924,9 @@ static gboolean menu_frame_show(ObMenuFrame *self) menu_frame_visible = g_list_prepend(menu_frame_visible, self); + if (self->menu->show_func) + self->menu->show_func(self, self->menu->data); + return TRUE; } @@ -1006,6 +1009,9 @@ void menu_frame_hide(ObMenuFrame *self) if (!it) return; + if (self->menu->hide_func) + self->menu->hide_func(self, self->menu->data); + if (self->child) menu_frame_hide(self->child); -- 2.39.2