summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Egan <seanegan@pidgin.im>2007-01-16 02:48:36 +0000
committerSean Egan <seanegan@pidgin.im>2007-01-16 02:48:36 +0000
commitf0f23c2822188c79a8d7cffd138fc7fa7f2ad123 (patch)
tree46cb2c2df9c51feab8529c791aa221e755f44635
parent2992f659cebb7e52b2fa446944715cf1121c0055 (diff)
downloadpidgin-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.c2
-rw-r--r--gtk/gtkimhtml.c76
-rw-r--r--gtk/gtkimhtml.h32
-rw-r--r--gtk/gtkutils.c24
-rw-r--r--gtk/gtkutils.h9
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