Mercurial > pidgin
diff src/gtkconv.c @ 12288:3897229ccb33
[gaim-migrate @ 14592]
" This patch fixes two serious bugs in the hidden
conversation/queuing code.
First, it removes the need to explicitly present
conversations created under queuing conditions.
Instead, when an incoming message is received and a
conversation does not exist, a hidden conversation is
created in a received-im-msg signal handler by swapping
out the create_conversation function in the gtkconv
ui_ops. This fixes a bug which could allow
conversations to be created in a hidden state when they
should be visible (i.e. buddy pounce open an im window
action). This required a second search for a
conversation in server.c after the signal is emitted.
Second, it fixes a bug which would cause gaim to crash
when quitting with a queued message. Fixing this
simplified the code a bit by removing the
private_remove_gtkconv function and instead adding a
check in gaim_gtk_conv_window_remove_gtkconv to prevent
the hidden_convwin from being destroyed when the last
conversation is removed." --charkins
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Fri, 02 Dec 2005 00:40:32 +0000 |
parents | 255e6912607b |
children | a532eccfc7bb |
line wrap: on
line diff
--- a/src/gtkconv.c Thu Dec 01 21:22:55 2005 +0000 +++ b/src/gtkconv.c Fri Dec 02 00:40:32 2005 +0000 @@ -133,8 +133,6 @@ static void update_typing_icon(GaimGtkConversation *gtkconv); static char *item_factory_translate_func (const char *path, gpointer func_data); gboolean gaim_gtkconv_has_focus(GaimConversation *conv); -static void private_remove_gtkconv(GaimGtkWindow *win, GaimGtkConversation *gtkconv, - gboolean destroy_empty); static GdkColor *get_nick_color(GaimGtkConversation *gtkconv, const char *name) { static GdkColor col; @@ -2389,7 +2387,7 @@ GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv); if(gtkconv->win==hidden_convwin) { - private_remove_gtkconv(hidden_convwin, gtkconv, FALSE); + gaim_gtk_conv_window_remove_gtkconv(hidden_convwin, gtkconv); gaim_gtkconv_placement_place(gtkconv); } @@ -3954,8 +3952,8 @@ /************************************************************************** * Conversation UI operations **************************************************************************/ -void -gaim_gtkconv_new(GaimConversation *conv) +static void +private_gtkconv_new(GaimConversation *conv, gboolean hidden) { GaimGtkConversation *gtkconv; GaimConversationType conv_type = gaim_conversation_get_type(conv); @@ -4053,24 +4051,50 @@ G_CALLBACK(gtk_widget_grab_focus), gtkconv->entry); - if (conv_type == GAIM_CONV_TYPE_IM) { - /* put conv in hidden_convwin if hide_new pref is always */ - if(strcmp(gaim_prefs_get_string("/gaim/gtk/conversations/im/hide_new"), "always")==0) { - gaim_gtk_conv_window_add_gtkconv(hidden_convwin, gtkconv); - return; - } - - /* put conv in hidden_convwin if hide_new pref is away and account is away */ - if(strcmp(gaim_prefs_get_string("/gaim/gtk/conversations/im/hide_new"), "away")==0 - && gaim_status_type_get_primitive( - gaim_status_get_type(gaim_account_get_active_status( - gaim_conversation_get_account(conv)))) == GAIM_STATUS_AWAY) { - gaim_gtk_conv_window_add_gtkconv(hidden_convwin, gtkconv); - return; - } - } - - gaim_gtkconv_placement_place(gtkconv); + if (hidden) + gaim_gtk_conv_window_add_gtkconv(hidden_convwin, gtkconv); + else + gaim_gtkconv_placement_place(gtkconv); +} + +static void +gaim_gtkconv_new_hidden(GaimConversation *conv) +{ + private_gtkconv_new(conv, TRUE); +} + +void +gaim_gtkconv_new(GaimConversation *conv) +{ + private_gtkconv_new(conv, FALSE); +} + +static void +received_im_msg_cb(GaimAccount *account, char *sender, char *message, + GaimConversation *conv, int flags) +{ + GaimConversationUiOps *ui_ops = gaim_gtk_conversations_get_conv_ui_ops(); + if(conv) + return; + + /* create hidden conv if hide_new pref is always */ + if(strcmp(gaim_prefs_get_string("/gaim/gtk/conversations/im/hide_new"), "always")==0) { + ui_ops->create_conversation = gaim_gtkconv_new_hidden; + gaim_conversation_new(GAIM_CONV_TYPE_IM, account, sender); + ui_ops->create_conversation = gaim_gtkconv_new; + return; + } + + /* create hidden conv if hide_new pref is away and account is away */ + if(strcmp(gaim_prefs_get_string("/gaim/gtk/conversations/im/hide_new"), "away")==0 + && gaim_status_type_get_primitive( + gaim_status_get_type( + gaim_account_get_active_status(account))) == GAIM_STATUS_AWAY) { + ui_ops->create_conversation = gaim_gtkconv_new_hidden; + gaim_conversation_new(GAIM_CONV_TYPE_IM, account, sender); + ui_ops->create_conversation = gaim_gtkconv_new; + return; + } } static void @@ -5703,7 +5727,7 @@ gaim_conversation_get_account(conv)))) == GAIM_STATUS_AWAY) continue; - private_remove_gtkconv(hidden_convwin, gtkconv, FALSE); + gaim_gtk_conv_window_remove_gtkconv(hidden_convwin, gtkconv); gaim_gtkconv_placement_place(gtkconv); } } @@ -5736,7 +5760,7 @@ gaim_conversation_get_account(conv)))) == GAIM_STATUS_AWAY) continue; - private_remove_gtkconv(hidden_convwin, gtkconv, FALSE); + gaim_gtk_conv_window_remove_gtkconv(hidden_convwin, gtkconv); gaim_gtkconv_placement_place(gtkconv); } } @@ -5916,6 +5940,9 @@ gaim_signal_connect(blist_handle, "buddy-removed", handle, G_CALLBACK(buddy_update_cb), NULL); + gaim_signal_connect(gaim_conversations_get_handle(), "received-im-msg", + handle, G_CALLBACK(received_im_msg_cb), NULL); + gaim_conversations_set_ui_ops(&conversation_ui_ops); hidden_convwin = gaim_gtk_conv_window_new(); @@ -6948,8 +6975,8 @@ update_send_to_selection(win); } -static void -private_remove_gtkconv(GaimGtkWindow *win, GaimGtkConversation *gtkconv, gboolean destroy_empty) +void +gaim_gtk_conv_window_remove_gtkconv(GaimGtkWindow *win, GaimGtkConversation *gtkconv) { unsigned int index; GaimConversationType conv_type; @@ -6970,14 +6997,9 @@ win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv); - if (destroy_empty && !win->gtkconvs) + if (!win->gtkconvs && win != hidden_convwin) gaim_gtk_conv_window_destroy(win); } -void -gaim_gtk_conv_window_remove_gtkconv(GaimGtkWindow *win, GaimGtkConversation *gtkconv) -{ - private_remove_gtkconv(win, gtkconv, TRUE); -} GaimGtkConversation * gaim_gtk_conv_window_get_gtkconv_at_index(const GaimGtkWindow *win, int index)