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

This commit is contained in:
Dana Jansens 2007-05-07 23:26:22 +00:00
parent 31d7680274
commit 280529221e
6 changed files with 100 additions and 13 deletions

View file

@ -57,13 +57,14 @@
typedef struct typedef struct
{ {
ObClientDestructor func; ObClientCallback func;
gpointer data; 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_get_all(ObClient *self);
static void client_toggle_border(ObClient *self, gboolean show); 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->func = func;
d->data = data; d->data = data;
client_destructors = g_slist_prepend(client_destructors, d); client_destructors = g_slist_prepend(client_destructors, d);
} }
void client_remove_destructor(ObClientDestructor func) void client_remove_destructor(ObClientCallback func)
{ {
GSList *it; GSList *it;
for (it = client_destructors; it; it = g_slist_next(it)) { for (it = client_destructors; it; it = g_slist_next(it)) {
Destructor *d = it->data; ClientCallback *d = it->data;
if (d->func == func) { if (d->func == func) {
g_free(d); g_free(d);
client_destructors = g_slist_delete_link(client_destructors, it); 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() void client_set_list()
{ {
Window *windows, *win_it; Window *windows, *win_it;
@ -533,7 +557,7 @@ void client_unmanage(ObClient *self)
screen_update_areas(); screen_update_areas();
for (it = client_destructors; it; it = g_slist_next(it)) { for (it = client_destructors; it; it = g_slist_next(it)) {
Destructor *d = it->data; ClientCallback *d = it->data;
d->func(self, d->data); d->func(self, d->data);
} }
@ -3001,6 +3025,12 @@ void client_set_desktop_recursive(ObClient *self,
focus_order_to_top(self); focus_order_to_top(self);
else else
focus_order_to_bottom(self); 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 */ /* move all transients */

View file

@ -300,10 +300,17 @@ extern GList *client_list;
void client_startup(gboolean reconfig); void client_startup(gboolean reconfig);
void client_shutdown(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); /* Callback functions */
void client_remove_destructor(ObClientDestructor func);
/*! 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 */ /*! Manages all existing windows */
void client_manage_all(); void client_manage_all();

View file

@ -125,7 +125,7 @@ static gboolean send_to_update(ObMenuFrame *frame, gpointer data)
guint i; guint i;
GSList *acts; GSList *acts;
ObAction *act; ObAction *act;
ObMenuEntry *e;; ObMenuEntry *e;
menu_clear_entries(menu); menu_clear_entries(menu);
@ -169,6 +169,32 @@ static gboolean send_to_update(ObMenuFrame *frame, gpointer data)
return TRUE; /* show the 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, static void client_menu_place(ObMenuFrame *frame, gint *x, gint *y,
gint button, gpointer data) 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 = menu_new(SEND_TO_MENU_NAME, _("&Send to desktop"), TRUE, NULL);
menu_set_update_func(menu, send_to_update); 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); menu = menu_new(CLIENT_MENU_NAME, _("Client menu"), TRUE, NULL);

View file

@ -528,6 +528,16 @@ ObMenuEntry* menu_add_separator(ObMenu *self, gint id, const gchar *label)
return e; 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) void menu_set_update_func(ObMenu *self, ObMenuUpdateFunc func)
{ {
self->update_func = func; self->update_func = func;

View file

@ -37,6 +37,8 @@ typedef struct _ObNormalMenuEntry ObNormalMenuEntry;
typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry; typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry;
typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry; 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, typedef gboolean (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame,
gpointer data); gpointer data);
typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry, typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry,
@ -75,6 +77,8 @@ struct _ObMenu
/* plugin data */ /* plugin data */
gpointer data; gpointer data;
ObMenuShowFunc show_func;
ObMenuHideFunc hide_func;
ObMenuUpdateFunc update_func; ObMenuUpdateFunc update_func;
ObMenuExecuteFunc execute_func; ObMenuExecuteFunc execute_func;
ObMenuDestroyFunc destroy_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, void menu_show(gchar *name, gint x, gint y, gint button,
struct _ObClient *client); 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_update_func(ObMenu *menu, ObMenuUpdateFunc func);
void menu_set_execute_func(ObMenu *menu, ObMenuExecuteFunc func); void menu_set_execute_func(ObMenu *menu, ObMenuExecuteFunc func);
void menu_set_destroy_func(ObMenu *menu, ObMenuDestroyFunc func); void menu_set_destroy_func(ObMenu *menu, ObMenuDestroyFunc func);

View file

@ -924,6 +924,9 @@ static gboolean menu_frame_show(ObMenuFrame *self)
menu_frame_visible = g_list_prepend(menu_frame_visible, 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; return TRUE;
} }
@ -1006,6 +1009,9 @@ void menu_frame_hide(ObMenuFrame *self)
if (!it) if (!it)
return; return;
if (self->menu->hide_func)
self->menu->hide_func(self, self->menu->data);
if (self->child) if (self->child)
menu_frame_hide(self->child); menu_frame_hide(self->child);