]> Dogcows Code - chaz/openbox/commitdiff
add a notifier for clients changing desktops. use it to update the send-to menu if...
authorDana Jansens <danakj@orodu.net>
Mon, 7 May 2007 23:26:22 +0000 (23:26 +0000)
committerDana Jansens <danakj@orodu.net>
Mon, 7 May 2007 23:26:22 +0000 (23:26 +0000)
openbox/client.c
openbox/client.h
openbox/client_menu.c
openbox/menu.c
openbox/menu.h
openbox/menuframe.c

index 47bfcabcb5ff6a547f2e7287fe124d47ca68ec5c..0d74882ce87abf53cee7df2157d4f455d21665df 100644 (file)
 
 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 */
index b046e665d9314d553a30b23e75b336092695c901..d902f72a5d1ee8bc34f8097bac4fcf5fd8545035 100644 (file)
@@ -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();
index da6ac2d9994ae9a81ae117c4161a3e66688be816..acb525300ad181f436817e648eebf33919fb00d0 100644 (file)
@@ -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);
index 4782bad35d44b1d6de80b81398f781a52f9a1cb2..da9ba6b851aa2889eaf0b9b92308811b123284bd 100644 (file)
@@ -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;
index f66e423e9ce0ac3a3360f59fffb1baf1f45a6e1a..9fc84bb8706f3916d97dc7ddbd93e53bdc7cb8d7 100644 (file)
@@ -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);
index 476f33733bce6130f0161161276ceda1470e68a1..768176abcb218cae14fa026f4cce42675b3e197f 100644 (file)
@@ -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);
 
This page took 0.03552 seconds and 4 git commands to generate.