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);
{
}
-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);
}
}
+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;
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);
}
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 */
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();
guint i;
GSList *acts;
ObAction *act;
- ObMenuEntry *e;;
+ ObMenuEntry *e;
menu_clear_entries(menu);
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)
{
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);
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;
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,
/* plugin data */
gpointer data;
+ ObMenuShowFunc show_func;
+ ObMenuHideFunc hide_func;
ObMenuUpdateFunc update_func;
ObMenuExecuteFunc execute_func;
ObMenuDestroyFunc destroy_func;
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);
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;
}
if (!it)
return;
+ if (self->menu->hide_func)
+ self->menu->hide_func(self, self->menu->data);
+
if (self->child)
menu_frame_hide(self->child);