Mercurial > pidgin.yaz
diff src/gtkblist.c @ 12016:24c7fb94d3a3
[gaim-migrate @ 14309]
Patch from charkins to fix potential problems with the buddy list becoming invisible with no way to restore visiblity. This (re)introduces the concept of a "visibility manager" that, if present, will be in charge of controlling the visibility of the buddy list.
committer: Tailor Script <tailor@pidgin.im>
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Wed, 09 Nov 2005 02:25:26 +0000 |
parents | 9ccbd9f8e8c6 |
children | e67993da8a22 |
line wrap: on
line diff
--- a/src/gtkblist.c Wed Nov 09 01:36:28 2005 +0000 +++ b/src/gtkblist.c Wed Nov 09 02:25:26 2005 +0000 @@ -101,6 +101,9 @@ static GtkWidget *protomenu = NULL; +static guint visibility_manager_count = 0; +static gboolean gtk_blist_obscured = FALSE; + static GList *gaim_gtk_blist_sort_methods = NULL; static struct gaim_gtk_blist_sort_method *current_sort_method = NULL; static GtkTreeIter sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); @@ -150,10 +153,42 @@ /*************************************************** * Callbacks * ***************************************************/ +static gboolean gtk_blist_visibility_cb(GtkWidget *w, GdkEventVisibility *event, gpointer data) +{ + if (event->state == GDK_VISIBILITY_FULLY_OBSCURED) + gtk_blist_obscured = TRUE; + else + gtk_blist_obscured = FALSE; + + /* continue to handle event normally */ + return FALSE; +} + +static gboolean gtk_blist_window_state_cb(GtkWidget *w, GdkEventWindowState *event, gpointer data) +{ + if(event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) { + if(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) + gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", FALSE); + else + gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", TRUE); + } + + if(event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) { + if(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) + gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", FALSE); + else + gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", TRUE); + } + + return FALSE; +} static gboolean gtk_blist_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data) { - gaim_core_quit(); + if(visibility_manager_count) + gaim_blist_set_visible(FALSE); + else + gaim_core_quit(); /* we handle everything, event should not propogate further */ return TRUE; @@ -3218,8 +3253,7 @@ {"application/x-im-contact", 0, DRAG_BUDDY}, {"text/x-vcard", 0, DRAG_VCARD }}; if (gtkblist && gtkblist->window) { - if (gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")) - gtk_widget_show(gtkblist->window); + gaim_blist_set_visible(gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")); return; } @@ -3233,8 +3267,10 @@ gtk_widget_show(gtkblist->vbox); gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); - g_signal_connect_after(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gtk_blist_delete_cb), NULL); + g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gtk_blist_delete_cb), NULL); g_signal_connect(G_OBJECT(gtkblist->window), "configure_event", G_CALLBACK(gtk_blist_configure_cb), NULL); + g_signal_connect(G_OBJECT(gtkblist->window), "visibility_notify_event", G_CALLBACK(gtk_blist_visibility_cb), NULL); + g_signal_connect(G_OBJECT(gtkblist->window), "window_state_event", G_CALLBACK(gtk_blist_window_state_cb), NULL); gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK); /******************************* Menu bar *************************************/ @@ -3400,11 +3436,8 @@ gaim_gtk_blist_update_sort_methods(); /* OK... let's show this bad boy. */ - if (gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")) { - gaim_gtk_blist_refresh(list); - gaim_gtk_blist_restore_position(); - gtk_widget_show(gtkblist->window); - } + gaim_gtk_blist_refresh(list); + gaim_blist_set_visible(gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")); /* start the refresh timer */ gtkblist->refresh_timer = g_timeout_add(30000, (GSourceFunc)gaim_gtk_blist_refresh_timer, list); @@ -3943,13 +3976,20 @@ if (!(gtkblist && gtkblist->window)) return; - gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", show); + //gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", show); if (show) { + if(!GAIM_WINDOW_ICONIFIED(gtkblist->window) && !GTK_WIDGET_VISIBLE(gtkblist->window)) + gaim_signal_emit(gaim_gtk_blist_get_handle(), "gtkblist-unhiding", gtkblist); gaim_gtk_blist_restore_position(); gtk_window_present(GTK_WINDOW(gtkblist->window)); } else { - gtk_window_iconify(GTK_WINDOW(gtkblist->window)); + if(visibility_manager_count) { + gaim_signal_emit(gaim_gtk_blist_get_handle(), "gtkblist-hiding", gtkblist); + gtk_widget_hide(gtkblist->window); + } else { + gtk_window_iconify(GTK_WINDOW(gtkblist->window)); + } } } @@ -4569,6 +4609,34 @@ _("Cancel"), NULL, NULL); } +void +gaim_gtk_blist_toggle_visibility() +{ + if (gtkblist && gtkblist->window) { + if (GTK_WIDGET_VISIBLE(gtkblist->window)) { + gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gtk_blist_obscured); + } else { + gaim_blist_set_visible(TRUE); + } + } +} + +void +gaim_gtk_blist_visibility_manager_add() +{ + visibility_manager_count++; +} + +void +gaim_gtk_blist_visibility_manager_remove() +{ + if (visibility_manager_count) + visibility_manager_count--; + if (!visibility_manager_count) + gaim_blist_set_visible(TRUE); +} + + static GaimBlistUiOps blist_ui_ops = { gaim_gtk_blist_new_list, @@ -4691,6 +4759,14 @@ gaim_prefs_add_int("/gaim/gtk/blist/tooltip_delay", 500); /* Register our signals */ + gaim_signal_register(gtk_blist_handle, "gtkblist-hiding", + gaim_marshal_VOID__POINTER, NULL, 1, + gaim_value_new(GAIM_TYPE_POINTER)); + + gaim_signal_register(gtk_blist_handle, "gtkblist-unhiding", + gaim_marshal_VOID__POINTER, NULL, 1, + gaim_value_new(GAIM_TYPE_SUBTYPE)); + gaim_signal_register(gtk_blist_handle, "gtkblist-created", gaim_marshal_VOID__POINTER, NULL, 1, gaim_value_new(GAIM_TYPE_SUBTYPE,