# HG changeset patch # User Richard Laager # Date 1189965520 0 # Node ID 642f08c490422bed9a1e8491dfc13c661e26af06 # Parent 34abe3faeaab0a153695a68ca3f067ba328ca7ed# Parent 1b95e3bd56283043f4741dfe78059bc4194aa66c explicit merge of 'b9e805b43e8543af0b4800e2e5553c85d947c610' and '85472e3c3dd9b1f401f415ad82bf18dd5a2f15a5' diff -r 34abe3faeaab -r 642f08c49042 COPYRIGHT --- a/COPYRIGHT Sun Sep 16 17:52:49 2007 +0000 +++ b/COPYRIGHT Sun Sep 16 17:58:40 2007 +0000 @@ -339,6 +339,7 @@ Michael Shkutkov Ettore Simone John Silvestri +Ankit Singla Craig Slusher Alex Smith Brad Smith @@ -349,6 +350,7 @@ Sony Computer Entertainment America, Inc. Andy Spencer Mark Spencer +Peter Speybrouck Lex Spoon Chris Stafford Kevin Stange @@ -375,6 +377,7 @@ Warren Togami Stu Tomlinson Bill Tompkins +Gal Topper Chris Toshok Ken Tossell Tom Tromey diff -r 34abe3faeaab -r 642f08c49042 ChangeLog.API --- a/ChangeLog.API Sun Sep 16 17:52:49 2007 +0000 +++ b/ChangeLog.API Sun Sep 16 17:58:40 2007 +0000 @@ -6,6 +6,9 @@ * PURPLE_MESSAGE_INVISIBLE flag, which can be used by purple_conv_im_send_with_flags to send a message, but not display it in the conversation + * serv_send_attention(), serv_got_attention(), as well as send_attention + and attention_types in PurplePluginProtocolInfo. This new API is used + for zapping in MySpaceIM, buzzing in Yahoo, and nudging in MSN. Changed: * purple_prefs_load is now called within purple_prefs_init. The UI no longer needs to call it. diff -r 34abe3faeaab -r 642f08c49042 libpurple/certificate.c --- a/libpurple/certificate.c Sun Sep 16 17:52:49 2007 +0000 +++ b/libpurple/certificate.c Sun Sep 16 17:58:40 2007 +0000 @@ -1083,11 +1083,14 @@ x509_tls_cached_show_cert(x509_tls_cached_ua_ctx *c, gint id) { PurpleCertificate *disp_crt = c->vrq->cert_chain->data; - purple_certificate_display_x509(disp_crt); /* Since clicking a button closes the request, show it again */ x509_tls_cached_user_auth(c->vrq, c->reason); + /* Show the certificate AFTER re-opening the dialog so that this + appears above the other */ + purple_certificate_display_x509(disp_crt); + x509_tls_cached_ua_ctx_free(c); } diff -r 34abe3faeaab -r 642f08c49042 libpurple/internal.h --- a/libpurple/internal.h Sun Sep 16 17:52:49 2007 +0000 +++ b/libpurple/internal.h Sun Sep 16 17:58:40 2007 +0000 @@ -29,6 +29,10 @@ # include #endif +/* for SIOCGIFCONF in SKYOS */ +#ifdef SKYOS +#include +#endif /* * If we're using NLS, make sure gettext works. If not, then define * dummy macros in place of the normal gettext macros. diff -r 34abe3faeaab -r 642f08c49042 libpurple/plugins/tcl/tcl_cmds.c --- a/libpurple/plugins/tcl/tcl_cmds.c Sun Sep 16 17:52:49 2007 +0000 +++ b/libpurple/plugins/tcl/tcl_cmds.c Sun Sep 16 17:58:40 2007 +0000 @@ -544,12 +544,16 @@ int tcl_cmd_cmd(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { - const char *cmds[] = { "register", "unregister", NULL }; - enum { CMD_CMD_REGISTER, CMD_CMD_UNREGISTER } cmd; + const char *cmds[] = { "do", "help", "list", "register", "unregister", NULL }; + enum { CMD_CMD_DO, CMD_CMD_HELP, CMD_CMD_LIST, CMD_CMD_REGISTER, CMD_CMD_UNREGISTER } cmd; struct tcl_cmd_handler *handler; - Tcl_Obj *result = Tcl_GetObjResult(interp); + Tcl_Obj *list, *elem, *result = Tcl_GetObjResult(interp); + PurpleConversation *convo; PurpleCmdId id; + PurpleCmdStatus status; int error; + GList *l, *cur; + gchar *escaped, *errstr = NULL; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); @@ -560,6 +564,57 @@ return error; switch (cmd) { + case CMD_CMD_DO: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "conversation command"); + return TCL_ERROR; + } + if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) + return TCL_ERROR; + escaped = g_markup_escape_text(Tcl_GetString(objv[3]), -1); + status = purple_cmd_do_command(convo, Tcl_GetString(objv[3]), + escaped, &errstr); + g_free(escaped); + Tcl_SetStringObj(result, errstr ? (char *)errstr : "", -1); + g_free(errstr); + if (status != PURPLE_CMD_STATUS_OK) { + return TCL_ERROR; + } + break; + case CMD_CMD_HELP: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "conversation name"); + return TCL_ERROR; + } + if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) + return TCL_ERROR; + l = cur = purple_cmd_help(convo, Tcl_GetString(objv[3])); + list = Tcl_NewListObj(0, NULL); + while (cur != NULL) { + elem = Tcl_NewStringObj((char *)cur->data, -1); + Tcl_ListObjAppendElement(interp, list, elem); + cur = g_list_next(cur); + } + g_list_free(l); + Tcl_SetObjResult(interp, list); + break; + case CMD_CMD_LIST: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "conversation"); + return TCL_ERROR; + } + if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) + return TCL_ERROR; + l = cur = purple_cmd_list(convo); + list = Tcl_NewListObj(0, NULL); + while (cur != NULL) { + elem = Tcl_NewStringObj((char *)cur->data, -1); + Tcl_ListObjAppendElement(interp, list, elem); + cur = g_list_next(cur); + } + g_list_free(l); + Tcl_SetObjResult(interp, list); + break; case CMD_CMD_REGISTER: if (objc != 9) { Tcl_WrongNumArgs(interp, 2, objv, "cmd arglist priority flags prpl_id proc helpstr"); diff -r 34abe3faeaab -r 642f08c49042 libpurple/protocols/msn/slp.c --- a/libpurple/protocols/msn/slp.c Sun Sep 16 17:52:49 2007 +0000 +++ b/libpurple/protocols/msn/slp.c Sun Sep 16 17:58:40 2007 +0000 @@ -345,7 +345,7 @@ if (xfer) { bin = (char *)purple_base64_decode(context, &bin_len); - file_size = GUINT32_FROM_LE(*((gsize *)bin + 2)); + file_size = GUINT32_FROM_LE(*(gsize *)(bin + 2)); uni_name = (gunichar2 *)(bin + 20); while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) { diff -r 34abe3faeaab -r 642f08c49042 libpurple/protocols/myspace/CHANGES --- a/libpurple/protocols/myspace/CHANGES Sun Sep 16 17:52:49 2007 +0000 +++ b/libpurple/protocols/myspace/CHANGES Sun Sep 16 17:58:40 2007 +0000 @@ -1,3 +1,13 @@ +2007-08-28 Jeff Connelly - 0.17 +* Get server-side contact list from server on sign-on (partly implements + server-side contacts, ticket #2658). +* Set local alias to username on sign-on, if not already set. This fixes + #2793, though this may not be the best way, other fixes under consideration. +* Support myim:sendIM and addContact URLs with cID and uID parameters. +* Fix #2722, only check for mail if "New mail notifications" is enabled. +* Modularize msimprpl. + + 2007-08-23 Jeff Connelly - 0.16 * Add option to add all friends from myspace.com to your buddy list (#2660) * If a user doesn't have a picture, don't display an icon (instead of @@ -6,6 +16,7 @@ * Fix #2752, which led to duplicate groups * Fix #2720, crash/disconnect when adding a buddy that doesn't exist (You'll now receive an error when looking up invalid usernames). +* Source-code release only. 2007-08-22 Jeff Connelly - 0.15 * Incomplete implementation of adding friends from myspace.com. diff -r 34abe3faeaab -r 642f08c49042 libpurple/protocols/myspace/myspace.c --- a/libpurple/protocols/myspace/myspace.c Sun Sep 16 17:52:49 2007 +0000 +++ b/libpurple/protocols/myspace/myspace.c Sun Sep 16 17:58:40 2007 +0000 @@ -683,6 +683,7 @@ msim_incoming_im(MsimSession *session, MsimMessage *msg) { gchar *username, *msg_msim_markup, *msg_purple_markup; + time_t time_received; g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE); g_return_val_if_fail(msg != NULL, FALSE); @@ -696,8 +697,12 @@ msg_purple_markup = msim_markup_to_html(session, msg_msim_markup); g_free(msg_msim_markup); - serv_got_im(session->gc, username, msg_purple_markup, - PURPLE_MESSAGE_RECV, time(NULL)); + time_received = msim_msg_get_integer(msg, "date"); + if (!time_received) { + time_received = time(NULL); + } + + serv_got_im(session->gc, username, msg_purple_markup, PURPLE_MESSAGE_RECV, time_received); g_free(username); g_free(msg_purple_markup); diff -r 34abe3faeaab -r 642f08c49042 libpurple/util.c diff -r 34abe3faeaab -r 642f08c49042 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sun Sep 16 17:52:49 2007 +0000 +++ b/pidgin/gtkblist.c Sun Sep 16 17:58:40 2007 +0000 @@ -2622,6 +2622,7 @@ struct _pidgin_blist_node *gtknode; GdkRectangle mon_size; int sig; + const char *name; if (node == NULL) return; @@ -2679,7 +2680,9 @@ gtknode = node->ui_data; + name = gtk_window_get_title(GTK_WINDOW(gtk_widget_get_toplevel(widget))); gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE); + gtk_window_set_title(GTK_WINDOW(gtkblist->tipwindow), name ? name : _("Buddy List")); gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE); gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips"); g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event", @@ -5206,6 +5209,10 @@ GdkPixbuf *emblem; char *mark; gboolean showicons = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"); + const char *name = purple_chat_get_name(chat); + PurpleConversation *conv = + purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, name, chat->account); + gboolean hidden = (conv && !PIDGIN_CONVERSATION(conv)); if(!insert_node(list, node, &iter)) return; @@ -5221,15 +5228,20 @@ avatar = NULL; mark = g_markup_escape_text(purple_chat_get_name(chat), -1); + if (hidden) { + char *bold = g_strdup_printf("%s", mark); + g_free(mark); + mark = bold; + } gtk_tree_store_set(gtkblist->treemodel, &iter, STATUS_ICON_COLUMN, status, STATUS_ICON_VISIBLE_COLUMN, TRUE, BUDDY_ICON_COLUMN, avatar ? avatar : gtkblist->empty_avatar, BUDDY_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"), - EMBLEM_COLUMN, emblem, + EMBLEM_COLUMN, emblem, EMBLEM_VISIBLE_COLUMN, emblem != NULL, - PROTOCOL_ICON_COLUMN, pidgin_create_prpl_icon(chat->account, PIDGIN_PRPL_ICON_SMALL), + PROTOCOL_ICON_COLUMN, pidgin_create_prpl_icon(chat->account, PIDGIN_PRPL_ICON_SMALL), PROTOCOL_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"), NAME_COLUMN, mark, GROUP_EXPANDER_VISIBLE_COLUMN, FALSE, diff -r 34abe3faeaab -r 642f08c49042 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sun Sep 16 17:52:49 2007 +0000 +++ b/pidgin/gtkconv.c Sun Sep 16 17:58:40 2007 +0000 @@ -139,6 +139,7 @@ static void generate_send_to_items(PidginWindow *win); /* Prototypes. <-- because Paco-Paco hates this comment. */ +static gboolean infopane_entry_activate(PidginConversation *gtkconv); static void got_typing_keypress(PidginConversation *gtkconv, gboolean first); static void gray_stuff_out(PidginConversation *gtkconv); static GList *generate_invite_user_names(PurpleConnection *gc); @@ -158,6 +159,8 @@ static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); static gboolean alias_double_click_cb(GtkWidget *widget, GdkEventButton *event, PidginConversation *gtkconv); +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 pidgin_conv_set_position_size(PidginWindow *win, int x, int y, int width, int height); @@ -1791,17 +1794,108 @@ } static gboolean +conv_keypress_common(PidginConversation *gtkconv, GdkEventKey *event) +{ + PidginWindow *win; + PurpleConversation *conv; + int curconv; + + conv = gtkconv->active_conv; + win = gtkconv->win; + curconv = gtk_notebook_get_current_page(GTK_NOTEBOOK(win->notebook)); + + /* If CTRL was held down... */ + if (event->state & GDK_CONTROL_MASK) { + switch (event->keyval) { + case GDK_Page_Down: + case ']': + if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1)) + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0); + else + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1); + return TRUE; + break; + + case GDK_Page_Up: + case '[': + if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1)) + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1); + else + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1); + return TRUE; + break; + + case GDK_Tab: + case GDK_ISO_Left_Tab: + if (event->state & GDK_SHIFT_MASK) { + move_to_next_unread_tab(gtkconv, FALSE); + } else { + move_to_next_unread_tab(gtkconv, TRUE); + } + + return TRUE; + break; + + case GDK_comma: + gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), + gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), + curconv - 1); + break; + + case GDK_period: + gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), + gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), +#if GTK_CHECK_VERSION(2,2,0) + (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook))); +#else + (curconv + 1) % g_list_length(GTK_NOTEBOOK(win->notebook)->children)); +#endif + break; + + } /* End of switch */ + } + + /* If ALT (or whatever) was held down... */ + else if (event->state & GDK_MOD1_MASK) + { + if (event->keyval > '0' && event->keyval <= '9') + { + guint switchto = event->keyval - '1'; + if (switchto < pidgin_conv_window_get_gtkconv_count(win)) + gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), switchto); + + return TRUE; + } + } + + /* If neither CTRL nor ALT were held down... */ + else + { + switch (event->keyval) { + case GDK_F2: + if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) { + infopane_entry_activate(gtkconv); + return TRUE; + } + break; + } + } + return FALSE; +} + +static gboolean entry_key_press_cb(GtkWidget *entry, GdkEventKey *event, gpointer data) { PidginWindow *win; PurpleConversation *conv; PidginConversation *gtkconv; - int curconv; gtkconv = (PidginConversation *)data; conv = gtkconv->active_conv; win = gtkconv->win; - curconv = gtk_notebook_get_current_page(GTK_NOTEBOOK(win->notebook)); + + if (conv_keypress_common(gtkconv, event)) + return TRUE; /* If CTRL was held down... */ if (event->state & GDK_CONTROL_MASK) { @@ -1899,88 +1993,32 @@ return TRUE; break; - - case GDK_Page_Down: - case ']': - if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1)) - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0); - else - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1); - return TRUE; - break; - - case GDK_Page_Up: - case '[': - if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1)) - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1); - else - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1); - return TRUE; - break; - - case GDK_Tab: - case GDK_ISO_Left_Tab: - if (event->state & GDK_SHIFT_MASK) { - move_to_next_unread_tab(gtkconv, FALSE); - } else { - move_to_next_unread_tab(gtkconv, TRUE); - } - - return TRUE; - break; - - case GDK_comma: - gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), - gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), - curconv - 1); - break; - - case GDK_period: - gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), - gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), -#if GTK_CHECK_VERSION(2,2,0) - (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook))); -#else - (curconv + 1) % g_list_length(GTK_NOTEBOOK(win->notebook)->children)); -#endif - break; - } /* End of switch */ } /* If ALT (or whatever) was held down... */ - else if (event->state & GDK_MOD1_MASK) - { - if (event->keyval > '0' && event->keyval <= '9') - { - guint switchto = event->keyval - '1'; - if (switchto < pidgin_conv_window_get_gtkconv_count(win)) - gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), switchto); - - return TRUE; - } + else if (event->state & GDK_MOD1_MASK) { + } /* If neither CTRL nor ALT were held down... */ - else - { - switch (event->keyval) - { - case GDK_Tab: - if (gtkconv->entry != entry) - break; - return tab_complete(conv); + else { + switch (event->keyval) { + case GDK_Tab: + if (gtkconv->entry != entry) break; - - case GDK_Page_Up: - gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); - return TRUE; - break; - - case GDK_Page_Down: - gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); - return TRUE; - break; + return tab_complete(conv); + break; + + case GDK_Page_Up: + gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); + return TRUE; + break; + + case GDK_Page_Down: + gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); + return TRUE; + break; } } @@ -2021,6 +2059,7 @@ /* If we have a valid key for the conversation display, then exit */ if ((event->state & GDK_CONTROL_MASK) || + (event->keyval == GDK_F6) || (event->keyval == GDK_F10) || (event->keyval == GDK_Shift_L) || (event->keyval == GDK_Shift_R) || @@ -2031,11 +2070,17 @@ (event->keyval == GDK_Down) || (event->keyval == GDK_Left) || (event->keyval == GDK_Right) || + (event->keyval == GDK_Page_Up) || + (event->keyval == GDK_Page_Down) || (event->keyval == GDK_Home) || (event->keyval == GDK_End) || (event->keyval == GDK_Tab) || (event->keyval == GDK_ISO_Left_Tab)) - return FALSE; + { + if (event->type == GDK_KEY_PRESS) + return conv_keypress_common(gtkconv, event); + return FALSE; + } if (event->type == GDK_KEY_RELEASE) gtk_widget_grab_focus(gtkconv->entry); @@ -4393,6 +4438,10 @@ g_signal_connect(G_OBJECT(list), "button_press_event", G_CALLBACK(right_click_chat_cb), gtkconv); + g_signal_connect(G_OBJECT(list), "motion-notify-event", + G_CALLBACK(pidgin_userlist_motion_cb), gtkconv); + g_signal_connect(G_OBJECT(list), "leave-notify-event", + G_CALLBACK(pidgin_userlist_motion_cb), gtkconv); g_signal_connect(G_OBJECT(list), "popup-menu", G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv); g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv); @@ -4437,6 +4486,8 @@ int timeout; PidginConversation *gtkconv; /* This is the Pidgin conversation that triggered the tooltip */ + int userlistx; + int userlisty; } tooltip; static void @@ -4493,6 +4544,72 @@ return FALSE; } +static gboolean +pidgin_userlist_tooltip_timeout(PidginConversation *gtkconv) +{ + PurplePluginProtocolInfo *prpl_info; + PurpleConversation *conv = gtkconv->active_conv; + PidginChatPane *gtkchat; + PurpleConnection *gc; + PurpleBlistNode *node = NULL; + PurpleAccount *account; + GtkTreePath *path; + GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeViewColumn *column; + gchar *who; + int x, y; + + gtkchat = gtkconv->u.chat; + account = purple_conversation_get_account(conv); + gc = account->gc; + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); + + gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkchat->list), + tooltip.userlistx, tooltip.userlisty, &path, &column, &x, &y); + + if (path == NULL) + return FALSE; + + gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path); + gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); + + node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who)); + if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) + pidgin_blist_draw_tooltip(node, gtkconv->infopane); + + g_free(who); + gtk_tree_path_free(path); + + + return FALSE; +} + +static gboolean +pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv) +{ + PurpleConversation *conv; + int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay"); + + pidgin_blist_tooltip_destroy(); + if (delay == 0) + return FALSE; + + if (tooltip.timeout != 0) + g_source_remove(tooltip.timeout); + + conv = gtkconv->active_conv; + + tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_userlist_tooltip_timeout, gtkconv); + tooltip.gtkconv = gtkconv; + tooltip.userlistx = event->x; + tooltip.userlisty = event->y; + + return FALSE; +} + static GtkWidget * setup_common_pane(PidginConversation *gtkconv) { @@ -5625,6 +5742,7 @@ account, name, displaying, conv, flags); g_free(displaying); } + static void pidgin_conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) { @@ -7238,10 +7356,10 @@ "conversation-displayed", gtkconv); } - /* XXX: If this is a chat: - * - populate the userlist - * - set the topic - */ + if (conv->type == PURPLE_CONV_TYPE_CHAT) { + pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC); + pidgin_conv_chat_add_users(conv, PURPLE_CONV_CHAT(conv)->in_room, TRUE); + } return TRUE; } @@ -7863,7 +7981,7 @@ infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) { if (e->type == GDK_2BUTTON_PRESS && e->button == 1) { - if (alias_double_click_cb(widget, e, gtkconv)) + if (infopane_entry_activate(gtkconv)) return TRUE; } @@ -8320,16 +8438,12 @@ } static gboolean -alias_double_click_cb(GtkWidget *widget, GdkEventButton *event, PidginConversation *gtkconv) +infopane_entry_activate(PidginConversation *gtkconv) { GtkWidget *entry = NULL; PurpleConversation *conv = gtkconv->active_conv; const char *text = NULL; - if (event->button != 1 || event->type != GDK_2BUTTON_PRESS) { - return FALSE; - } - if (!GTK_WIDGET_VISIBLE(gtkconv->tab_label)) { /* There's already an entry for alias. Let's not create another one. */ return FALSE; @@ -8372,9 +8486,30 @@ gtk_widget_hide(gtkconv->infopane); gtk_widget_grab_focus(entry); + return TRUE; +} + +static gboolean +alias_double_click_cb(GtkWidget *widget, GdkEventButton *event, PidginConversation *gtkconv) +{ + /* I'm keeping this around in case we decide to handle double-clicking tabs + * (or some other label) this way. */ + if (event->button != 1 || event->type != GDK_2BUTTON_PRESS) { + return FALSE; + } + + infopane_entry_activate(gtkconv); return FALSE; } +static gboolean +window_keypress_cb(GtkWidget *widget, GdkEventKey *event, PidginWindow *win) +{ + PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win); + + return conv_keypress_common(gtkconv, event); +} + static void switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num, gpointer user_data) @@ -8570,6 +8705,11 @@ g_signal_connect(G_OBJECT(win->window), "focus_in_event", G_CALLBACK(focus_win_cb), win); + /* Intercept keystrokes from the menu items */ + g_signal_connect(G_OBJECT(win->window), "key_press_event", + G_CALLBACK(window_keypress_cb), win); + + /* Create the notebook. */ win->notebook = gtk_notebook_new(); diff -r 34abe3faeaab -r 642f08c49042 pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Sun Sep 16 17:52:49 2007 +0000 +++ b/pidgin/gtkimhtml.c Sun Sep 16 17:58:40 2007 +0000 @@ -4890,7 +4890,7 @@ } else if (c == '"') { str = g_string_append(str, """); } else if (c == '\n') { - str = g_string_append(str, "
"); + str = g_string_append(str, "
\n"); } else { str = g_string_append_unichar(str, c); }