# HG changeset patch # User SHiNE CsyFeK # Date 1221835680 0 # Node ID 11de3fd58c59234e581ef433d3c562bba8109b7b # Parent d57928c9dd8f52eb70108d0c85d0c9cf4682c7f7# Parent 8f30b1f32f4637e6bcd92311ae9762c9d2db2e16 merge of '8c50cfe68a5cab6521acc54fedd6797e6c8b863f' and 'b5edbb5c5168486c2c8c4b6bd01af85cbe56dc3c' diff -r d57928c9dd8f -r 11de3fd58c59 ChangeLog --- a/ChangeLog Fri Sep 19 14:46:41 2008 +0000 +++ b/ChangeLog Fri Sep 19 14:48:00 2008 +0000 @@ -11,6 +11,8 @@ * Fix a case where a conversation window could close unexpectedly. * A mute sounds option has been added to the preferences window to help with discoverability. CTRL+S is no longer bound to mute. + * Added ability to change the color of visited links (using the theme + control plugin, or setting the color in ~/.gtkrc-2.0) Finch: * A new 'Nested Grouping' option in the 'Grouping' plugin. Group diff -r d57928c9dd8f -r 11de3fd58c59 libpurple/dnsquery.c --- a/libpurple/dnsquery.c Fri Sep 19 14:46:41 2008 +0000 +++ b/libpurple/dnsquery.c Fri Sep 19 14:48:00 2008 +0000 @@ -85,7 +85,7 @@ char hostname[512]; int port; } dns_params_t; -#endif +#endif /* end PURPLE_DNSQUERY_USE_FORK */ static void purple_dnsquery_resolved(PurpleDnsQueryData *query_data, GSList *hosts) @@ -108,6 +108,15 @@ } } +#ifdef PURPLE_DNSQUERY_USE_FORK + /* + * Add the resolver to the list of available resolvers, and set it + * to NULL so that it doesn't get destroyed along with the query_data + */ + free_dns_children = g_slist_prepend(free_dns_children, query_data->resolver); + query_data->resolver = NULL; +#endif /* PURPLE_DNSQUERY_USE_FORK */ + purple_dnsquery_destroy(query_data); } @@ -126,10 +135,7 @@ PurpleDnsQueryUiOps *ops = purple_dnsquery_get_ui_ops(); if (ops && ops->resolve_host) - { - if (ops->resolve_host(query_data, purple_dnsquery_resolved, purple_dnsquery_failed)) - return TRUE; - } + return ops->resolve_host(query_data, purple_dnsquery_resolved, purple_dnsquery_failed); return FALSE; } @@ -209,6 +215,16 @@ * the result back to our parent, when finished. */ while (1) { + fd_set fds; + struct timeval tv = { .tv_sec = 20, .tv_usec = 0 }; + FD_ZERO(&fds); + FD_SET(child_in, &fds); + rc = select(child_in + 1, &fds, NULL, NULL, &tv); + if (!rc) { + if (show_debug) + printf("dns[%d]: nobody needs me... =(\n", getpid()); + break; + } rc = read(child_in, &dns_params, sizeof(dns_params_t)); if (rc < 0) { fprintf(stderr, "dns[%d]: Error: Could not read dns_params: " @@ -402,9 +418,9 @@ /** * @return TRUE if the request was sent succesfully. FALSE - * if the request could not be sent. This isn't - * necessarily an error. If the child has expired, - * for example, we won't be able to send the message. + * if the request could not be sent. This isn't + * necessarily an error. If the child has expired, + * for example, we won't be able to send the message. */ static gboolean send_dns_request_to_child(PurpleDnsQueryData *query_data, @@ -476,13 +492,6 @@ query_data = queued_requests->data; queued_requests = g_slist_delete_link(queued_requests, queued_requests); - if (purple_dnsquery_ui_resolve(query_data)) - { - /* The UI is handling the resolve; we're done */ - handle_next_queued_request(); - return; - } - /* * If we have any children, attempt to have them perform the DNS * query. If we're able to send the query then resolver will be @@ -579,7 +588,7 @@ purple_dnsquery_failed(query_data, message); } else if (rc == 0) { - g_snprintf(message, sizeof(message), _("EOF while reading from resolver process")); + g_snprintf(message, sizeof(message), _("Resolver process exited without answering our request")); purple_dnsquery_failed(query_data, message); } @@ -594,6 +603,12 @@ query_data = data; query_data->timeout = 0; + if (purple_dnsquery_ui_resolve(query_data)) + { + /* The UI is handling the resolve; we're done */ + return FALSE; + } + handle_next_queued_request(); return FALSE; @@ -617,7 +632,7 @@ query_data->data = data; query_data->resolver = NULL; - if (strlen(query_data->hostname) == 0) + if (*query_data->hostname == '\0') { purple_dnsquery_destroy(query_data); g_return_val_if_reached(NULL); @@ -895,10 +910,13 @@ if (query_data->resolver != NULL) /* - * Ideally we would tell our resolver child to stop resolving - * shit and then we would add it back to the free_dns_children - * linked list. However, it's hard to tell children stuff, - * they just don't listen. + * This is only non-NULL when we're cancelling an in-progress + * query. Ideally we would tell our resolver child to stop + * resolving shit and then we would add it back to the + * free_dns_children linked list. However, it's hard to tell + * children stuff, they just don't listen. So we'll just + * kill the process and allow a new child to be started if we + * have more stuff to resolve. */ purple_dnsquery_resolver_destroy(query_data->resolver); #elif defined _WIN32 /* end PURPLE_DNSQUERY_USE_FORK */ @@ -922,7 +940,7 @@ query_data->hosts = g_slist_remove(query_data->hosts, query_data->hosts->data); } g_free(query_data->error_message); -#endif +#endif /* end _WIN32 */ if (query_data->timeout > 0) purple_timeout_remove(query_data->timeout); @@ -976,5 +994,5 @@ purple_dnsquery_resolver_destroy(free_dns_children->data); free_dns_children = g_slist_remove(free_dns_children, free_dns_children->data); } -#endif +#endif /* end PURPLE_DNSQUERY_USE_FORK */ } diff -r d57928c9dd8f -r 11de3fd58c59 libpurple/protocols/oscar/flap_connection.c --- a/libpurple/protocols/oscar/flap_connection.c Fri Sep 19 14:46:41 2008 +0000 +++ b/libpurple/protocols/oscar/flap_connection.c Fri Sep 19 14:48:00 2008 +0000 @@ -158,8 +158,8 @@ gettimeofday(&now, NULL); purple_debug_info("oscar", "Attempting to send %u queued SNACs and %u queued low-priority SNACs for %p\n", - (conn->queued_snacs ? g_queue_get_length(conn->queued_snacs) : 0), - (conn->queued_lowpriority_snacs ? g_queue_get_length(conn->queued_lowpriority_snacs) : 0), + (conn->queued_snacs ? conn->queued_snacs->length : 0), + (conn->queued_lowpriority_snacs ? conn->queued_lowpriority_snacs->length : 0), conn); if (!conn->queued_snacs || flap_connection_send_snac_queue(conn, now, conn->queued_snacs)) { if (!conn->queued_lowpriority_snacs || flap_connection_send_snac_queue(conn, now, conn->queued_lowpriority_snacs)) { diff -r d57928c9dd8f -r 11de3fd58c59 libpurple/proxy.c --- a/libpurple/proxy.c Fri Sep 19 14:46:41 2008 +0000 +++ b/libpurple/proxy.c Fri Sep 19 14:48:00 2008 +0000 @@ -212,19 +212,21 @@ { static PurpleProxyInfo info = {0, NULL, 0, NULL, NULL}; gboolean use_same_proxy = FALSE; - gchar *tmp, *err; + gchar *tmp, *err = NULL; tmp = g_find_program_in_path("gconftool-2"); if (tmp == NULL) return purple_global_proxy_get_info(); g_free(tmp); + tmp = NULL; /* Check whether to use a proxy. */ if (!g_spawn_command_line_sync("gconftool-2 -g /system/proxy/mode", &tmp, &err, NULL, NULL)) return purple_global_proxy_get_info(); g_free(err); + err = NULL; if (!strcmp(tmp, "none\n")) { info.type = PURPLE_PROXY_NONE; @@ -239,6 +241,7 @@ } g_free(tmp); + tmp = NULL; /* Free the old fields */ if (info.host) { @@ -258,28 +261,31 @@ &tmp, &err, NULL, NULL)) return purple_global_proxy_get_info(); g_free(err); + err = NULL; if (!strcmp(tmp, "true\n")) use_same_proxy = TRUE; g_free(tmp); + tmp = NULL; - if (!use_same_proxy && !g_spawn_command_line_sync("gconftool-2 -g /system/proxy/socks_host", + if (!use_same_proxy) { + if (!g_spawn_command_line_sync("gconftool-2 -g /system/proxy/socks_host", &info.host, &err, NULL, NULL)) - return purple_global_proxy_get_info(); - g_free(err); - g_strchomp(info.host); + return purple_global_proxy_get_info(); + g_free(err); + err = NULL; + } - if (!use_same_proxy && *info.host != '\0') { + if(info.host != NULL) + g_strchomp(info.host); + + if (!use_same_proxy && (info.host != NULL) && (*info.host != '\0')) { info.type = PURPLE_PROXY_SOCKS5; if (!g_spawn_command_line_sync("gconftool-2 -g /system/proxy/socks_port", &tmp, &err, NULL, NULL)) { g_free(info.host); info.host = NULL; - g_free(info.username); - info.username = NULL; - g_free(info.password); - info.password = NULL; return purple_global_proxy_get_info(); } g_free(err); @@ -291,6 +297,8 @@ &info.host, &err, NULL, NULL)) return purple_global_proxy_get_info(); g_free(err); + err = NULL; + /* If we get this far then we know we're using an HTTP proxy */ info.type = PURPLE_PROXY_HTTP; @@ -310,11 +318,10 @@ { g_free(info.host); info.host = NULL; - g_free(info.username); - info.username = NULL; return purple_global_proxy_get_info(); } g_free(err); + err = NULL; g_strchomp(info.username); if (!g_spawn_command_line_sync("gconftool-2 -g /system/http_proxy/authentication_password", @@ -327,6 +334,7 @@ return purple_global_proxy_get_info(); } g_free(err); + err = NULL; g_strchomp(info.password); if (!g_spawn_command_line_sync("gconftool-2 -g /system/http_proxy/port", diff -r d57928c9dd8f -r 11de3fd58c59 pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Fri Sep 19 14:46:41 2008 +0000 +++ b/pidgin/gtkimhtml.c Fri Sep 19 14:48:00 2008 +0000 @@ -446,6 +446,20 @@ parent_style_set(widget, prev_style); } +static void +gtk_imhtml_set_link_color(GtkIMHtml *imhtml, GtkTextTag *tag) +{ + GdkColor *color = NULL; + gboolean visited = !!g_object_get_data(G_OBJECT(tag), "visited"); + gtk_widget_style_get(GTK_WIDGET(imhtml), visited ? "hyperlink-visited-color" : "hyperlink-color", &color, NULL); + if (color) { + g_object_set(G_OBJECT(tag), "foreground-gdk", color, NULL); + gdk_color_free(color); + } else { + g_object_set(G_OBJECT(tag), "foreground", visited ? "#800000" : "blue", NULL); + } +} + static gint gtk_imhtml_tip_paint (GtkIMHtml *imhtml) { @@ -566,7 +580,6 @@ int x, y; char *tip = NULL; GSList *tags = NULL, *templist = NULL; - GdkColor *norm, *pre; GtkTextTag *tag = NULL, *oldprelit_tag; GtkTextChildAnchor* anchor; gboolean hand = TRUE; @@ -588,13 +601,15 @@ templist = templist->next; } - if (tip) { - gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-prelight-color", &pre, NULL); + if (tip && (!tag || !g_object_get_data(G_OBJECT(tag), "visited"))) { GTK_IMHTML(imhtml)->prelit_tag = tag; if (tag != oldprelit_tag) { - if (pre) + GdkColor *pre = NULL; + gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-prelight-color", &pre, NULL); + if (pre) { g_object_set(G_OBJECT(tag), "foreground-gdk", pre, NULL); - else + gdk_color_free(pre); + } else g_object_set(G_OBJECT(tag), "foreground", "#70a0ff", NULL); } } else { @@ -602,11 +617,7 @@ } if ((oldprelit_tag != NULL) && (GTK_IMHTML(imhtml)->prelit_tag != oldprelit_tag)) { - gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-color", &norm, NULL); - if (norm) - g_object_set(G_OBJECT(oldprelit_tag), "foreground-gdk", norm, NULL); - else - g_object_set(G_OBJECT(oldprelit_tag), "foreground", "blue", NULL); + gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), oldprelit_tag); } if (GTK_IMHTML(imhtml)->tip) { @@ -670,12 +681,7 @@ { /* when leaving the widget, clear any current & pending tooltips and restore the cursor */ if (GTK_IMHTML(imhtml)->prelit_tag) { - GdkColor *norm; - gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-color", &norm, NULL); - if (norm) - g_object_set(G_OBJECT(GTK_IMHTML(imhtml)->prelit_tag), "foreground-gdk", norm, NULL); - else - g_object_set(G_OBJECT(GTK_IMHTML(imhtml)->prelit_tag), "foreground", "blue", NULL); + gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), GTK_IMHTML(imhtml)->prelit_tag); GTK_IMHTML(imhtml)->prelit_tag = NULL; } @@ -1482,6 +1488,10 @@ _("Hyperlink color"), _("Color to draw hyperlinks."), GDK_TYPE_COLOR, G_PARAM_READABLE)); + gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-visited-color", + _("Hyperlink visited color"), + _("Color to draw hyperlinks after it has been visited (or activated)."), + GDK_TYPE_COLOR, G_PARAM_READABLE)); gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-prelight-color", _("Hyperlink prelight color"), _("Color to draw hyperlinks when mouse is over them."), @@ -1679,20 +1689,24 @@ struct url_data { GObject *object; gchar *url; + GtkTextTag *tag; }; static void url_data_destroy(gpointer mydata) { struct url_data *data = mydata; g_object_unref(data->object); + g_object_unref(data->tag); g_free(data->url); g_free(data); } -static void url_open(GtkWidget *w, struct url_data *data) { +static void url_open(GtkWidget *w, struct url_data *data) +{ if(!data) return; g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url); - + g_object_set_data(G_OBJECT(data->tag), "visited", GINT_TO_POINTER(TRUE)); + gtk_imhtml_set_link_color(GTK_IMHTML(data->object), data->tag); } static void url_copy(GtkWidget *w, gchar *url) { @@ -1706,7 +1720,8 @@ } /* The callback for an event on a link tag. */ -static gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, gpointer unused) { +static gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, gpointer unused) +{ GdkEventButton *event_button = (GdkEventButton *) event; if (GTK_IMHTML(imhtml)->editable) return FALSE; @@ -1723,12 +1738,15 @@ g_object_ref(G_OBJECT(tag)); g_signal_emit(imhtml, signals[URL_CLICKED], 0, g_object_get_data(G_OBJECT(tag), "link_url")); g_object_unref(G_OBJECT(tag)); + g_object_set_data(G_OBJECT(tag), "visited", GINT_TO_POINTER(TRUE)); + gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), tag); return FALSE; } else if(event_button->button == 3) { GtkWidget *img, *item, *menu; struct url_data *tempdata = g_new(struct url_data, 1); tempdata->object = g_object_ref(imhtml); tempdata->url = g_strdup(g_object_get_data(G_OBJECT(tag), "link_url")); + tempdata->tag = g_object_ref(tag); /* Don't want the tooltip around if user right-clicked on link */ if (GTK_IMHTML(imhtml)->tip_window) { diff -r d57928c9dd8f -r 11de3fd58c59 pidgin/gtkmenutray.c --- a/pidgin/gtkmenutray.c Fri Sep 19 14:46:41 2008 +0000 +++ b/pidgin/gtkmenutray.c Fri Sep 19 14:48:00 2008 +0000 @@ -84,6 +84,14 @@ } static void +pidgin_menu_tray_map(GtkWidget *widget) +{ + GTK_WIDGET_CLASS(parent_class)->map(widget); + gtk_container_add(GTK_CONTAINER(widget), + PIDGIN_MENU_TRAY(widget)->tray); +} + +static void pidgin_menu_tray_finalize(GObject *obj) { PidginMenuTray *tray = PIDGIN_MENU_TRAY(obj); @@ -109,6 +117,7 @@ pidgin_menu_tray_class_init(PidginMenuTrayClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); GtkItemClass *item_class = GTK_ITEM_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); GParamSpec *pspec; parent_class = g_type_class_peek_parent(klass); @@ -119,6 +128,8 @@ item_class->select = pidgin_menu_tray_select; item_class->deselect = pidgin_menu_tray_deselect; + widget_class->map = pidgin_menu_tray_map; + pspec = g_param_spec_object("box", "The box", "The box", GTK_TYPE_BOX, @@ -152,8 +163,6 @@ gtk_widget_set_size_request(widget, -1, height); } - gtk_container_add(GTK_CONTAINER(menu_tray), menu_tray->tray); - gtk_widget_show(menu_tray->tray); } diff -r d57928c9dd8f -r 11de3fd58c59 pidgin/plugins/pidginrc.c --- a/pidgin/plugins/pidginrc.c Fri Sep 19 14:46:41 2008 +0000 +++ b/pidgin/plugins/pidginrc.c Fri Sep 19 14:48:00 2008 +0000 @@ -31,6 +31,7 @@ "/plugins/gtk/purplerc/color/GtkWidget::cursor-color", "/plugins/gtk/purplerc/color/GtkWidget::secondary-cursor-color", "/plugins/gtk/purplerc/color/GtkIMHtml::hyperlink-color", + "/plugins/gtk/purplerc/color/GtkIMHtml::hyperlink-visited-color", "/plugins/gtk/purplerc/color/GtkIMHtml::send-name-color", "/plugins/gtk/purplerc/color/GtkIMHtml::receive-name-color", "/plugins/gtk/purplerc/color/GtkIMHtml::highlight-name-color", @@ -40,6 +41,7 @@ "/plugins/gtk/purplerc/set/color/GtkWidget::cursor-color", "/plugins/gtk/purplerc/set/color/GtkWidget::secondary-cursor-color", "/plugins/gtk/purplerc/set/color/GtkIMHtml::hyperlink-color", + "/plugins/gtk/purplerc/set/color/GtkIMHtml::hyperlink-visited-color", "/plugins/gtk/purplerc/set/color/GtkIMHtml::send-name-color", "/plugins/gtk/purplerc/set/color/GtkIMHtml::receive-name-color", "/plugins/gtk/purplerc/set/color/GtkIMHtml::highlight-name-color", @@ -49,6 +51,7 @@ N_("Cursor Color"), N_("Secondary Cursor Color"), N_("Hyperlink Color"), + N_("Visited Hyperlink Color"), N_("Sent Message Name Color"), N_("Received Message Name Color"), N_("Highlighted Message Name Color"),