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
{
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 */

View 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();

View 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);

View 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;

View 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);

View 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);