diff options
-rw-r--r-- | demos/widget-factory/widget-factory.c | 12 | ||||
-rw-r--r-- | examples/bp/bloatpad.c | 10 | ||||
-rw-r--r-- | examples/plugman.c | 10 | ||||
-rw-r--r-- | gtk/gtktextbuffer.c | 732 | ||||
-rw-r--r-- | gtk/gtktextbuffer.h | 18 | ||||
-rw-r--r-- | gtk/gtktextview.c | 145 | ||||
-rw-r--r-- | testsuite/gtk/textbuffer.c | 4 |
7 files changed, 373 insertions, 558 deletions
diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c index 3de7bd47a8..74022ec7c6 100644 --- a/demos/widget-factory/widget-factory.c +++ b/demos/widget-factory/widget-factory.c @@ -1232,10 +1232,10 @@ static void handle_cutcopypaste (GtkWidget *button, GtkWidget *textview) { GtkTextBuffer *buffer; - GtkClipboard *clipboard; + GdkClipboard *clipboard; const gchar *id; - clipboard = gtk_widget_get_old_clipboard (textview, GDK_SELECTION_CLIPBOARD); + clipboard = gtk_widget_get_clipboard (textview); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); id = gtk_buildable_get_name (GTK_BUILDABLE (button)); @@ -1250,13 +1250,13 @@ handle_cutcopypaste (GtkWidget *button, GtkWidget *textview) } static void -clipboard_owner_change (GtkClipboard *clipboard, GdkEvent *event, GtkWidget *button) +clipboard_formats_notify (GdkClipboard *clipboard, GdkEvent *event, GtkWidget *button) { const gchar *id; gboolean has_text; id = gtk_buildable_get_name (GTK_BUILDABLE (button)); - has_text = gtk_clipboard_wait_is_text_available (clipboard); + has_text = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_TEXT_BUFFER); if (strcmp (id, "pastebutton") == 0) gtk_widget_set_sensitive (button, has_text); @@ -1837,8 +1837,8 @@ activate (GApplication *app) G_CALLBACK (textbuffer_notify_selection), widget); widget = (GtkWidget *)gtk_builder_get_object (builder, "pastebutton"); g_signal_connect (widget, "clicked", G_CALLBACK (handle_cutcopypaste), widget2); - g_signal_connect_object (gtk_widget_get_old_clipboard (widget2, GDK_SELECTION_CLIPBOARD), "owner-change", - G_CALLBACK (clipboard_owner_change), widget, 0); + g_signal_connect_object (gtk_widget_get_clipboard (widget2), "notify::formats", + G_CALLBACK (clipboard_formats_notify), widget, 0); widget = (GtkWidget *)gtk_builder_get_object (builder, "osd_frame"); widget2 = (GtkWidget *)gtk_builder_get_object (builder, "totem_like_osd"); diff --git a/examples/bp/bloatpad.c b/examples/bp/bloatpad.c index 5a52f92d57..78ca433add 100644 --- a/examples/bp/bloatpad.c +++ b/examples/bp/bloatpad.c @@ -93,12 +93,6 @@ change_justify_state (GSimpleAction *action, g_simple_action_set_state (action, state); } -static GtkClipboard * -get_clipboard (GtkWidget *widget) -{ - return gtk_widget_get_old_clipboard (widget, gdk_atom_intern_static_string ("CLIPBOARD")); -} - static void window_copy (GSimpleAction *action, GVariant *parameter, @@ -108,7 +102,7 @@ window_copy (GSimpleAction *action, GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text"); gtk_text_buffer_copy_clipboard (gtk_text_view_get_buffer (text), - get_clipboard ((GtkWidget*) text)); + gtk_widget_get_clipboard (GTK_WIDGET (text))); } static void @@ -120,7 +114,7 @@ window_paste (GSimpleAction *action, GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text"); gtk_text_buffer_paste_clipboard (gtk_text_view_get_buffer (text), - get_clipboard ((GtkWidget*) text), + gtk_widget_get_clipboard (GTK_WIDGET (text)), NULL, TRUE); diff --git a/examples/plugman.c b/examples/plugman.c index 8605587779..67d7960c5d 100644 --- a/examples/plugman.c +++ b/examples/plugman.c @@ -38,12 +38,6 @@ change_fullscreen_state (GSimpleAction *action, g_simple_action_set_state (action, state); } -static GtkClipboard * -get_clipboard (GtkWidget *widget) -{ - return gtk_widget_get_old_clipboard (widget, gdk_atom_intern_static_string ("CLIPBOARD")); -} - static void window_copy (GSimpleAction *action, GVariant *parameter, @@ -53,7 +47,7 @@ window_copy (GSimpleAction *action, GtkTextView *text = g_object_get_data ((GObject*)window, "plugman-text"); gtk_text_buffer_copy_clipboard (gtk_text_view_get_buffer (text), - get_clipboard ((GtkWidget*) text)); + gtk_widget_get_clipboard (GTK_WIDGET (text))); } static void @@ -65,7 +59,7 @@ window_paste (GSimpleAction *action, GtkTextView *text = g_object_get_data ((GObject*)window, "plugman-text"); gtk_text_buffer_paste_clipboard (gtk_text_view_get_buffer (text), - get_clipboard ((GtkWidget*) text), + gtk_widget_get_clipboard (GTK_WIDGET (text)), NULL, TRUE); diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c index 620ac499ea..b7d18056a9 100644 --- a/gtk/gtktextbuffer.c +++ b/gtk/gtktextbuffer.c @@ -27,7 +27,6 @@ #include <string.h> #include <stdarg.h> -#include "gtkclipboard.h" #include "gtkdnd.h" #include "gtkinvisible.h" #include "gtkmarshalers.h" @@ -55,14 +54,11 @@ typedef struct _GtkTextLogAttrCache GtkTextLogAttrCache; struct _GtkTextBufferPrivate { - GdkContentFormats *copy_target_list; - GdkContentFormats *paste_target_list; - GtkTextTagTable *tag_table; GtkTextBTree *btree; - GSList *clipboard_contents_buffers; GSList *selection_clipboards; + GdkContentProvider *selection_content; GtkTextLogAttrCache *log_attr_cache; @@ -149,10 +145,6 @@ static void free_log_attr_cache (GtkTextLogAttrCache *cache); static void remove_all_selection_clipboards (GtkTextBuffer *buffer); static void update_selection_clipboards (GtkTextBuffer *buffer); -static GtkTextBuffer *create_clipboard_contents_buffer (GtkTextBuffer *buffer); - -static void gtk_text_buffer_free_target_lists (GtkTextBuffer *buffer); - static void gtk_text_buffer_set_property (GObject *object, guint prop_id, const GValue *value, @@ -161,14 +153,239 @@ static void gtk_text_buffer_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void gtk_text_buffer_notify (GObject *object, - GParamSpec *pspec); static guint signals[LAST_SIGNAL] = { 0 }; static GParamSpec *text_buffer_props[LAST_PROP]; G_DEFINE_TYPE_WITH_PRIVATE (GtkTextBuffer, gtk_text_buffer, G_TYPE_OBJECT) +#define GTK_TYPE_TEXT_BUFFER_CONTENT (gtk_text_buffer_content_get_type ()) +#define GTK_TEXT_BUFFER_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TEXT_BUFFER_CONTENT, GtkTextBufferContent)) +#define GTK_IS_TEXT_BUFFER_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TEXT_BUFFER_CONTENT)) +#define GTK_TEXT_BUFFER_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_BUFFER_CONTENT, GtkTextBufferContentClass)) +#define GTK_IS_TEXT_BUFFER_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TEXT_BUFFER_CONTENT)) +#define GTK_TEXT_BUFFER_CONTENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TEXT_BUFFER_CONTENT, GtkTextBufferContentClass)) + +typedef struct _GtkTextBufferContent GtkTextBufferContent; +typedef struct _GtkTextBufferContentClass GtkTextBufferContentClass; + +struct _GtkTextBufferContent +{ + GdkContentProvider parent; + + GtkTextBuffer *text_buffer; +}; + +struct _GtkTextBufferContentClass +{ + GdkContentProviderClass parent_class; +}; + +GType gtk_text_buffer_content_get_type (void) G_GNUC_CONST; + +G_DEFINE_TYPE (GtkTextBufferContent, gtk_text_buffer_content, GDK_TYPE_CONTENT_PROVIDER) + +static GdkContentFormats * +gtk_text_buffer_content_ref_formats (GdkContentProvider *provider) +{ + GtkTextBufferContent *content = GTK_TEXT_BUFFER_CONTENT (provider); + + if (content->text_buffer) + return gdk_content_formats_new_for_gtype (GTK_TYPE_TEXT_BUFFER); + else + return gdk_content_formats_new (NULL, 0); +} + +static gboolean +gtk_text_buffer_content_get_value (GdkContentProvider *provider, + GValue *value, + GError **error) +{ + GtkTextBufferContent *content = GTK_TEXT_BUFFER_CONTENT (provider); + + if (G_VALUE_HOLDS (value, GTK_TYPE_TEXT_BUFFER) && + content->text_buffer != NULL) + { + g_value_set_object (value, content->text_buffer); + return TRUE; + } + + return GDK_CONTENT_PROVIDER_CLASS (gtk_text_buffer_content_parent_class)->get_value (provider, value, error); +} + +static void +gtk_text_buffer_content_detach (GdkContentProvider *provider, + GdkClipboard *clipboard) +{ + GtkTextBufferContent *content = GTK_TEXT_BUFFER_CONTENT (provider); + GtkTextIter insert; + GtkTextIter selection_bound; + + if (content->text_buffer == NULL) + return; + + /* Move selection_bound to the insertion point */ + gtk_text_buffer_get_iter_at_mark (content->text_buffer, &insert, + gtk_text_buffer_get_insert (content->text_buffer)); + gtk_text_buffer_get_iter_at_mark (content->text_buffer, &selection_bound, + gtk_text_buffer_get_selection_bound (content->text_buffer)); + + if (!gtk_text_iter_equal (&insert, &selection_bound)) + gtk_text_buffer_move_mark (content->text_buffer, + gtk_text_buffer_get_selection_bound (content->text_buffer), + &insert); +} + +static void +gtk_text_buffer_content_class_init (GtkTextBufferContentClass *class) +{ + GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class); + + provider_class->ref_formats = gtk_text_buffer_content_ref_formats; + provider_class->get_value = gtk_text_buffer_content_get_value; + provider_class->detach_clipboard = gtk_text_buffer_content_detach; +} + +static void +gtk_text_buffer_content_init (GtkTextBufferContent *content) +{ +} + +static GdkContentProvider * +gtk_text_buffer_content_new (GtkTextBuffer *buffer) +{ + GtkTextBufferContent *content; + + content = g_object_new (GTK_TYPE_TEXT_BUFFER_CONTENT, NULL); + content->text_buffer = g_object_ref (buffer); + + return GDK_CONTENT_PROVIDER (content); +} + +static void +gtk_text_buffer_deserialize_text_plain_finish (GObject *source, + GAsyncResult *result, + gpointer deserializer) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source); + GtkTextBuffer *buffer; + GtkTextIter start, end; + GError *error = NULL; + gssize written; + + written = g_output_stream_splice_finish (stream, result, &error); + if (written < 0) + { + gdk_content_deserializer_return_error (deserializer, error); + return; + } + + buffer = g_value_get_object (gdk_content_deserializer_get_value (deserializer)); + gtk_text_buffer_get_end_iter (buffer, &end); + gtk_text_buffer_insert (buffer, + &end, + g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM ( + g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (stream)))), + -1); + gtk_text_buffer_get_bounds (buffer, &start, &end); + gtk_text_buffer_select_range (buffer, &start, &end); + + gdk_content_deserializer_return_success (deserializer); +} + +static void +gtk_text_buffer_deserialize_text_plain (GdkContentDeserializer *deserializer) +{ + GOutputStream *output, *filter; + GCharsetConverter *converter; + GtkTextBuffer *buffer; + GError *error = NULL; + + buffer = gtk_text_buffer_new (NULL); + g_value_set_object (gdk_content_deserializer_get_value (deserializer), + buffer); + + /* validates the stream */ + converter = g_charset_converter_new ("utf-8", "utf-8", &error); + if (converter == NULL) + { + gdk_content_deserializer_return_error (deserializer, error); + return; + } + g_charset_converter_set_use_fallback (converter, TRUE); + + output = g_memory_output_stream_new_resizable (); + filter = g_converter_output_stream_new (output, G_CONVERTER (converter)); + g_object_unref (output); + g_object_unref (converter); + + g_output_stream_splice_async (filter, + gdk_content_deserializer_get_input_stream (deserializer), + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + gdk_content_deserializer_get_priority (deserializer), + gdk_content_deserializer_get_cancellable (deserializer), + gtk_text_buffer_deserialize_text_plain_finish, + deserializer); + g_object_unref (filter); +} + +static void +gtk_text_buffer_serialize_text_plain_finish (GObject *source, + GAsyncResult *result, + gpointer serializer) +{ + GOutputStream *stream = G_OUTPUT_STREAM (source); + GError *error = NULL; + + if (!g_output_stream_write_all_finish (stream, result, NULL, &error)) + gdk_content_serializer_return_error (serializer, error); + else + gdk_content_serializer_return_success (serializer); +} + +static void +gtk_text_buffer_serialize_text_plain (GdkContentSerializer *serializer) +{ + GtkTextBuffer *buffer; + GtkTextIter start, end; + char *str; + + buffer = g_value_get_object (gdk_content_serializer_get_value (serializer)); + + if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) + { + str = gtk_text_iter_get_visible_text (&start, &end); + } + else + { + str = g_strdup (""); + } + gdk_content_serializer_set_task_data (serializer, str, g_free); + + g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer), + str, + strlen (str) + 1, + gdk_content_serializer_get_priority (serializer), + gdk_content_serializer_get_cancellable (serializer), + gtk_text_buffer_serialize_text_plain_finish, + serializer); +} + +static void +gtk_text_buffer_register_serializers (void) +{ + gdk_content_register_deserializer ("text/plain;charset=utf-8", + GTK_TYPE_TEXT_BUFFER, + gtk_text_buffer_deserialize_text_plain, + NULL, + NULL); + gdk_content_register_serializer (GTK_TYPE_TEXT_BUFFER, + "text/plain;charset=utf-8", + gtk_text_buffer_serialize_text_plain, + NULL, + NULL); +} + static void gtk_text_buffer_class_init (GtkTextBufferClass *klass) { @@ -177,7 +394,6 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass) object_class->finalize = gtk_text_buffer_finalize; object_class->set_property = gtk_text_buffer_set_property; object_class->get_property = gtk_text_buffer_get_property; - object_class->notify = gtk_text_buffer_notify; klass->insert_text = gtk_text_buffer_real_insert_text; klass->insert_texture = gtk_text_buffer_real_insert_texture; @@ -617,7 +833,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass) /** * GtkTextBuffer::paste-done: * @textbuffer: the object which received the signal - * @clipboard: the #GtkClipboard pasted from + * @clipboard: the #GdkClipboard pasted from * * The paste-done signal is emitted after paste operation has been completed. * This is useful to properly scroll the view to the end of the pasted text. @@ -634,14 +850,15 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass) NULL, G_TYPE_NONE, 1, - GTK_TYPE_CLIPBOARD); + GDK_TYPE_CLIPBOARD); + + gtk_text_buffer_register_serializers (); } static void gtk_text_buffer_init (GtkTextBuffer *buffer) { buffer->priv = gtk_text_buffer_get_instance_private (buffer); - buffer->priv->clipboard_contents_buffers = NULL; buffer->priv->tag_table = NULL; } @@ -741,31 +958,12 @@ gtk_text_buffer_get_property (GObject *object, g_value_set_int (value, gtk_text_iter_get_offset (&iter)); break; - case PROP_COPY_TARGET_LIST: - g_value_set_boxed (value, gtk_text_buffer_get_copy_target_list (text_buffer)); - break; - - case PROP_PASTE_TARGET_LIST: - g_value_set_boxed (value, gtk_text_buffer_get_paste_target_list (text_buffer)); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } -static void -gtk_text_buffer_notify (GObject *object, - GParamSpec *pspec) -{ - if (!strcmp (pspec->name, "copy-target-list") || - !strcmp (pspec->name, "paste-target-list")) - { - gtk_text_buffer_free_target_lists (GTK_TEXT_BUFFER (object)); - } -} - /** * gtk_text_buffer_new: * @table: (allow-none): a tag table, or %NULL to create a new one @@ -813,8 +1011,6 @@ gtk_text_buffer_finalize (GObject *object) priv->log_attr_cache = NULL; - gtk_text_buffer_free_target_lists (buffer); - G_OBJECT_CLASS (gtk_text_buffer_parent_class)->finalize (object); } @@ -3170,74 +3366,20 @@ gtk_text_buffer_get_char_count (GtkTextBuffer *buffer) return _gtk_text_btree_char_count (get_btree (buffer)); } -/* Called when we lose the primary selection. - */ -static void -clipboard_clear_selection_cb (GtkClipboard *clipboard, - gpointer data) -{ - /* Move selection_bound to the insertion point */ - GtkTextIter insert; - GtkTextIter selection_bound; - GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data); - - gtk_text_buffer_get_iter_at_mark (buffer, &insert, - gtk_text_buffer_get_insert (buffer)); - gtk_text_buffer_get_iter_at_mark (buffer, &selection_bound, - gtk_text_buffer_get_selection_bound (buffer)); - - if (!gtk_text_iter_equal (&insert, &selection_bound)) - gtk_text_buffer_move_mark (buffer, - gtk_text_buffer_get_selection_bound (buffer), - &insert); -} - -/* Called when we have the primary selection and someone else wants our - * data in order to paste it. - */ -static void -clipboard_get_selection_cb (GtkClipboard *clipboard, - GtkSelectionData *selection_data, - gpointer data) -{ - GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data); - GtkTextIter start, end; - - if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) - { - if (gtk_selection_data_get_target (selection_data) == gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS")) - { - /* Provide the address of the buffer; this will only be - * used within-process - */ - gtk_selection_data_set (selection_data, - gtk_selection_data_get_target (selection_data), - 8, /* bytes */ - (void*)&buffer, - sizeof (buffer)); - } - else if (gtk_selection_data_targets_include_text (selection_data)) - { - gchar *str; - - str = gtk_text_iter_get_visible_text (&start, &end); - gtk_selection_data_set_text (selection_data, str, -1); - g_free (str); - } - } -} - static GtkTextBuffer * -create_clipboard_contents_buffer (GtkTextBuffer *buffer) +create_clipboard_contents_buffer (GtkTextBuffer *buffer, + GtkTextIter *start_iter, + GtkTextIter *end_iter) { + GtkTextIter start, end; GtkTextBuffer *contents; contents = gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer)); - g_object_set_data (G_OBJECT (contents), I_("gtk-text-buffer-clipboard-source"), - buffer); - g_object_set_data (G_OBJECT (contents), I_("gtk-text-buffer-clipboard"), - GINT_TO_POINTER (1)); + gtk_text_buffer_get_iter_at_offset (contents, &start, 0); + gtk_text_buffer_insert_range (contents, &start, start_iter, end_iter); + gtk_text_buffer_get_bounds (contents, &start, &end); + gtk_text_buffer_select_range (contents, &start, &end); /* Ref the source buffer as long as the clipboard contents buffer * exists, because it's needed for serializing the contents buffer. @@ -3249,49 +3391,6 @@ create_clipboard_contents_buffer (GtkTextBuffer *buffer) return contents; } -/* Provide cut/copied data */ -static void -clipboard_get_contents_cb (GtkClipboard *clipboard, - GtkSelectionData *selection_data, - gpointer data) -{ - GtkTextBuffer *contents = GTK_TEXT_BUFFER (data); - - g_assert (contents); /* This should never be called unless we own the clipboard */ - - if (gtk_selection_data_get_target (selection_data) == gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS")) - { - /* Provide the address of the clipboard buffer; this will only - * be used within-process. OK to supply a NULL value for contents. - */ - gtk_selection_data_set (selection_data, - gtk_selection_data_get_target (selection_data), - 8, /* bytes */ - (void*)&contents, - sizeof (contents)); - } - else - { - gchar *str; - GtkTextIter start, end; - - gtk_text_buffer_get_bounds (contents, &start, &end); - - str = gtk_text_iter_get_visible_text (&start, &end); - gtk_selection_data_set_text (selection_data, str, -1); - g_free (str); - } -} - -static void -clipboard_clear_contents_cb (GtkClipboard *clipboard, - gpointer data) -{ - GtkTextBuffer *contents = GTK_TEXT_BUFFER (data); - - g_object_unref (contents); -} - static void get_paste_point (GtkTextBuffer *buffer, GtkTextIter *iter, @@ -3348,7 +3447,7 @@ pre_paste_prep (ClipboardRequest *request_data, static void emit_paste_done (GtkTextBuffer *buffer, - GtkClipboard *clipboard) + GdkClipboard *clipboard) { g_signal_emit (buffer, signals[PASTE_DONE], 0, clipboard); } @@ -3360,90 +3459,6 @@ free_clipboard_request (ClipboardRequest *request_data) g_slice_free (ClipboardRequest, request_data); } -/* Called when we request a paste and receive the text data - */ -static void -clipboard_text_received (GtkClipboard *clipboard, - const gchar *str, - gpointer data) -{ - ClipboardRequest *request_data = data; - GtkTextBuffer *buffer = request_data->buffer; - - if (str) - { - GtkTextIter insert_point; - - if (request_data->interactive) - gtk_text_buffer_begin_user_action (buffer); - - pre_paste_prep (request_data, &insert_point); - - if (request_data->interactive) - gtk_text_buffer_insert_interactive (buffer, &insert_point, - str, -1, request_data->default_editable); - else - gtk_text_buffer_insert (buffer, &insert_point, - str, -1); - - if (request_data->interactive) - gtk_text_buffer_end_user_action (buffer); - - emit_paste_done (buffer, clipboard); - } - else - { - /* It may happen that we set a point override but we are not inserting - any text, so we must remove it afterwards */ - GtkTextMark *paste_point_override; - - paste_point_override = gtk_text_buffer_get_mark (buffer, - "gtk_paste_point_override"); - - if (paste_point_override != NULL) - gtk_text_buffer_delete_mark (buffer, paste_point_override); - } - - free_clipboard_request (request_data); -} - -static GtkTextBuffer* -selection_data_get_buffer (GtkSelectionData *selection_data, - ClipboardRequest *request_data) -{ - GdkWindow *owner; - GtkTextBuffer *src_buffer = NULL; - - /* If we can get the owner, the selection is in-process */ - owner = gdk_selection_owner_get_for_display (gtk_selection_data_get_display (selection_data), - gtk_selection_data_get_selection (selection_data)); - - if (owner == NULL) - return NULL; - - if (gdk_window_get_window_type (owner) == GDK_WINDOW_FOREIGN) - return NULL; - - if (gtk_selection_data_get_data_type (selection_data) != gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS")) - return NULL; - - if (gtk_selection_data_get_length (selection_data) != sizeof (src_buffer)) - return NULL; - - memcpy (&src_buffer, gtk_selection_data_get_data (selection_data), sizeof (src_buffer)); - - if (src_buffer == NULL) - return NULL; - - g_return_val_if_fail (GTK_IS_TEXT_BUFFER (src_buffer), NULL); - - if (gtk_text_buffer_get_tag_table (src_buffer) != - gtk_text_buffer_get_tag_table (request_data->buffer)) - return NULL; - - return src_buffer; -} - #if 0 /* These are pretty handy functions; maybe something like them * should be in the public API. Also, there are other places in this @@ -3472,7 +3487,7 @@ restore_iter (const GtkTextIter *iter, #endif static void -paste_from_buffer (GtkClipboard *clipboard, +paste_from_buffer (GdkClipboard *clipboard, ClipboardRequest *request_data, GtkTextBuffer *src_buffer, const GtkTextIter *start, @@ -3522,45 +3537,30 @@ done: } static void -clipboard_clipboard_buffer_received (GtkClipboard *clipboard, - GtkSelectionData *selection_data, - gpointer data) +gtk_text_buffer_paste_clipboard_finish (GObject *source, + GAsyncResult *result, + gpointer data) { + GdkClipboard *clipboard = GDK_CLIPBOARD (source); ClipboardRequest *request_data = data; GtkTextBuffer *src_buffer; + GtkTextIter start, end; + const GValue *value; - src_buffer = selection_data_get_buffer (selection_data, request_data); - - if (src_buffer) - { - GtkTextIter start, end; + value = gdk_clipboard_read_value_finish (clipboard, result, NULL); + if (value == NULL) + return; - if (g_object_get_data (G_OBJECT (src_buffer), "gtk-text-buffer-clipboard")) - { - gtk_text_buffer_get_bounds (src_buffer, &start, &end); + src_buffer = g_value_get_object (value); - paste_from_buffer (clipboard, request_data, src_buffer, - &start, &end); - } - else - { - if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end)) - paste_from_buffer (clipboard, request_data, src_buffer, - &start, &end); - } - } - else - { - /* Request the text selection instead */ - gtk_clipboard_request_text (clipboard, - clipboard_text_received, - data); - } + if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end)) + paste_from_buffer (clipboard, request_data, src_buffer, + &start, &end); } typedef struct { - GtkClipboard *clipboard; + GdkClipboard *clipboard; guint ref_count; } SelectionClipboard; @@ -3568,43 +3568,45 @@ static void update_selection_clipboards (GtkTextBuffer *buffer) { GtkTextBufferPrivate *priv; - gboolean has_selection; GtkTextIter start; GtkTextIter end; - GSList *tmp_list; + GSList *l; priv = buffer->priv; - gtk_text_buffer_get_copy_target_list (buffer); - has_selection = gtk_text_buffer_get_selection_bounds (buffer, &start, &end); - tmp_list = buffer->priv->selection_clipboards; - - while (tmp_list) + if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) { - SelectionClipboard *selection_clipboard = tmp_list->data; - GtkClipboard *clipboard = selection_clipboard->clipboard; - - if (has_selection) + if (priv->selection_content) + gdk_content_provider_content_changed (priv->selection_content); + else + priv->selection_content = gtk_text_buffer_content_new (buffer); + + for (l = priv->selection_clipboards; l; l = l->next) { - /* Even if we already have the selection, we need to update our - * timestamp. - */ - gtk_clipboard_set_with_owner (clipboard, - priv->copy_target_list, - clipboard_get_selection_cb, - clipboard_clear_selection_cb, - G_OBJECT (buffer)); + SelectionClipboard *selection_clipboard = l->data; + gdk_clipboard_set_content (selection_clipboard->clipboard, priv->selection_content); + } + } + else + { + if (priv->selection_content) + { + GTK_TEXT_BUFFER_CONTENT (priv->selection_content)->text_buffer = NULL; + for (l = priv->selection_clipboards; l; l = l->next) + { + SelectionClipboard *selection_clipboard = l->data; + GdkClipboard *clipboard = selection_clipboard->clipboard; + if (gdk_clipboard_get_content (clipboard) == priv->selection_content) + gdk_clipboard_set_content (clipboard, NULL); + } + g_clear_object (&priv->selection_content); } - else if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (buffer)) - gtk_clipboard_clear (clipboard); - - tmp_list = tmp_list->next; } } static SelectionClipboard * find_selection_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard) + GdkClipboard *clipboard) { GSList *tmp_list = buffer->priv->selection_clipboards; while (tmp_list) @@ -3622,15 +3624,16 @@ find_selection_clipboard (GtkTextBuffer *buffer, /** * gtk_text_buffer_add_selection_clipboard: * @buffer: a #GtkTextBuffer - * @clipboard: a #GtkClipboard + * @clipboard: a #GdkClipboard * * Adds @clipboard to the list of clipboards in which the selection * contents of @buffer are available. In most cases, @clipboard will be - * the #GtkClipboard of type %GDK_SELECTION_PRIMARY for a view of @buffer. + * the #GdkClipboard returned by gdk_widget_get_primary_clipboard() + * for a view of @buffer. **/ void gtk_text_buffer_add_selection_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard) + GdkClipboard *clipboard) { SelectionClipboard *selection_clipboard; @@ -3657,16 +3660,17 @@ gtk_text_buffer_add_selection_clipboard (GtkTextBuffer *buffer, /** * gtk_text_buffer_remove_selection_clipboard: * @buffer: a #GtkTextBuffer - * @clipboard: a #GtkClipboard added to @buffer by + * @clipboard: a #GdkClipboard added to @buffer by * gtk_text_buffer_add_selection_clipboard() * - * Removes a #GtkClipboard added with + * Removes a #GdkClipboard added with * gtk_text_buffer_add_selection_clipboard(). **/ void gtk_text_buffer_remove_selection_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard) + GdkClipboard *clipboard) { + GtkTextBufferPrivate *priv; SelectionClipboard *selection_clipboard; g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer)); @@ -3675,11 +3679,13 @@ gtk_text_buffer_remove_selection_clipboard (GtkTextBuffer *buffer, selection_clipboard = find_selection_clipboard (buffer, clipboard); g_return_if_fail (selection_clipboard != NULL); + priv = buffer->priv; selection_clipboard->ref_count--; if (selection_clipboard->ref_count == 0) { - if (gtk_clipboard_get_owner (selection_clipboard->clipboard) == G_OBJECT (buffer)) - gtk_clipboard_clear (selection_clipboard->clipboard); + if (priv->selection_content && + gdk_clipboard_get_content (clipboard) == priv->selection_content) + gdk_clipboard_set_content (clipboard, NULL); buffer->priv->selection_clipboards = g_slist_remove (buffer->priv->selection_clipboards, selection_clipboard); @@ -3707,7 +3713,7 @@ remove_all_selection_clipboards (GtkTextBuffer *buffer) /** * gtk_text_buffer_paste_clipboard: * @buffer: a #GtkTextBuffer - * @clipboard: the #GtkClipboard to paste from + * @clipboard: the #GdkClipboard to paste from * @override_location: (allow-none): location to insert pasted text, or %NULL * @default_editable: whether the buffer is editable by default * @@ -3721,7 +3727,7 @@ remove_all_selection_clipboards (GtkTextBuffer *buffer) **/ void gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard, + GdkClipboard *clipboard, GtkTextIter *override_location, gboolean default_editable) { @@ -3752,9 +3758,12 @@ gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer, gtk_text_iter_equal (&paste_point, &end))) data->replace_selection = TRUE; - gtk_clipboard_request_contents (clipboard, - gdk_atom_intern_static_string ("GTK_TEXT_BUFFER_CONTENTS"), - clipboard_clipboard_buffer_received, data); + gdk_clipboard_read_value_async (clipboard, + GTK_TYPE_TEXT_BUFFER, + G_PRIORITY_DEFAULT, + NULL, + gtk_text_buffer_paste_clipboard_finish, + data); } /** @@ -3885,44 +3894,12 @@ gtk_text_buffer_backspace (GtkTextBuffer *buffer, } static void -gtk_text_buffer_free_target_lists (GtkTextBuffer *buffer) -{ - GtkTextBufferPrivate *priv = buffer->priv; - - g_clear_pointer (&priv->copy_target_list, gdk_content_formats_unref); - g_clear_pointer (&priv->paste_target_list, gdk_content_formats_unref); -} - -static GdkContentFormats * -gtk_text_buffer_get_target_list (GtkTextBuffer *buffer, - gboolean deserializable, - gboolean include_local) -{ - GdkContentFormats *target_list; - - - if (include_local) - target_list = gdk_content_formats_new ((const char *[2]) { - "GTK_TEXT_BUFFER_CONTENTS", - NULL - }, 1); - else - target_list = gdk_content_formats_new (NULL, 0); - - target_list = gtk_content_formats_add_text_targets (target_list); - - return target_list; -} - -static void cut_or_copy (GtkTextBuffer *buffer, - GtkClipboard *clipboard, + GdkClipboard *clipboard, gboolean delete_region_after, gboolean interactive, gboolean default_editable) { - GtkTextBufferPrivate *priv; - /* We prefer to cut the selected region between selection_bound and * insertion point. If that region is empty, then we cut the region * between the "anchor" and the insertion point (this is for @@ -3933,10 +3910,6 @@ cut_or_copy (GtkTextBuffer *buffer, GtkTextIter start; GtkTextIter end; - priv = buffer->priv; - - gtk_text_buffer_get_copy_target_list (buffer); - if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) { /* Let's try the anchor thing */ @@ -3953,31 +3926,20 @@ cut_or_copy (GtkTextBuffer *buffer, if (!gtk_text_iter_equal (&start, &end)) { - GtkTextIter ins; GtkTextBuffer *contents; + GdkContentProvider *provider; + GValue value = G_VALUE_INIT; - contents = create_clipboard_contents_buffer (buffer); + contents = create_clipboard_contents_buffer (buffer, &start, &end); - gtk_text_buffer_get_iter_at_offset (contents, &ins, 0); - - gtk_text_buffer_insert_range (contents, &ins, &start, &end); - - if (!gtk_clipboard_set_with_data (clipboard, - priv->copy_target_list, - clipboard_get_contents_cb, - clipboard_clear_contents_cb, - contents)) - { - g_object_unref (contents); - } - else - { - GdkContentFormats *list; - - list = gtk_text_buffer_get_target_list (buffer, FALSE, FALSE); - gtk_clipboard_set_can_store (clipboard, list); - gdk_content_formats_unref (list); - } + g_value_init (&value, GTK_TYPE_TEXT_BUFFER); + g_value_take_object (&value, contents); + + provider = gdk_content_provider_new_for_value (&value); + g_value_unset (&value); + + gdk_clipboard_set_content (clipboard, provider); + g_object_unref (provider); if (delete_region_after) { @@ -3993,7 +3955,7 @@ cut_or_copy (GtkTextBuffer *buffer, /** * gtk_text_buffer_cut_clipboard: * @buffer: a #GtkTextBuffer - * @clipboard: the #GtkClipboard object to cut to + * @clipboard: the #GdkClipboard object to cut to * @default_editable: default editability of the buffer * * Copies the currently-selected text to a clipboard, then deletes @@ -4001,7 +3963,7 @@ cut_or_copy (GtkTextBuffer *buffer, **/ void gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard, + GdkClipboard *clipboard, gboolean default_editable) { gtk_text_buffer_begin_user_action (buffer); @@ -4012,13 +3974,13 @@ gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer, /** * gtk_text_buffer_copy_clipboard: * @buffer: a #GtkTextBuffer - * @clipboard: the #GtkClipboard object to copy to + * @clipboard: the #GdkClipboard object to copy to * * Copies the currently-selected text to a clipboard. **/ void gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard) + GdkClipboard *clipboard) { cut_or_copy (buffer, clipboard, FALSE, TRUE, TRUE); } @@ -4106,64 +4068,6 @@ gtk_text_buffer_end_user_action (GtkTextBuffer *buffer) } } -/** - * gtk_text_buffer_get_copy_target_list: - * @buffer: a #GtkTextBuffer - * - * This function returns the list of targets this text buffer can - * provide for copying and as DND source. The targets in the list are - * added with @info values from the #GtkTextBufferTargetInfo enum, - * using gdk_content_formats_add_text_targets(). - * - * Returns: (transfer none): the #GdkContentFormats - * - * Since: 2.10 - **/ -GdkContentFormats * -gtk_text_buffer_get_copy_target_list (GtkTextBuffer *buffer) -{ - GtkTextBufferPrivate *priv; - - g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL); - - priv = buffer->priv; - - if (! priv->copy_target_list) - priv->copy_target_list = - gtk_text_buffer_get_target_list (buffer, FALSE, TRUE); - - return priv->copy_target_list; -} - -/** - * gtk_text_buffer_get_paste_target_list: - * @buffer: a #GtkTextBuffer - * - * This function returns the list of targets this text buffer supports - * for pasting and as DND destination. The targets in the list are - * added with @info values from the #GtkTextBufferTargetInfo enum, - * using gtk_content_formats_add_text_targets(). - * - * Returns: (transfer none): the #GdkContentFormats - * - * Since: 2.10 - **/ -GdkContentFormats * -gtk_text_buffer_get_paste_target_list (GtkTextBuffer *buffer) -{ - GtkTextBufferPrivate *priv; - - g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL); - - priv = buffer->priv; - - if (! priv->paste_target_list) - priv->paste_target_list = - gtk_text_buffer_get_target_list (buffer, TRUE, TRUE); - - return priv->paste_target_list; -} - /* * Logical attribute cache */ diff --git a/gtk/gtktextbuffer.h b/gtk/gtktextbuffer.h index 240bf8e2f9..2181c5efb5 100644 --- a/gtk/gtktextbuffer.h +++ b/gtk/gtktextbuffer.h @@ -30,7 +30,6 @@ #endif #include <gtk/gtkwidget.h> -#include <gtk/gtkclipboard.h> #include <gtk/gtktexttagtable.h> #include <gtk/gtktextiter.h> #include <gtk/gtktextmark.h> @@ -146,7 +145,7 @@ struct _GtkTextBufferClass void (* end_user_action) (GtkTextBuffer *buffer); void (* paste_done) (GtkTextBuffer *buffer, - GtkClipboard *clipboard); + GdkClipboard *clipboard); /*< private >*/ @@ -425,21 +424,21 @@ gboolean gtk_text_buffer_get_has_selection (GtkTextBuffer *buffer); GDK_AVAILABLE_IN_ALL void gtk_text_buffer_add_selection_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard); + GdkClipboard *clipboard); GDK_AVAILABLE_IN_ALL void gtk_text_buffer_remove_selection_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard); + GdkClipboard *clipboard); GDK_AVAILABLE_IN_ALL void gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard, + GdkClipboard *clipboard, gboolean default_editable); GDK_AVAILABLE_IN_ALL void gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard); + GdkClipboard *clipboard); GDK_AVAILABLE_IN_ALL void gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer, - GtkClipboard *clipboard, + GdkClipboard *clipboard, GtkTextIter *override_location, gboolean default_editable); @@ -458,11 +457,6 @@ void gtk_text_buffer_begin_user_action (GtkTextBuffer *buffer); GDK_AVAILABLE_IN_ALL void gtk_text_buffer_end_user_action (GtkTextBuffer *buffer); -GDK_AVAILABLE_IN_ALL -GdkContentFormats * gtk_text_buffer_get_copy_target_list (GtkTextBuffer *buffer); -GDK_AVAILABLE_IN_ALL -GdkContentFormats * gtk_text_buffer_get_paste_target_list (GtkTextBuffer *buffer); - G_END_DECLS diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index f8c5376d34..359c14550d 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -536,11 +536,8 @@ static void gtk_text_view_mark_set_handler (GtkTextBuffer *buffer, const GtkTextIter *location, GtkTextMark *mark, gpointer data); -static void gtk_text_view_target_list_notify (GtkTextBuffer *buffer, - const GParamSpec *pspec, - gpointer data); static void gtk_text_view_paste_done_handler (GtkTextBuffer *buffer, - GtkClipboard *clipboard, + GdkClipboard *clipboard, gpointer data); static void gtk_text_view_buffer_changed_handler (GtkTextBuffer *buffer, gpointer data); @@ -1690,7 +1687,7 @@ gtk_text_view_init (GtkTextView *text_view) gtk_drag_dest_set (widget, 0, NULL, GDK_ACTION_COPY | GDK_ACTION_MOVE); - target_list = gdk_content_formats_new (NULL, 0); + target_list = gdk_content_formats_new_for_gtype (GTK_TYPE_TEXT_BUFFER); gtk_drag_dest_set_target_list (widget, target_list); gdk_content_formats_unref (target_list); @@ -1883,9 +1880,6 @@ gtk_text_view_set_buffer (GtkTextView *text_view, gtk_text_view_mark_set_handler, text_view); g_signal_handlers_disconnect_by_func (priv->buffer, - gtk_text_view_target_list_notify, - text_view); - g_signal_handlers_disconnect_by_func (priv->buffer, gtk_text_view_paste_done_handler, text_view); g_signal_handlers_disconnect_by_func (priv->buffer, @@ -1894,8 +1888,7 @@ gtk_text_view_set_buffer (GtkTextView *text_view, if (gtk_widget_get_realized (GTK_WIDGET (text_view))) { - GtkClipboard *clipboard = gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_PRIMARY); + GdkClipboard *clipboard = gtk_widget_get_primary_clipboard (GTK_WIDGET (text_view)); gtk_text_buffer_remove_selection_clipboard (priv->buffer, clipboard); } @@ -1934,9 +1927,6 @@ gtk_text_view_set_buffer (GtkTextView *text_view, g_signal_connect (priv->buffer, "mark-set", G_CALLBACK (gtk_text_view_mark_set_handler), text_view); - g_signal_connect (priv->buffer, "notify::paste-target-list", - G_CALLBACK (gtk_text_view_target_list_notify), - text_view); g_signal_connect (priv->buffer, "paste-done", G_CALLBACK (gtk_text_view_paste_done_handler), text_view); @@ -1944,12 +1934,9 @@ gtk_text_view_set_buffer (GtkTextView *text_view, G_CALLBACK (gtk_text_view_buffer_changed_handler), text_view); - gtk_text_view_target_list_notify (priv->buffer, NULL, text_view); - if (gtk_widget_get_realized (GTK_WIDGET (text_view))) { - GtkClipboard *clipboard = gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_PRIMARY); + GdkClipboard *clipboard = gtk_widget_get_primary_clipboard (GTK_WIDGET (text_view)); gtk_text_buffer_add_selection_clipboard (priv->buffer, clipboard); } @@ -4582,8 +4569,7 @@ gtk_text_view_realize (GtkWidget *widget) if (priv->buffer) { - GtkClipboard *clipboard = gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_PRIMARY); + GdkClipboard *clipboard = gtk_widget_get_primary_clipboard (GTK_WIDGET (text_view)); gtk_text_buffer_add_selection_clipboard (priv->buffer, clipboard); } @@ -4602,8 +4588,7 @@ gtk_text_view_unrealize (GtkWidget *widget) if (priv->buffer) { - GtkClipboard *clipboard = gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_PRIMARY); + GdkClipboard *clipboard = gtk_widget_get_primary_clipboard (GTK_WIDGET (text_view)); gtk_text_buffer_remove_selection_clipboard (priv->buffer, clipboard); } @@ -5289,8 +5274,7 @@ gtk_text_view_multipress_gesture_pressed (GtkGestureMultiPress *gesture, get_iter_from_gesture (text_view, priv->multipress_gesture, &iter, NULL, NULL); gtk_text_buffer_paste_clipboard (get_buffer (text_view), - gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_PRIMARY), + gtk_widget_get_primary_clipboard (GTK_WIDGET (text_view)), &iter, priv->editable); } @@ -6770,8 +6754,7 @@ gtk_text_view_backspace (GtkTextView *text_view) static void gtk_text_view_cut_clipboard (GtkTextView *text_view) { - GtkClipboard *clipboard = gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_CLIPBOARD); + GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view)); gtk_text_buffer_cut_clipboard (get_buffer (text_view), clipboard, @@ -6785,8 +6768,7 @@ gtk_text_view_cut_clipboard (GtkTextView *text_view) static void gtk_text_view_copy_clipboard (GtkTextView *text_view) { - GtkClipboard *clipboard = gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_CLIPBOARD); + GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view)); gtk_text_buffer_copy_clipboard (get_buffer (text_view), clipboard); @@ -6797,8 +6779,7 @@ gtk_text_view_copy_clipboard (GtkTextView *text_view) static void gtk_text_view_paste_clipboard (GtkTextView *text_view) { - GtkClipboard *clipboard = gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_CLIPBOARD); + GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view)); gtk_text_buffer_paste_clipboard (get_buffer (text_view), clipboard, @@ -6808,7 +6789,7 @@ gtk_text_view_paste_clipboard (GtkTextView *text_view) static void gtk_text_view_paste_done_handler (GtkTextBuffer *buffer, - GtkClipboard *clipboard, + GdkClipboard *clipboard, gpointer data) { GtkTextView *text_view = data; @@ -7836,13 +7817,13 @@ gtk_text_view_start_selection_dnd (GtkTextView *text_view, gint x, gint y) { - GdkContentFormats *target_list; + GdkContentFormats *formats; - target_list = gtk_text_buffer_get_copy_target_list (get_buffer (text_view)); + formats = gdk_content_formats_new_for_gtype (GTK_TYPE_TEXT_BUFFER); g_signal_connect (text_view, "drag-begin", G_CALLBACK (drag_begin_cb), NULL); - gtk_drag_begin_with_coordinates (GTK_WIDGET (text_view), target_list, + gtk_drag_begin_with_coordinates (GTK_WIDGET (text_view), formats, GDK_ACTION_COPY | GDK_ACTION_MOVE, 1, (GdkEvent*) event, x, y); } @@ -8610,14 +8591,6 @@ gtk_text_view_mark_set_handler (GtkTextBuffer *buffer, } static void -gtk_text_view_target_list_notify (GtkTextBuffer *buffer, - const GParamSpec *pspec, - gpointer data) -{ - gtk_drag_dest_set_target_list (data, gtk_text_buffer_get_paste_target_list (buffer)); -} - -static void gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view, GtkTextIter *cursor, gint *x, @@ -8747,12 +8720,6 @@ popup_menu_detach (GtkWidget *attach_widget, GTK_TEXT_VIEW (attach_widget)->priv->popup_menu = NULL; } -typedef struct -{ - GtkTextView *text_view; - GdkEvent *trigger_event; -} PopupInfo; - static gboolean range_contains_editable_text (const GtkTextIter *start, const GtkTextIter *end, @@ -8772,34 +8739,28 @@ range_contains_editable_text (const GtkTextIter *start, } static void -popup_targets_received (GtkClipboard *clipboard, - GtkSelectionData *data, - gpointer user_data) +gtk_text_view_do_popup (GtkTextView *text_view, + const GdkEvent *event) { - PopupInfo *info = user_data; - GtkTextView *text_view; - GtkTextViewPrivate *priv; + GtkTextViewPrivate *priv = text_view->priv; + GdkEvent *trigger_event; - text_view = info->text_view; - priv = text_view->priv; + if (event) + trigger_event = gdk_event_copy (event); + else + trigger_event = gtk_get_current_event (); if (gtk_widget_get_realized (GTK_WIDGET (text_view))) { - /* We implicitely rely here on the fact that if we are pasting ourself, we'll - * have text targets as well as the private GTK_TEXT_BUFFER_CONTENTS target. - */ - gboolean clipboard_contains_text; GtkWidget *menuitem; gboolean have_selection; - gboolean can_insert; + gboolean can_insert, can_paste; GtkTextIter iter; GtkTextIter sel_start, sel_end; GdkRectangle iter_location; GdkRectangle visible_rect; gboolean is_visible; - clipboard_contains_text = gtk_selection_data_targets_include_text (data); - if (priv->popup_menu) gtk_widget_destroy (priv->popup_menu); @@ -8819,6 +8780,8 @@ popup_targets_received (GtkClipboard *clipboard, gtk_text_buffer_get_insert (get_buffer (text_view))); can_insert = gtk_text_iter_can_insert (&iter, priv->editable); + can_paste = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (gtk_widget_get_clipboard (GTK_WIDGET (text_view))), + GTK_TYPE_TEXT_BUFFER); append_action_signal (text_view, priv->popup_menu, _("Cu_t"), "cut-clipboard", have_selection && @@ -8827,7 +8790,7 @@ popup_targets_received (GtkClipboard *clipboard, append_action_signal (text_view, priv->popup_menu, _("_Copy"), "copy-clipboard", have_selection); append_action_signal (text_view, priv->popup_menu, _("_Paste"), "paste-clipboard", - can_insert && clipboard_contains_text); + can_insert && can_paste); menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete")); gtk_widget_set_sensitive (menuitem, @@ -8864,8 +8827,8 @@ popup_targets_received (GtkClipboard *clipboard, g_signal_emit (text_view, signals[POPULATE_POPUP], 0, priv->popup_menu); - if (info->trigger_event && gdk_event_triggers_context_menu (info->trigger_event)) - gtk_menu_popup_at_pointer (GTK_MENU (priv->popup_menu), info->trigger_event); + if (trigger_event && gdk_event_triggers_context_menu (trigger_event)) + gtk_menu_popup_at_pointer (GTK_MENU (priv->popup_menu), trigger_event); else { gtk_text_view_get_iter_location (text_view, &iter, &iter_location); @@ -8890,42 +8853,20 @@ popup_targets_received (GtkClipboard *clipboard, &iter_location, GDK_GRAVITY_SOUTH_EAST, GDK_GRAVITY_NORTH_WEST, - info->trigger_event); + trigger_event); } else gtk_menu_popup_at_widget (GTK_MENU (priv->popup_menu), GTK_WIDGET (text_view), GDK_GRAVITY_CENTER, GDK_GRAVITY_CENTER, - info->trigger_event); + trigger_event); gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->popup_menu), FALSE); } } - g_clear_pointer (&info->trigger_event, gdk_event_free); - g_object_unref (text_view); - g_slice_free (PopupInfo, info); -} - -static void -gtk_text_view_do_popup (GtkTextView *text_view, - const GdkEvent *event) -{ - PopupInfo *info = g_slice_new (PopupInfo); - - /* In order to know what entries we should make sensitive, we - * ask for the current targets of the clipboard, and when - * we get them, then we actually pop up the menu. - */ - info->text_view = g_object_ref (text_view); - info->trigger_event = event ? gdk_event_copy (event) : gtk_get_current_event (); - - gtk_clipboard_request_contents (gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_CLIPBOARD), - gdk_atom_intern_static_string ("TARGETS"), - popup_targets_received, - info); + g_clear_pointer (&trigger_event, gdk_event_free); } static gboolean @@ -9022,14 +8963,13 @@ append_bubble_action (GtkTextView *text_view, gtk_container_add (GTK_CONTAINER (toolbar), item); } -static void -bubble_targets_received (GtkClipboard *clipboard, - GtkSelectionData *data, - gpointer user_data) +static gboolean +gtk_text_view_selection_bubble_popup_show (gpointer user_data) { GtkTextView *text_view = user_data; GtkTextViewPrivate *priv = text_view->priv; cairo_rectangle_int_t rect; + GdkClipboard *clipboard; gboolean has_selection; gboolean has_clipboard; gboolean can_insert; @@ -9050,7 +8990,7 @@ bubble_targets_received (GtkClipboard *clipboard, if (!priv->editable && !has_selection) { priv->selection_bubble_timeout_id = 0; - return; + return G_SOURCE_REMOVE; } if (priv->selection_bubble) @@ -9075,7 +9015,8 @@ bubble_targets_received (GtkClipboard *clipboard, gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &iter, gtk_text_buffer_get_insert (get_buffer (text_view))); can_insert = gtk_text_iter_can_insert (&iter, priv->editable); - has_clipboard = gtk_selection_data_targets_include_text (data); + clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view)); + has_clipboard = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_TEXT_BUFFER); if (range_contains_editable_text (&sel_start, &sel_end, priv->editable) && has_selection) append_bubble_action (text_view, toolbar, _("Select all"), "edit-select-all-symbolic", "select-all", !all_selected); @@ -9105,18 +9046,6 @@ bubble_targets_received (GtkClipboard *clipboard, gtk_popover_set_pointing_to (GTK_POPOVER (priv->selection_bubble), &rect); gtk_widget_show (priv->selection_bubble); -} - -static gboolean -gtk_text_view_selection_bubble_popup_show (gpointer user_data) -{ - GtkTextView *text_view = user_data; - gtk_clipboard_request_contents (gtk_widget_get_old_clipboard (GTK_WIDGET (text_view), - GDK_SELECTION_CLIPBOARD), - gdk_atom_intern_static_string ("TARGETS"), - bubble_targets_received, - text_view); - text_view->priv->selection_bubble_timeout_id = 0; return G_SOURCE_REMOVE; } diff --git a/testsuite/gtk/textbuffer.c b/testsuite/gtk/textbuffer.c index 4f8cefed4a..f0817bbbf0 100644 --- a/testsuite/gtk/textbuffer.c +++ b/testsuite/gtk/textbuffer.c @@ -1365,13 +1365,13 @@ check_buffer_contents (GtkTextBuffer *buffer, static void test_clipboard (void) { - GtkClipboard *clipboard; + GdkClipboard *clipboard; GtkTextBuffer *buffer; GtkTextIter start; GtkTextIter end; GtkTextTag *tag; - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + clipboard = gdk_display_get_clipboard (gdk_display_get_default ()); buffer = gtk_text_buffer_new (NULL); gtk_text_buffer_set_text (buffer, "abcdef", -1); |