# HG changeset patch # User Stu Tomlinson # Date 1180920637 0 # Node ID e1cb3ec4ceb6c76f634a504b5b46a8d97fcc59be # Parent 2e1131c31941090b26322f519b58facf68c56f40# Parent 486daeb90aa9ea73795ee1c7d6bffab2f855b90d merge of '4ced433906d17bb2758a2b010ce264314d17fe04' and '876a32332db2efa993b1f6461d35e6e686c6715a' diff -r 486daeb90aa9 -r e1cb3ec4ceb6 pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Mon Jun 04 01:30:13 2007 +0000 +++ b/pidgin/gtkimhtml.c Mon Jun 04 01:30:37 2007 +0000 @@ -140,6 +140,10 @@ }; static guint signals [LAST_SIGNAL] = { 0 }; +static char *html_clipboard = NULL; +static char *text_clipboard = NULL; +GtkClipboard *clipboard_selection = NULL; + static GtkTargetEntry selection_targets[] = { #ifndef _WIN32 { "text/html", 0, TARGET_HTML }, @@ -871,14 +875,17 @@ static void gtk_imhtml_clipboard_get(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, GtkIMHtml *imhtml) { char *text = NULL; - gboolean primary; + gboolean primary = (clipboard != clipboard_selection); GtkTextIter start, end; - GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); - GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); - - gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, sel); - gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &end, ins); - primary = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY) == clipboard; + GtkTextMark *sel = NULL; + GtkTextMark *ins = NULL; + + if (primary) { + ins = gtk_text_buffer_get_insert(imhtml->text_buffer); + sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); + gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, sel); + gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &end, ins); + } if (info == TARGET_HTML) { char *selection; @@ -888,7 +895,7 @@ if (primary) { text = gtk_imhtml_get_markup_range(imhtml, &start, &end); } else - text = imhtml->clipboard_html_string; + text = html_clipboard; /* Mozilla asks that we start our text/html with the Unicode byte order mark */ str = g_string_append_unichar(str, 0xfeff); @@ -906,7 +913,7 @@ if (primary) { text = gtk_imhtml_get_text(imhtml, &start, &end); } else - text = imhtml->clipboard_text_string; + text = text_clipboard; gtk_selection_data_set_text(selection_data, text, strlen(text)); } if (primary) /* This was allocated here */ @@ -929,20 +936,32 @@ &insert); } +static void gtk_imhtml_clipboard_clear (GtkClipboard *clipboard, GtkSelectionData *sel_data, + guint info, gpointer user_data_or_owner) +{ + clipboard_selection = NULL; +} + static void copy_clipboard_cb(GtkIMHtml *imhtml, gpointer unused) { GtkTextIter start, end; if (gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { - gtk_clipboard_set_with_owner(gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD), + if (!clipboard_selection) + clipboard_selection = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_with_owner(clipboard_selection, selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry), (GtkClipboardGetFunc)gtk_imhtml_clipboard_get, - (GtkClipboardClearFunc)NULL, G_OBJECT(imhtml)); + (GtkClipboardClearFunc)gtk_imhtml_clipboard_clear, G_OBJECT(imhtml)); g_free(imhtml->clipboard_html_string); g_free(imhtml->clipboard_text_string); imhtml->clipboard_html_string = gtk_imhtml_get_markup_range(imhtml, &start, &end); imhtml->clipboard_text_string = gtk_imhtml_get_text(imhtml, &start, &end); + + text_clipboard = imhtml->clipboard_text_string; + html_clipboard = imhtml->clipboard_html_string; + } g_signal_stop_emission_by_name(imhtml, "copy-clipboard"); @@ -952,10 +971,12 @@ { GtkTextIter start, end; if (gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, &start, &end)) { - gtk_clipboard_set_with_owner(gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD), + if (!clipboard_selection) + clipboard_selection = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_with_owner(clipboard_selection, selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry), (GtkClipboardGetFunc)gtk_imhtml_clipboard_get, - (GtkClipboardClearFunc)NULL, G_OBJECT(imhtml)); + (GtkClipboardClearFunc)gtk_imhtml_clipboard_clear, G_OBJECT(imhtml)); g_free(imhtml->clipboard_html_string); g_free(imhtml->clipboard_text_string); @@ -963,6 +984,9 @@ imhtml->clipboard_html_string = gtk_imhtml_get_markup_range(imhtml, &start, &end); imhtml->clipboard_text_string = gtk_imhtml_get_text(imhtml, &start, &end); + text_clipboard = imhtml->clipboard_text_string; + html_clipboard = imhtml->clipboard_html_string; + if (imhtml->editable) gtk_text_buffer_delete_selection(imhtml->text_buffer, FALSE, FALSE); } @@ -1199,17 +1223,18 @@ g_free(img_data); } - if (imhtml->clipboard_text_string) { - g_free(imhtml->clipboard_text_string); - g_free(imhtml->clipboard_html_string); - } - g_list_free(imhtml->scalables); g_slist_free(imhtml->im_images); g_queue_free(imhtml->animations); g_free(imhtml->protocol_name); g_free(imhtml->search_string); G_OBJECT_CLASS(parent_class)->finalize (object); + if (clipboard_selection) + gtk_clipboard_set_with_owner(clipboard_selection, + selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry), + (GtkClipboardGetFunc)gtk_imhtml_clipboard_get, + (GtkClipboardClearFunc)NULL, G_OBJECT(imhtml)); + } /* Boring GTK+ stuff */