# HG changeset patch # User Ka-Hing Cheung # Date 1179614931 0 # Node ID dc042f70bd8c03fdf932f9fa45400d87c0c7e587 # Parent 4c5d68e93ef8e02a3dc31651775b426de3fd5e1d# Parent 6f3432091d4bcdaa06c5cf0d287c009f80a40cb4 merge of '04f3de66fbed599e51f30258916fdb8f966ffdcd' and 'b92b51d5aa18a5df8e4de6cfd0c4710845197b51' diff -r 4c5d68e93ef8 -r dc042f70bd8c COPYRIGHT --- a/COPYRIGHT Sat May 19 22:48:25 2007 +0000 +++ b/COPYRIGHT Sat May 19 22:48:51 2007 +0000 @@ -304,6 +304,7 @@ David Schmitt Mark Schneider Evan Schoenberg +Gabriel Schulof Federico Schwindt Torrey Searle Peter Seebach @@ -360,6 +361,7 @@ James Vega David Vermeille Sid Vicious +Jorge VillaseƱor (Masca) Bjoern Voigt Wan Hing Wah Philip Walford diff -r 4c5d68e93ef8 -r dc042f70bd8c ChangeLog --- a/ChangeLog Sat May 19 22:48:25 2007 +0000 +++ b/ChangeLog Sat May 19 22:48:51 2007 +0000 @@ -35,6 +35,10 @@ * Improved tab completion support * Ctrl+c prompts with a dialog before exiting * Filter string in the debug window + * Notify when you leave a chat + * Work around an ncurses bug which appears when half of a multi-cell + character is covered by an upper-level window + * New plugins are shown in bold text in the plugin dialog version 2.0.0 (5/3/2007): * The project has new names - libpurple for the core, Pidgin for the diff -r 4c5d68e93ef8 -r dc042f70bd8c finch/gntconv.c --- a/finch/gntconv.c Sat May 19 22:48:25 2007 +0000 +++ b/finch/gntconv.c Sat May 19 22:48:51 2007 +0000 @@ -493,7 +493,8 @@ FinchConvChat *fc = ggc->u.chat = g_new0(FinchConvChat, 1); hbox = gnt_hbox_new(FALSE); gnt_box_set_pad(GNT_BOX(hbox), 0); - tree = fc->userlist = gnt_tree_new(); + tree = fc->userlist = gnt_tree_new_with_columns(2); + gnt_tree_set_col_width(GNT_TREE(tree), 0, 1); /* The flag column */ gnt_tree_set_compare_func(GNT_TREE(tree), (GCompareFunc)g_utf8_collate); gnt_tree_set_hash_fns(GNT_TREE(tree), g_str_hash, g_str_equal, g_free); GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER); @@ -675,6 +676,20 @@ finch_write_common(conv, name, message, flags, mtime); } +static const char * +chat_flag_text(PurpleConvChatBuddyFlags flags) +{ + if (flags & PURPLE_CBFLAGS_FOUNDER) + return "~"; + if (flags & PURPLE_CBFLAGS_OP) + return "@"; + if (flags & PURPLE_CBFLAGS_HALFOP) + return "%"; + if (flags & PURPLE_CBFLAGS_VOICE) + return "+"; + return " "; +} + static void finch_chat_add_users(PurpleConversation *conv, GList *users, gboolean new_arrivals) { @@ -709,7 +724,7 @@ gnt_entry_add_suggest(entry, cbuddy->name); gnt_entry_add_suggest(entry, cbuddy->alias); gnt_tree_add_row_after(tree, g_strdup(cbuddy->name), - gnt_tree_create_row(tree, cbuddy->alias), NULL, NULL); + gnt_tree_create_row(tree, chat_flag_text(cbuddy->flags), cbuddy->alias), NULL, NULL); } } @@ -720,12 +735,15 @@ FinchConv *ggc = conv->ui_data; GntEntry *entry = GNT_ENTRY(ggc->entry); GntTree *tree = GNT_TREE(ggc->u.chat->userlist); + PurpleConvChatBuddy *cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), new_n); + gnt_entry_remove_suggest(entry, old); + gnt_tree_remove(tree, (gpointer)old); + gnt_entry_add_suggest(entry, new_n); gnt_entry_add_suggest(entry, new_a); - gnt_tree_remove(tree, (gpointer)old); gnt_tree_add_row_after(tree, g_strdup(new_n), - gnt_tree_create_row(tree, new_a), NULL, NULL); + gnt_tree_create_row(tree, chat_flag_text(cb->flags), new_a), NULL, NULL); } static void @@ -744,6 +762,9 @@ static void finch_chat_update_user(PurpleConversation *conv, const char *user) { + PurpleConvChatBuddy *cb = purple_conv_chat_cb_find(PURPLE_CONV_CHAT(conv), user); + FinchConv *ggc = conv->ui_data; + gnt_tree_change_text(GNT_TREE(ggc->u.chat->userlist), (gpointer)user, 0, chat_flag_text(cb->flags)); } static PurpleConversationUiOps conv_ui_ops = diff -r 4c5d68e93ef8 -r dc042f70bd8c libpurple/Makefile.am --- a/libpurple/Makefile.am Sat May 19 22:48:25 2007 +0000 +++ b/libpurple/Makefile.am Sat May 19 22:48:51 2007 +0000 @@ -151,7 +151,7 @@ dbus_headers = dbus-bindings.h dbus-purple.h dbus-server.h dbus-useful.h dbus-define-api.h dbus_exported = dbus-useful.h dbus-define-api.h account.h blist.h buddyicon.h \ - connection.h conversation.h core.h log.h prefs.h roomlist.h \ + connection.h conversation.h core.h log.h notify.h prefs.h roomlist.h \ savedstatuses.h status.h server.h util.h xmlnode.h purple_build_coreheaders = $(addprefix $(srcdir)/, $(purple_coreheaders)) diff -r 4c5d68e93ef8 -r dc042f70bd8c libpurple/conversation.c --- a/libpurple/conversation.c Sat May 19 22:48:25 2007 +0000 +++ b/libpurple/conversation.c Sat May 19 22:48:51 2007 +0000 @@ -970,20 +970,20 @@ { im->typing_state = state; - if (state == PURPLE_TYPING) - { - purple_signal_emit(purple_conversations_get_handle(), - "buddy-typing", im->conv->account, im->conv->name); - } - else if (state == PURPLE_TYPED) + switch (state) { - purple_signal_emit(purple_conversations_get_handle(), - "buddy-typed", im->conv->account, im->conv->name); - } - else if (state == PURPLE_NOT_TYPING) - { - purple_signal_emit(purple_conversations_get_handle(), - "buddy-typing-stopped", im->conv->account, im->conv->name); + case PURPLE_TYPING: + purple_signal_emit(purple_conversations_get_handle(), + "buddy-typing", im->conv->account, im->conv->name); + break; + case PURPLE_TYPED: + purple_signal_emit(purple_conversations_get_handle(), + "buddy-typed", im->conv->account, im->conv->name); + break; + case PURPLE_NOT_TYPING: + purple_signal_emit(purple_conversations_get_handle(), + "buddy-typing-stopped", im->conv->account, im->conv->name); + break; } } } diff -r 4c5d68e93ef8 -r dc042f70bd8c libpurple/dbus-analyze-functions.py --- a/libpurple/dbus-analyze-functions.py Sat May 19 22:48:25 2007 +0000 +++ b/libpurple/dbus-analyze-functions.py Sat May 19 22:48:51 2007 +0000 @@ -96,7 +96,7 @@ if len(type) == 1: # simple types (int, gboolean, etc.) and enums - if (type[0] in simpletypes) or (type[0].startswith("Purple")): + if (type[0] in simpletypes) or ((type[0].startswith("Purple") and not type[0].endswith("Callback"))): return self.inputsimple(type, name) # pointers ... @@ -118,7 +118,6 @@ # unknown pointers are always replaced with NULL else: return self.inputpointer(type, name) - return raise myexception diff -r 4c5d68e93ef8 -r dc042f70bd8c libpurple/idle.c --- a/libpurple/idle.c Sat May 19 22:48:25 2007 +0000 +++ b/libpurple/idle.c Sat May 19 22:48:51 2007 +0000 @@ -31,7 +31,6 @@ #include "signals.h" #define IDLEMARK 600 /* 10 minutes! */ -#define IDLE_CHECK_INTERVAL 5 /* 5 seconds */ typedef enum { @@ -92,6 +91,8 @@ purple_presence_set_idle(presence, FALSE, 0); } + +static gint time_until_next_idle_event; /* * This function should be called when you think your idle state * may have changed. Maybe you're over the 10-minute mark and @@ -110,14 +111,17 @@ * 2. Set or unset your auto-away message. * 3. Report your current idle time to the IM server. */ -static gint -check_idleness() + +static void +check_idleness(void) { time_t time_idle; gboolean auto_away; const gchar *idle_reporting; gboolean report_idle; GList *l; + gint away_seconds = 0; + static int no_away = 0; purple_signal_emit(purple_blist_get_handle(), "update-idle"); @@ -153,14 +157,24 @@ time_idle = time(NULL) - last_active_time; } - if (auto_away && - (time_idle > (60 * purple_prefs_get_int("/purple/away/mins_before_away")))) + time_until_next_idle_event = IDLEMARK - time_idle; /* reasonable start upperbound */ + + if (auto_away || !no_away) + away_seconds = 60 * purple_prefs_get_int("/purple/away/mins_before_away"); + + if (auto_away && time_idle > away_seconds) { purple_savedstatus_set_idleaway(TRUE); + no_away = 0; + if (time_idle < away_seconds && (away_seconds - time_idle) < time_until_next_idle_event) + time_until_next_idle_event = away_seconds - time_idle; } - else if (time_idle < 60 * purple_prefs_get_int("/purple/away/mins_before_away")) + else if (!no_away && time_idle < away_seconds) { purple_savedstatus_set_idleaway(FALSE); + no_away = 1; + if (time_idle < away_seconds && (away_seconds - time_idle) < time_until_next_idle_event) + time_until_next_idle_event = away_seconds - time_idle; } /* Idle reporting stuff */ @@ -177,8 +191,21 @@ while (idled_accts != NULL) set_account_unidle(idled_accts->data); } + + if (time_until_next_idle_event < 0) + time_until_next_idle_event = IDLEMARK; +} - return TRUE; + +/* + * Check idle and set the timer to fire at the next idle-worth event + */ +static gint +check_idleness_timer() +{ + check_idleness(); + idle_timer = purple_timeout_add(1000 * (time_until_next_idle_event + 1), check_idleness_timer, NULL); + return FALSE; } static void @@ -241,7 +268,7 @@ purple_idle_init() { /* Add the timer to check if we're idle */ - idle_timer = purple_timeout_add(IDLE_CHECK_INTERVAL * 1000, check_idleness, NULL); + idle_timer = purple_timeout_add(1000 * (IDLEMARK + 1), check_idleness_timer, NULL); purple_signal_connect(purple_conversations_get_handle(), "sent-im-msg", purple_idle_get_handle(), diff -r 4c5d68e93ef8 -r dc042f70bd8c libpurple/notify.c --- a/libpurple/notify.c Sat May 19 22:48:25 2007 +0000 +++ b/libpurple/notify.c Sat May 19 22:48:51 2007 +0000 @@ -22,6 +22,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "internal.h" +#include "dbus-maybe.h" #include "notify.h" static PurpleNotifyUiOps *notify_ui_ops = NULL; @@ -481,6 +483,7 @@ PurpleNotifyUserInfoEntry *user_info_entry; user_info_entry = g_new0(PurpleNotifyUserInfoEntry, 1); + PURPLE_DBUS_REGISTER_POINTER(user_info_entry, PurpleNotifyUserInfoEntry); user_info_entry->label = g_strdup(label); user_info_entry->value = g_strdup(value); user_info_entry->type = PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR; @@ -495,6 +498,7 @@ g_free(user_info_entry->label); g_free(user_info_entry->value); + PURPLE_DBUS_UNREGISTER_POINTER(user_info_entry); g_free(user_info_entry); } @@ -504,6 +508,7 @@ PurpleNotifyUserInfo *user_info; user_info = g_new0(PurpleNotifyUserInfo, 1); + PURPLE_DBUS_REGISTER_POINTER(user_info, PurpleNotifyUserInfo); user_info->user_info_entries = NULL; return user_info; @@ -521,6 +526,7 @@ } g_list_free(user_info->user_info_entries); + PURPLE_DBUS_UNREGISTER_POINTER(user_info); g_free(user_info); } diff -r 4c5d68e93ef8 -r dc042f70bd8c libpurple/server.c --- a/libpurple/server.c Sat May 19 22:48:25 2007 +0000 +++ b/libpurple/server.c Sat May 19 22:48:51 2007 +0000 @@ -576,15 +576,20 @@ purple_conv_im_set_typing_state(im, state); purple_conv_im_update_typing(im); } else { - if (state == PURPLE_TYPING) + switch (state) { - purple_signal_emit(purple_conversations_get_handle(), - "buddy-typing", gc->account, name); - } - else - { - purple_signal_emit(purple_conversations_get_handle(), - "buddy-typed", gc->account, name); + case PURPLE_TYPING: + purple_signal_emit(purple_conversations_get_handle(), + "buddy-typing", gc->account, name); + break; + case PURPLE_TYPED: + purple_signal_emit(purple_conversations_get_handle(), + "buddy-typed", gc->account, name); + break; + case PURPLE_NOT_TYPING: + purple_signal_emit(purple_conversations_get_handle(), + "buddy-typing-stopped", gc->account, name); + break; } } diff -r 4c5d68e93ef8 -r dc042f70bd8c pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sat May 19 22:48:25 2007 +0000 +++ b/pidgin/gtkconv.c Sat May 19 22:48:51 2007 +0000 @@ -5556,9 +5556,9 @@ flags = purple_conv_chat_user_get_flags(chat, user); - cbuddy = purple_conv_chat_cb_new(user, alias, flags); - - add_chat_buddy_common(conv, cbuddy, NULL); + cbuddy = purple_conv_chat_cb_find(chat, user); + if (cbuddy) + add_chat_buddy_common(conv, cbuddy, NULL); g_free(alias); } diff -r 4c5d68e93ef8 -r dc042f70bd8c pidgin/gtkidle.c --- a/pidgin/gtkidle.c Sat May 19 22:48:25 2007 +0000 +++ b/pidgin/gtkidle.c Sat May 19 22:48:51 2007 +0000 @@ -103,14 +103,21 @@ /* Query xscreensaver */ static XScreenSaverInfo *mit_info = NULL; + static int has_extension = -1; int event_base, error_base; - if (XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base)) { - if (mit_info == NULL) { + + if (has_extension == -1) + has_extension = XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base); + + if (has_extension) + { + if (mit_info == NULL) mit_info = XScreenSaverAllocInfo(); - } + XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info); return (mit_info->idle) / 1000; - } else + } + else return 0; # endif /* !_WIN32 */ # endif /* !HAVE_IOKIT */ diff -r 4c5d68e93ef8 -r dc042f70bd8c pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Sat May 19 22:48:25 2007 +0000 +++ b/pidgin/gtkimhtml.c Sat May 19 22:48:51 2007 +0000 @@ -3388,7 +3388,7 @@ return FALSE; pix = gdk_pixbuf_animation_get_static_image(anim); - image = gtk_imhtml_image_new(pix, NULL, 0); + image = gtk_imhtml_image_new(pix, smiley->smile, 0); ret = gtk_imhtml_image_clicked(w, event, (GtkIMHtmlImage*)image); g_object_set_data_full(G_OBJECT(w), "image-data", image, (GDestroyNotify)gtk_imhtml_image_free); g_object_unref(G_OBJECT(pix)); diff -r 4c5d68e93ef8 -r dc042f70bd8c pidgin/gtkmain.c --- a/pidgin/gtkmain.c Sat May 19 22:48:25 2007 +0000 +++ b/pidgin/gtkmain.c Sat May 19 22:48:51 2007 +0000 @@ -473,9 +473,6 @@ #else debug_enabled = FALSE; #endif - - /* This is the first Glib function call. Make sure to initialize GThread bfeore then */ - g_thread_init(NULL); #ifdef ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); diff -r 4c5d68e93ef8 -r dc042f70bd8c pidgin/gtkutils.c --- a/pidgin/gtkutils.c Sat May 19 22:48:25 2007 +0000 +++ b/pidgin/gtkutils.c Sat May 19 22:48:51 2007 +0000 @@ -510,10 +510,10 @@ const char *proto_name; char buf[256]; int i, selected_index = -1; - char *gtalk_name = NULL; + const char *gtalk_name = NULL; if (purple_find_prpl("prpl-jabber")) - gtalk_name = g_strdup(_("Google Talk")); + gtalk_name = _("Google Talk"); optmenu = gtk_option_menu_new(); gtk_widget_show(optmenu); @@ -548,10 +548,9 @@ image = gtk_image_new(); gtalk_item = pidgin_protocol_option_menu_item(menu, sg, image, gtalk_name, "prpl-fake"); - g_object_set_data(G_OBJECT(gtalk_item), "real_protocol", plugin->info->id); + g_object_set_data(G_OBJECT(gtalk_item), "real_protocol", "prpl-jabber"); i++; - g_free(gtalk_name); gtalk_name = NULL; } @@ -586,12 +585,6 @@ g_object_unref(G_OBJECT(pixbuf)); } - /* This is only needed if Pidgin has zero prpls compiled in, but - * I'm doing it because it's proper and might make a difference - * for automated source checkers. */ - g_free(gtalk_name); - - gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu); if (selected_index != -1) diff -r 4c5d68e93ef8 -r dc042f70bd8c pidgin/win32/gtkwin32dep.c --- a/pidgin/win32/gtkwin32dep.c Sat May 19 22:48:25 2007 +0000 +++ b/pidgin/win32/gtkwin32dep.c Sat May 19 22:48:51 2007 +0000 @@ -251,7 +251,13 @@ static gboolean stop_flashing(GtkWidget *widget, GdkEventFocus *event, gpointer data) { GtkWindow *window = data; + gpointer handler_id; + winpidgin_window_flash(window, FALSE); + + if ((handler_id = g_object_get_data(G_OBJECT(window), "flash_stop_handler_id"))) + g_signal_handler_disconnect(G_OBJECT(window), (gulong) GPOINTER_TO_UINT(handler_id)); + return FALSE; } @@ -275,12 +281,12 @@ memset(&info, 0, sizeof(FLASHWINFO)); info.cbSize = sizeof(FLASHWINFO); info.hwnd = GDK_WINDOW_HWND(gdkwin); - if (flash) - info.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG; - else + if (flash) { + info.uCount = 3; + info.dwFlags = FLASHW_ALL | FLASHW_TIMER; + } else info.dwFlags = FLASHW_STOP; info.dwTimeout = 0; - info.dwTimeout = 0; MyFlashWindowEx(&info); } else @@ -314,8 +320,11 @@ winpidgin_window_flash(window, TRUE); /* Stop flashing when window receives focus */ - g_signal_connect(G_OBJECT(window), "focus-in-event", - G_CALLBACK(stop_flashing), window); + if (g_object_get_data(G_OBJECT(window), "flash_stop_handler_id") == NULL) { + gulong handler_id = g_signal_connect(G_OBJECT(window), "focus-in-event", + G_CALLBACK(stop_flashing), window); + g_object_set_data(G_OBJECT(window), "flash_stop_handler_id", GUINT_TO_POINTER(handler_id)); + } } static gboolean