changeset 17455:2e1131c31941

Maintain global poitners to the clipboard selection text, with the aim of keeping that selection from disappearing when the widget is destroyed. The GtkTextView destructor gives up the clipboard selection, so I have to grab it back after calling the destructor. I don't care for that hack. I don't know how this effects Windows Fixes #391
author Sean Egan <seanegan@gmail.com>
date Sun, 03 Jun 2007 19:15:42 +0000
parents 8223df108932
children 1a98c57c9746 e1cb3ec4ceb6 677a57f12e28
files pidgin/gtkimhtml.c
diffstat 1 files changed, 43 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/gtkimhtml.c	Sun Jun 03 18:56:55 2007 +0000
+++ b/pidgin/gtkimhtml.c	Sun Jun 03 19:15:42 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 */