all repos — openbox @ 280529221e9349aa07c6c498df6b80b3a8951198

openbox fork - make it a bit more like ryudo

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
Dana Jansens danakj@orodu.net
commit

280529221e9349aa07c6c498df6b80b3a8951198

parent

31d7680274cdf2fa3c45b8c8d56db2b5d8fbc111

6 files changed, 100 insertions(+), 13 deletions(-)

jump to
M openbox/client.copenbox/client.c

@@ -57,13 +57,14 @@ ButtonMotionMask)

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,23 +106,46 @@ 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); + break; + } + } +} + +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; } }

@@ -533,7 +557,7 @@ if (STRUT_EXISTS(self->strut))

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 @@ if (config_focus_new)

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 */
M openbox/client.hopenbox/client.h

@@ -300,10 +300,17 @@

void client_startup(gboolean reconfig); void client_shutdown(gboolean reconfig); -typedef void (*ObClientDestructor)(ObClient *client, gpointer data); +typedef void (*ObClientCallback)(ObClient *client, gpointer data); + +/* Callback functions */ + +/*! Get notified when the client is unmanaged */ +void client_add_destructor(ObClientCallback func, gpointer data); +void client_remove_destructor(ObClientCallback func); -void client_add_destructor(ObClientDestructor func, gpointer data); -void client_remove_destructor(ObClientDestructor 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();
M openbox/client_menu.copenbox/client_menu.c

@@ -125,7 +125,7 @@ ObMenu *menu = frame->menu;

guint i; GSList *acts; ObAction *act; - ObMenuEntry *e;; + ObMenuEntry *e; menu_clear_entries(menu);

@@ -167,6 +167,32 @@ if (frame->client->desktop == desk)

e->data.normal.enabled = FALSE; } 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,

@@ -259,6 +285,8 @@

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);
M openbox/menu.copenbox/menu.c

@@ -528,6 +528,16 @@ self->more_menu->entries = self->entries; /* keep it in sync */

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;
M openbox/menu.hopenbox/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 @@

/* 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(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);
M openbox/menuframe.copenbox/menuframe.c

@@ -924,6 +924,9 @@ menu_frame_update(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; }

@@ -1005,6 +1008,9 @@ GList *it = g_list_find(menu_frame_visible, 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);