# HG changeset patch # User Sadrul Habib Chowdhury # Date 1189142571 0 # Node ID ee5b3ac0d41d9cf008494a75398eedc7568be25a # Parent 25f4be036a164ddc0178ef4bfb1136fceb8965c2 "We are going to destroy the conversations immediately only if the 'close immediately' preference is selected. Otherwise, close the conversation after a reasonable timeout (I am going to consider 10 minutes as a 'reasonable timeout' here. For chats, close immediately if the chat is not in the buddylist, or if the chat is not marked 'Persistent'." diff -r 25f4be036a16 -r ee5b3ac0d41d pidgin/gtkblist.c --- a/pidgin/gtkblist.c Wed Sep 05 12:52:48 2007 +0000 +++ b/pidgin/gtkblist.c Fri Sep 07 05:22:51 2007 +0000 @@ -319,6 +319,12 @@ gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))); } +static void gtk_blist_menu_persistent_cb(GtkWidget *w, PurpleChat *chat) +{ + purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-persistent", + gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))); +} + static PurpleConversation * find_conversation_with_buddy(PurpleBuddy *buddy) { @@ -1274,16 +1280,19 @@ create_chat_menu(PurpleBlistNode *node, PurpleChat *c) { GtkWidget *menu; - gboolean autojoin; + gboolean autojoin, persistent; menu = gtk_menu_new(); autojoin = (purple_blist_node_get_bool(node, "gtk-autojoin") || (purple_blist_node_get_string(node, "gtk-autojoin") != NULL)); + persistent = purple_blist_node_get_bool(node, "gtk-persistent"); pidgin_new_item_from_stock(menu, _("_Join"), PIDGIN_STOCK_CHAT, G_CALLBACK(gtk_blist_menu_join_cb), node, 0, 0, NULL); pidgin_new_check_item(menu, _("Auto-Join"), G_CALLBACK(gtk_blist_menu_autojoin_cb), node, autojoin); + pidgin_new_check_item(menu, _("Persistent"), + G_CALLBACK(gtk_blist_menu_persistent_cb), node, persistent); pidgin_new_item_from_stock(menu, _("View _Log"), NULL, G_CALLBACK(gtk_blist_menu_showlog_cb), node, 0, 0, NULL); @@ -3688,7 +3697,7 @@ menu = NULL; } - convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM, PIDGIN_UNSEEN_TEXT, TRUE, 0); + convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_ANY, PIDGIN_UNSEEN_TEXT, TRUE, 0); if (!convs) /* no conversations added, don't show the menu */ return; @@ -3744,7 +3753,7 @@ gtkblist->menutrayicon = NULL; } - convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM, PIDGIN_UNSEEN_TEXT, TRUE, 0); + convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_ANY, PIDGIN_UNSEEN_TEXT, TRUE, 0); if (convs) { GtkWidget *img = NULL; GString *tooltip_text = NULL; @@ -3752,7 +3761,7 @@ tooltip_text = g_string_new(""); l = convs; while (l != NULL) { - int count = GPOINTER_TO_INT(purple_conversation_get_data(l->data, "unseen-count")) + 1; + int count = GPOINTER_TO_INT(purple_conversation_get_data(l->data, "unseen-count")); g_string_append_printf(tooltip_text, ngettext("%d unread message from %s\n", "%d unread messages from %s\n", count), count, purple_conversation_get_name(l->data)); @@ -3803,8 +3812,6 @@ ui->conv.flags |= PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE; ui->conv.last_message = time(NULL); /* XXX: for lack of better data */ pidgin_blist_update(purple_get_blist(), node); - purple_conversation_set_data(conv, "unseen-count", - GINT_TO_POINTER(GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")) + 1)); } static void @@ -3816,7 +3823,6 @@ return; ui->conv.flags &= ~PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE; pidgin_blist_update(purple_get_blist(), node); - purple_conversation_set_data(conv, "unseen-count", 0); } static void diff -r 25f4be036a16 -r ee5b3ac0d41d pidgin/gtkconv.c --- a/pidgin/gtkconv.c Wed Sep 05 12:52:48 2007 +0000 +++ b/pidgin/gtkconv.c Fri Sep 07 05:22:51 2007 +0000 @@ -69,6 +69,8 @@ #include "gtknickcolors.h" +#define CLOSE_CONV_TIMEOUT_SECS (10 * 60) + #define AUTO_RESPONSE "<AUTO-REPLY> : " typedef enum @@ -159,6 +161,7 @@ static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); static gboolean pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv); static void pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv); +static void hide_conv(PidginConversation *gtkconv, gboolean closetimer); static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y, int width, int height); @@ -187,12 +190,49 @@ **************************************************************************/ static gboolean -close_conv_cb(GtkWidget *w, GdkEventButton *event, PidginConversation *gtkconv) -{ +close_this_sucker(gpointer data) +{ + PidginConversation *gtkconv = data; GList *list = g_list_copy(gtkconv->convs); - g_list_foreach(list, (GFunc)purple_conversation_destroy, NULL); g_list_free(list); + return FALSE; +} + +static gboolean +close_conv_cb(GtkWidget *w, GdkEventButton *event, PidginConversation *gtkconv) +{ + /* We are going to destroy the conversations immediately only if the 'close immediately' + * preference is selected. Otherwise, close the conversation after a reasonable timeout + * (I am going to consider 10 minutes as a 'reasonable timeout' here. + * For chats, close immediately if the chat is not in the buddylist, or if the chat is + * not marked 'Persistent' */ + PurpleConversation *conv = gtkconv->active_conv; + PurpleAccount *account = purple_conversation_get_account(conv); + const char *name = purple_conversation_get_name(conv); + + switch (purple_conversation_get_type(conv)) { + case PURPLE_CONV_TYPE_IM: + { + if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/close_immediately")) + close_this_sucker(gtkconv); + else + hide_conv(gtkconv, TRUE); + break; + } + case PURPLE_CONV_TYPE_CHAT: + { + PurpleChat *chat = purple_blist_find_chat(account, name); + if (!chat || + !purple_blist_node_get_bool(&chat->node, "gtk-persistent")) + close_this_sucker(gtkconv); + else + hide_conv(gtkconv, FALSE); + break; + } + default: + ; + } return TRUE; } @@ -1300,15 +1340,32 @@ add_remove_cb(NULL, PIDGIN_CONVERSATION(conv)); } -static void -menu_hide_conv_cb(gpointer data, guint action, GtkWidget *widget) -{ - PidginWindow *win = data; - PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win); - PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); +static gboolean +close_already(gpointer data) +{ + purple_conversation_destroy(data); + return FALSE; +} + +static void +hide_conv(PidginConversation *gtkconv, gboolean closetimer) +{ + GList *list; + purple_signal_emit(pidgin_conversations_get_handle(), "conversation-hiding", gtkconv); - purple_conversation_set_ui_ops(conv, NULL); + + for (list = g_list_copy(gtkconv->convs); list; list = g_list_delete_link(list, list)) { + PurpleConversation *conv = list->data; + if (closetimer) { + guint timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer")); + if (timer) + purple_timeout_remove(timer); + timer = purple_timeout_add_seconds(CLOSE_CONV_TIMEOUT_SECS, close_already, conv); + purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(timer)); + } + purple_conversation_set_ui_ops(conv, NULL); + } } static void @@ -2772,7 +2829,8 @@ if (gtkconv != NULL && gtkconv->active_conv != conv) continue; if (gtkconv == NULL) { - if (!hidden_only) + if (!hidden_only || + !purple_conversation_get_data(conv, "unseen-count")) continue; r = g_list_prepend(r, conv); c++; @@ -2911,8 +2969,6 @@ { "/Conversation/sep4", NULL, NULL, 0, "", NULL }, - { N_("/Conversation/_Hide"), NULL, menu_hide_conv_cb, 0, - "", NULL}, { N_("/Conversation/_Close"), NULL, menu_close_conv_cb, 0, "", GTK_STOCK_CLOSE }, @@ -6552,6 +6608,17 @@ pidgin_conv_update_fields(conv, flags); } +static void +wrote_msg_update_unseen_cb(PurpleAccount *account, const char *who, const char *message, + PurpleConversation *conv, PurpleMessageFlags flag, gpointer null) +{ + if (conv == NULL || PIDGIN_IS_PIDGIN_CONVERSATION(conv)) + return; + purple_conversation_set_data(conv, "unseen-count", + GINT_TO_POINTER(GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")) + 1)); + purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN); +} + static PurpleConversationUiOps conversation_ui_ops = { pidgin_conv_new, @@ -7290,10 +7357,12 @@ { GList *list; PidginConversation *gtkconv; + int timer; if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) return FALSE; + purple_conversation_set_data(conv, "unseen-count", NULL); purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops()); private_gtkconv_new(conv, FALSE); gtkconv = PIDGIN_CONVERSATION(conv); @@ -7313,6 +7382,10 @@ pidgin_conv_chat_add_users(conv, PURPLE_CONV_CHAT(conv)->in_room, TRUE); } + timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer")); + if (timer) + purple_timeout_remove(timer); + return TRUE; } @@ -7378,6 +7451,7 @@ purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons", TRUE); purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new", "never"); + purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/im/close_immediately", FALSE); #ifdef _WIN32 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/win32/minimize_new_convs", FALSE); @@ -7576,6 +7650,10 @@ purple_signal_connect_priority(purple_conversations_get_handle(), "conversation-updated", handle, PURPLE_CALLBACK(pidgin_conv_updated), NULL, PURPLE_SIGNAL_PRIORITY_LOWEST); + purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", handle, + PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); + purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, + PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); } void diff -r 25f4be036a16 -r ee5b3ac0d41d pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Wed Sep 05 12:52:48 2007 +0000 +++ b/pidgin/gtkprefs.c Fri Sep 07 05:22:51 2007 +0000 @@ -993,6 +993,8 @@ pidgin_prefs_checkbox(_("Show _formatting on incoming messages"), PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting", vbox); + pidgin_prefs_checkbox(_("Close IMs immediately when the tab is closed"), + PIDGIN_PREFS_ROOT "/conversations/im/close_immediately", vbox); iconpref1 = pidgin_prefs_checkbox(_("Show _detailed information"), PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons", vbox);