forked from AuroraMiddleware/gtk
textview: Redo clipboard handling
Instead of using GtkClipboard and handling everything ourselves, we now put GtkTextBuffer into the GdkClipboard and register (de)serializers for text/plain.
This commit is contained in:
parent
4e06aaeaa8
commit
f53848c360
@ -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");
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
value = gdk_clipboard_read_value_finish (clipboard, result, NULL);
|
||||
if (value == NULL)
|
||||
return;
|
||||
|
||||
if (src_buffer)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
src_buffer = g_value_get_object (value);
|
||||
|
||||
if (g_object_get_data (G_OBJECT (src_buffer), "gtk-text-buffer-clipboard"))
|
||||
{
|
||||
gtk_text_buffer_get_bounds (src_buffer, &start, &end);
|
||||
|
||||
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 (priv->selection_content)
|
||||
gdk_content_provider_content_changed (priv->selection_content);
|
||||
else
|
||||
priv->selection_content = gtk_text_buffer_content_new (buffer);
|
||||
|
||||
if (has_selection)
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3884,45 +3893,13 @@ gtk_text_buffer_backspace (GtkTextBuffer *buffer,
|
||||
return retval;
|
||||
}
|
||||
|
||||
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);
|
||||
g_value_init (&value, GTK_TYPE_TEXT_BUFFER);
|
||||
g_value_take_object (&value, contents);
|
||||
|
||||
gtk_text_buffer_insert_range (contents, &ins, &start, &end);
|
||||
provider = gdk_content_provider_new_for_value (&value);
|
||||
g_value_unset (&value);
|
||||
|
||||
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);
|
||||
}
|
||||
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
|
||||
*/
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
@ -1882,9 +1879,6 @@ gtk_text_view_set_buffer (GtkTextView *text_view,
|
||||
g_signal_handlers_disconnect_by_func (priv->buffer,
|
||||
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);
|
||||
@ -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);
|
||||
}
|
||||
@ -8609,14 +8590,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,
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user