diff options
author | Sean Egan <seanegan@pidgin.im> | 2007-01-16 02:48:36 +0000 |
---|---|---|
committer | Sean Egan <seanegan@pidgin.im> | 2007-01-16 02:48:36 +0000 |
commit | f0f23c2822188c79a8d7cffd138fc7fa7f2ad123 (patch) | |
tree | 46cb2c2df9c51feab8529c791aa221e755f44635 | |
parent | 2992f659cebb7e52b2fa446944715cf1121c0055 (diff) | |
download | pidgin-f0f23c2822188c79a8d7cffd138fc7fa7f2ad123.tar.gz |
[gaim-migrate @ 18134]
Syncing up my tree. I've gotten smileys, <hr>'s and IM images to *mostly* work. Scrolling's the
only obviously busted thing right now.
I also made blist headlines set the URGENT hint.
-rw-r--r-- | gtk/gtkblist.c | 2 | ||||
-rw-r--r-- | gtk/gtkimhtml.c | 76 | ||||
-rw-r--r-- | gtk/gtkimhtml.h | 32 | ||||
-rw-r--r-- | gtk/gtkutils.c | 24 | ||||
-rw-r--r-- | gtk/gtkutils.h | 9 |
5 files changed, 137 insertions, 6 deletions
diff --git a/gtk/gtkblist.c b/gtk/gtkblist.c index 6ca2a326ec..c3bb553863 100644 --- a/gtk/gtkblist.c +++ b/gtk/gtkblist.c @@ -3807,6 +3807,7 @@ reset_headline(GaimGtkBuddyList *gtkblist) gtkblist->headline_callback = NULL; gtkblist->headline_data = NULL; gtkblist->headline_destroy = NULL; + gaim_gtk_set_urgent(gtkblist->window->window, FALSE); } static gboolean @@ -5707,6 +5708,7 @@ gaim_gtk_blist_set_headline(const char *text, GdkPixbuf *pixbuf, GCallback callb gtkblist->headline_callback = callback; gtkblist->headline_data = user_data; gtkblist->headline_destroy = destroy; + gaim_gtk_set_urgent(gtkblist->window->window, TRUE); gtk_widget_show_all(gtkblist->headline_hbox); } diff --git a/gtk/gtkimhtml.c b/gtk/gtkimhtml.c index 58e7bc1109..2014fbc3a3 100644 --- a/gtk/gtkimhtml.c +++ b/gtk/gtkimhtml.c @@ -1215,7 +1215,13 @@ gtk_imhtml_finalize (GObject *object) g_free(imhtml->clipboard_text_string); g_free(imhtml->clipboard_html_string); } + + for (l = imhtml->anchors; l; l = l->next) { + GtkIMHtmlAnchor *anchor = l->data; + gtk_imhtml_anchor_free(anchor); + } + g_slist_free(imhtml->anchors); g_list_free(imhtml->scalables); g_slist_free(imhtml->im_images); g_free(imhtml->protocol_name); @@ -2362,6 +2368,7 @@ static gboolean set_adj_idle_cb(gpointer data) { GtkIMHtml *imhtml = data; + gtk_adjustment_set_value(GTK_TEXT_VIEW(imhtml)->vadjustment, imhtml->adj); return FALSE; } @@ -2373,6 +2380,7 @@ void gtk_imhtml_insert_html_at_iter(GtkIMHtml *imhtml, { GdkRectangle rect; GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; + GSList *anchors; gint pos = 0; gchar *ws; gchar *tag; @@ -2383,6 +2391,7 @@ void gtk_imhtml_insert_html_at_iter(GtkIMHtml *imhtml, const gchar *c; gchar *amp; gint len_protocol; + gboolean refocus = GTK_WIDGET_HAS_FOCUS(imhtml); guint bold = 0, @@ -2395,7 +2404,6 @@ void gtk_imhtml_insert_html_at_iter(GtkIMHtml *imhtml, pre = 0; gboolean br = FALSE; - GSList *fonts = NULL; GObject *object; GtkIMHtmlScalable *scalable = NULL; @@ -2409,6 +2417,17 @@ void gtk_imhtml_insert_html_at_iter(GtkIMHtml *imhtml, ws[0] = 0; imhtml->adj = gtk_adjustment_get_value(adj); + + for (anchors = imhtml->anchors; anchors; anchors = anchors->next) { + GtkIMHtmlAnchor *anchor = anchors->data; + if (gtk_text_child_anchor_get_deleted(anchor->anchor)) { + imhtml->anchors = g_slist_remove(imhtml->anchors, anchor); + gtk_imhtml_anchor_free(anchor); + continue; + } + gtk_container_remove(GTK_CONTAINER(imhtml), anchor->widget); + + } gtk_widget_hide(GTK_WIDGET(imhtml)); gtk_widget_unrealize(GTK_WIDGET(imhtml)); gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->empty_buffer); @@ -3070,10 +3089,18 @@ void gtk_imhtml_insert_html_at_iter(GtkIMHtml *imhtml, gtk_imhtml_close_tags(imhtml, iter); gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); + for (anchors = imhtml->anchors; anchors; anchors = anchors->next) { + GtkIMHtmlAnchor *anchor = anchors->data; + gtk_imhtml_add_anchor(imhtml, anchor); + } + object = g_object_ref(G_OBJECT(imhtml)); gtk_widget_realize(GTK_WIDGET(imhtml)); gtk_widget_show_all(GTK_WIDGET(imhtml)); - object = g_object_ref(G_OBJECT(imhtml)); - g_idle_add(set_adj_idle_cb, imhtml); + g_idle_add_full(G_PRIORITY_HIGH_IDLE, set_adj_idle_cb, imhtml, NULL); + if (refocus){ + printf("refocusing\n"); + gtk_widget_grab_focus(GTK_WIDGET(imhtml)); + } g_signal_emit(object, signals[UPDATE_FORMAT], 0); g_object_unref(object); } @@ -3466,6 +3493,7 @@ void gtk_imhtml_image_free(GtkIMHtmlScalable *scale) void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) { + GtkIMHtmlAnchor *ianchor; GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; GtkWidget *box = gtk_event_box_new(); char *tag; @@ -3483,7 +3511,9 @@ void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTex g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", tag, g_free); g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "[Image]"); - gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), box, anchor); + ianchor = gtk_imhtml_anchor_new(anchor, box); + imhtml->anchors = g_slist_append(imhtml->anchors, ianchor); + g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), image); } @@ -3509,11 +3539,13 @@ void gtk_imhtml_hr_scale(GtkIMHtmlScalable *scale, int width, int height) void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) { + GtkIMHtmlAnchor *ianchor; GtkIMHtmlHr *hr = (GtkIMHtmlHr *)scale; GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); g_object_set_data(G_OBJECT(anchor), "gtkimhtml_htmltext", "<hr>"); g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "\n---\n"); - gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), hr->sep, anchor); + ianchor = gtk_imhtml_anchor_new(anchor, hr->sep); + imhtml->anchors = g_slist_append(imhtml->anchors, ianchor); } void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale) @@ -3521,6 +3553,36 @@ void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale) g_free(scale); } +GtkIMHtmlAnchor *gtk_imhtml_anchor_new(GtkTextChildAnchor *anchor, GtkWidget *widget) +{ + GtkIMHtmlAnchor *a = g_new0(GtkIMHtmlAnchor, 1); + a->anchor = anchor; + a->widget = widget; + + g_object_ref(anchor); + g_object_ref(widget); + + return a; +} + +void gtk_imhtml_anchor_free(GtkIMHtmlAnchor *anchor) +{ + g_object_unref(anchor->anchor); + g_object_unref(anchor->widget); + g_free(anchor); +} + +void gtk_imhtml_add_anchor(GtkIMHtml *imhtml, GtkIMHtmlAnchor *anchor) +{ + if (gtk_text_child_anchor_get_deleted(anchor->anchor)) { + imhtml->anchors = g_slist_remove(imhtml->anchors, anchor); + gtk_imhtml_anchor_free(anchor); + return; + } + + gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), anchor->widget, anchor->anchor); +} + gboolean gtk_imhtml_search_find(GtkIMHtml *imhtml, const gchar *text) { GtkTextIter iter, start, end; @@ -4470,6 +4532,7 @@ void gtk_imhtml_insert_smiley_at_iter(GtkIMHtml *imhtml, const char *sml, char * } if (icon) { + GtkIMHtmlAnchor *ianchor; anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", g_strdup(unescaped), g_free); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free); @@ -4481,7 +4544,8 @@ void gtk_imhtml_insert_smiley_at_iter(GtkIMHtml *imhtml, const char *sml, char * g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL); gtk_widget_show(icon); - gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); + ianchor = gtk_imhtml_anchor_new(anchor, icon); + imhtml->anchors = g_slist_append(imhtml->anchors, ianchor); } else if (imhtml_smiley != NULL && (imhtml->format_functions & GTK_IMHTML_SMILEY)) { anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, anchor); diff --git a/gtk/gtkimhtml.h b/gtk/gtkimhtml.h index 3900163ebf..2baf049663 100644 --- a/gtk/gtkimhtml.h +++ b/gtk/gtkimhtml.h @@ -53,6 +53,7 @@ typedef struct _GtkIMHtmlScalable GtkIMHtmlScalable; typedef struct _GtkIMHtmlImage GtkIMHtmlImage; typedef struct _GtkIMHtmlHr GtkIMHtmlHr; typedef struct _GtkIMHtmlFuncs GtkIMHtmlFuncs; +typedef struct _GtkIMHtmlAnchor GtkIMHtmlAnchor; typedef enum { GTK_IMHTML_BOLD = 1 << 0, @@ -125,6 +126,7 @@ struct _GtkIMHtml { char *clipboard_html_string; GSList *im_images; + GSList *anchors; GtkIMHtmlFuncs *funcs; }; @@ -190,6 +192,11 @@ struct _GtkIMHtmlHr { GtkWidget *sep; }; +struct _GtkIMHtmlAnchor { + GtkTextChildAnchor *anchor; + GtkWidget *widget; +}; + typedef enum { GTK_IMHTML_NO_COLOURS = 1 << 0, GTK_IMHTML_NO_FONTS = 1 << 1, @@ -474,6 +481,31 @@ void gtk_imhtml_hr_scale(GtkIMHtmlScalable *scale, int width, int height); void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter); /** + * Creates a new anchor for GTK+ widgets, taking care of reference counting + * + * @param anchor The GtkTextChildAnchor + * @param widget The GtkWidget + * + * @return The GtkIMHtmlAnchor + */ +GtkIMHtmlAnchor *gtk_imhtml_anchor_new(GtkTextChildAnchor *anchor, GtkWidget *widget); + +/** + * Frees an anchor, taking care of refcounting + * + * @param anchor The anchor + */ +void gtk_imhtml_anchor_free(GtkIMHtmlAnchor *anchor); + +/** + * Associates an anchor with an imhtml + * + * @param imhtml The IMHTML to associate with. + * @param anchor The anchor to associate + */ +void gtk_imhtml_add_anchor(GtkIMHtml *imhtml, GtkIMHtmlAnchor *anchor); + +/** * Finds and highlights a given string in a GTK+ IM/HTML. * * @param imhtml The GTK+ IM/HTML. diff --git a/gtk/gtkutils.c b/gtk/gtkutils.c index 59f20f130f..4d3f736f0c 100644 --- a/gtk/gtkutils.c +++ b/gtk/gtkutils.c @@ -2876,6 +2876,30 @@ char *gaim_gtk_make_pretty_arrows(const char *str) return ret; } +void gaim_gtk_set_urgent(GdkWindow *window, gboolean urgent) +{ +#ifdef _WIN32 +#error Hey, Daniel! Make this work! +#else + XWMHints *hints; + + g_return_if_fail(window != NULL); + + hints = XGetWMHints(GDK_WINDOW_XDISPLAY(window), + GDK_WINDOW_XWINDOW(window)); + if(!hints) + hints = XAllocWMHints(); + + if (urgent) + hints->flags |= XUrgencyHint; + else + hints->flags &= ~XUrgencyHint; + XSetWMHints(GDK_WINDOW_XDISPLAY(window), + GDK_WINDOW_XWINDOW(window), hints); + XFree(hints); +#endif +} + GSList *minidialogs = NULL; static void * diff --git a/gtk/gtkutils.h b/gtk/gtkutils.h index 2188565ff7..8e317a5a59 100644 --- a/gtk/gtkutils.h +++ b/gtk/gtkutils.h @@ -533,6 +533,15 @@ void *gaim_gtk_make_mini_dialog(GaimConnection *handle, const char* stock_id, gboolean gaim_gtk_tree_view_search_equal_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer data); +/** + * Sets or resets a window to 'urgent,' by setting the URGENT hint in X + * or blinking in the win32 taskbar + * + * @param window The window to draw attention to + * @param urgent Whether to set the urgent hint or not + */ +void gaim_gtk_set_urgent(GdkWindow *window, gboolean urgent); + #if !GTK_CHECK_VERSION(2,2,0) /** * This is copied from Gtk to support Gtk 2.0 |