summaryrefslogtreecommitdiff
path: root/gtk/gtktextview.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2017-11-28 02:09:21 +0100
committerBenjamin Otte <otte@redhat.com>2017-12-03 05:46:48 +0100
commitf53848c3606a9c46bcb3a0e568f36e573bdf84da (patch)
treeb1dd4a727486e33abcf40401208c94c6b2f547fa /gtk/gtktextview.c
parent4e06aaeaa8de2f01e28f68f41c442b6dd66482db (diff)
downloadgtk+-f53848c3606a9c46bcb3a0e568f36e573bdf84da.tar.gz
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.
Diffstat (limited to 'gtk/gtktextview.c')
-rw-r--r--gtk/gtktextview.c145
1 files changed, 37 insertions, 108 deletions
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;
}