[gtk+/wip/otte/clipboard: 95/102] entry: Port to GdkClipboard
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/clipboard: 95/102] entry: Port to GdkClipboard
- Date: Sat, 2 Dec 2017 15:36:36 +0000 (UTC)
commit fbed3725885d487d9e385924b4af24d8da21359a
Author: Benjamin Otte <otte redhat com>
Date: Fri Dec 1 07:21:21 2017 +0100
entry: Port to GdkClipboard
gtk/gtkentry.c | 309 ++++++++++++++++++++++++++++++--------------------------
1 files changed, 167 insertions(+), 142 deletions(-)
---
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 2fc8bb4..7b5f5ea 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -34,7 +34,6 @@
#include "gtkbindings.h"
#include "gtkcelleditable.h"
-#include "gtkclipboard.h"
#include "gtkdebug.h"
#include "gtkdnd.h"
#include "gtkdndprivate.h"
@@ -194,6 +193,8 @@ struct _GtkEntryPrivate
PangoAttrList *attrs;
PangoTabArray *tabs;
+ GdkContentProvider *selection_content;
+
gchar *im_module;
gchar *placeholder_text;
@@ -596,7 +597,7 @@ static void gtk_entry_delete_whitespace (GtkEntry *entry);
static void gtk_entry_select_word (GtkEntry *entry);
static void gtk_entry_select_line (GtkEntry *entry);
static void gtk_entry_paste (GtkEntry *entry,
- GdkAtom selection);
+ GdkClipboard *clipboard);
static void gtk_entry_update_primary_selection (GtkEntry *entry);
static void gtk_entry_do_popup (GtkEntry *entry,
const GdkEvent *event);
@@ -673,6 +674,86 @@ G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_EDITABLE,
gtk_entry_cell_editable_init))
+#define GTK_TYPE_ENTRY_CONTENT (gtk_entry_content_get_type ())
+#define GTK_ENTRY_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ENTRY_CONTENT,
GtkEntryContent))
+#define GTK_IS_ENTRY_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ENTRY_CONTENT))
+#define GTK_ENTRY_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ENTRY_CONTENT,
GtkEntryContentClass))
+#define GTK_IS_ENTRY_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ENTRY_CONTENT))
+#define GTK_ENTRY_CONTENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ENTRY_CONTENT,
GtkEntryContentClass))
+
+typedef struct _GtkEntryContent GtkEntryContent;
+typedef struct _GtkEntryContentClass GtkEntryContentClass;
+
+struct _GtkEntryContent
+{
+ GdkContentProvider parent;
+
+ GtkEntry *entry;
+};
+
+struct _GtkEntryContentClass
+{
+ GdkContentProviderClass parent_class;
+};
+
+GType gtk_entry_content_get_type (void) G_GNUC_CONST;
+
+G_DEFINE_TYPE (GtkEntryContent, gtk_entry_content, GDK_TYPE_CONTENT_PROVIDER)
+
+static GdkContentFormats *
+gtk_entry_content_ref_formats (GdkContentProvider *provider)
+{
+ return gdk_content_formats_new_for_gtype (G_TYPE_STRING);
+}
+
+static gboolean
+gtk_entry_content_get_value (GdkContentProvider *provider,
+ GValue *value,
+ GError **error)
+{
+ GtkEntryContent *content = GTK_ENTRY_CONTENT (provider);
+
+ if (G_VALUE_HOLDS (value, G_TYPE_STRING))
+ {
+ int start, end;
+
+ if (gtk_editable_get_selection_bounds (GTK_EDITABLE (content->entry), &start, &end))
+ {
+ gchar *str = _gtk_entry_get_display_text (content->entry, start, end);
+ g_value_take_string (value, str);
+ }
+ return TRUE;
+ }
+
+ return GDK_CONTENT_PROVIDER_CLASS (gtk_entry_content_parent_class)->get_value (provider, value, error);
+}
+
+static void
+gtk_entry_content_detach (GdkContentProvider *provider,
+ GdkClipboard *clipboard)
+{
+ GtkEntryContent *content = GTK_ENTRY_CONTENT (provider);
+ GtkEntry *entry = content->entry;
+ GtkEntryPrivate *priv = entry->priv;
+
+ gtk_editable_select_region (GTK_EDITABLE (entry), priv->current_pos, priv->current_pos);
+}
+
+static void
+gtk_entry_content_class_init (GtkEntryContentClass *class)
+{
+ GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
+
+ provider_class->ref_formats = gtk_entry_content_ref_formats;
+ provider_class->get_value = gtk_entry_content_get_value;
+ provider_class->detach_clipboard = gtk_entry_content_detach;
+}
+
+static void
+gtk_entry_content_init (GtkEntryContent *content)
+{
+}
+
static void
add_move_binding (GtkBindingSet *binding_set,
guint keyval,
@@ -2493,6 +2574,10 @@ gtk_entry_init (GtkEntry *entry)
priv->xalign = 0.0;
priv->caps_lock_warning = TRUE;
priv->caps_lock_warning_shown = FALSE;
+ priv->insert_pos = -1;
+
+ priv->selection_content = g_object_new (GTK_TYPE_ENTRY_CONTENT, NULL);
+ GTK_ENTRY_CONTENT (priv->selection_content)->entry = entry;
gtk_drag_dest_set (GTK_WIDGET (entry), 0, NULL,
GDK_ACTION_COPY | GDK_ACTION_MOVE);
@@ -2698,6 +2783,8 @@ gtk_entry_finalize (GObject *object)
EntryIconInfo *icon_info = NULL;
gint i;
+ g_clear_object (&priv->selection_content);
+
for (i = 0; i < MAX_ICONS; i++)
{
icon_info = priv->icons[i];
@@ -3017,15 +3104,15 @@ gtk_entry_unrealize (GtkWidget *widget)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = entry->priv;
- GtkClipboard *clipboard;
+ GdkClipboard *clipboard;
gtk_entry_reset_layout (entry);
gtk_im_context_set_client_widget (priv->im_context, NULL);
- clipboard = gtk_widget_get_old_clipboard (widget, GDK_SELECTION_PRIMARY);
- if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry))
- gtk_clipboard_clear (clipboard);
+ clipboard = gtk_widget_get_primary_clipboard (widget);
+ if (gdk_clipboard_get_content (clipboard) == priv->selection_content)
+ gdk_clipboard_set_content (clipboard, NULL);
if (priv->popup_menu)
{
@@ -3682,7 +3769,7 @@ gtk_entry_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
if (priv->editable)
{
priv->insert_pos = tmp_pos;
- gtk_entry_paste (entry, GDK_SELECTION_PRIMARY);
+ gtk_entry_paste (entry, gtk_widget_get_primary_clipboard (widget));
}
else
{
@@ -5117,9 +5204,7 @@ gtk_entry_copy_clipboard (GtkEntry *entry)
}
str = _gtk_entry_get_display_text (entry, start, end);
- gtk_clipboard_set_text (gtk_widget_get_old_clipboard (GTK_WIDGET (entry),
- GDK_SELECTION_CLIPBOARD),
- str, -1);
+ gdk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (entry)), str);
g_free (str);
}
}
@@ -5168,7 +5253,7 @@ gtk_entry_paste_clipboard (GtkEntry *entry)
GtkEntryPrivate *priv = entry->priv;
if (priv->editable)
- gtk_entry_paste (entry, GDK_SELECTION_CLIPBOARD);
+ gtk_entry_paste (entry, gtk_widget_get_clipboard (GTK_WIDGET (entry)));
else
gtk_widget_error_bell (GTK_WIDGET (entry));
@@ -6483,130 +6568,103 @@ truncate_multiline (const gchar *text)
}
static void
-paste_received (GtkClipboard *clipboard,
- const gchar *text,
+paste_received (GObject *clipboard,
+ GAsyncResult *result,
gpointer data)
{
GtkEntry *entry = GTK_ENTRY (data);
GtkEditable *editable = GTK_EDITABLE (entry);
GtkEntryPrivate *priv = entry->priv;
- guint button;
+ char *text;
+ gint pos, start, end;
+ gint length = -1;
+ gboolean popup_completion;
+ GtkEntryCompletion *completion;
- button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (priv->multipress_gesture));
+ text = gdk_clipboard_read_text_finish (GDK_CLIPBOARD (clipboard), result, NULL);
+ if (text == NULL)
+ {
+ gtk_widget_error_bell (GTK_WIDGET (entry));
+ return;
+ }
- if (button == GDK_BUTTON_MIDDLE)
+ if (priv->insert_pos >= 0)
{
gint pos, start, end;
pos = priv->insert_pos;
gtk_editable_get_selection_bounds (editable, &start, &end);
if (!((start <= pos && pos <= end) || (end <= pos && pos <= start)))
gtk_editable_select_region (editable, pos, pos);
+ priv->insert_pos = -1;
}
- if (text)
- {
- gint pos, start, end;
- gint length = -1;
- gboolean popup_completion;
- GtkEntryCompletion *completion;
-
- completion = gtk_entry_get_completion (entry);
+ completion = gtk_entry_get_completion (entry);
- if (priv->truncate_multiline)
- length = truncate_multiline (text);
+ if (priv->truncate_multiline)
+ length = truncate_multiline (text);
- /* only complete if the selection is at the end */
- popup_completion = (gtk_entry_buffer_get_length (get_buffer (entry)) ==
- MAX (priv->current_pos, priv->selection_bound));
+ /* only complete if the selection is at the end */
+ popup_completion = (gtk_entry_buffer_get_length (get_buffer (entry)) ==
+ MAX (priv->current_pos, priv->selection_bound));
- if (completion)
- {
- if (gtk_widget_get_mapped (completion->priv->popup_window))
- _gtk_entry_completion_popdown (completion);
+ if (completion)
+ {
+ if (gtk_widget_get_mapped (completion->priv->popup_window))
+ _gtk_entry_completion_popdown (completion);
- if (!popup_completion && completion->priv->changed_id > 0)
- g_signal_handler_block (entry, completion->priv->changed_id);
- }
+ if (!popup_completion && completion->priv->changed_id > 0)
+ g_signal_handler_block (entry, completion->priv->changed_id);
+ }
- begin_change (entry);
- if (gtk_editable_get_selection_bounds (editable, &start, &end))
- gtk_editable_delete_text (editable, start, end);
+ begin_change (entry);
+ if (gtk_editable_get_selection_bounds (editable, &start, &end))
+ gtk_editable_delete_text (editable, start, end);
- pos = priv->current_pos;
- gtk_editable_insert_text (editable, text, length, &pos);
- gtk_editable_set_position (editable, pos);
- end_change (entry);
+ pos = priv->current_pos;
+ gtk_editable_insert_text (editable, text, length, &pos);
+ gtk_editable_set_position (editable, pos);
+ end_change (entry);
- if (completion &&
- !popup_completion && completion->priv->changed_id > 0)
- g_signal_handler_unblock (entry, completion->priv->changed_id);
- }
+ if (completion &&
+ !popup_completion && completion->priv->changed_id > 0)
+ g_signal_handler_unblock (entry, completion->priv->changed_id);
+ g_free (text);
g_object_unref (entry);
}
static void
-gtk_entry_paste (GtkEntry *entry,
- GdkAtom selection)
+gtk_entry_paste (GtkEntry *entry,
+ GdkClipboard *clipboard)
{
g_object_ref (entry);
- gtk_clipboard_request_text (gtk_widget_get_old_clipboard (GTK_WIDGET (entry), selection),
- paste_received, entry);
-}
-
-static void
-primary_get_cb (GtkClipboard *clipboard,
- GtkSelectionData *selection_data,
- gpointer data)
-{
- GtkEntry *entry = GTK_ENTRY (data);
- gint start, end;
-
- if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
- {
- gchar *str = _gtk_entry_get_display_text (entry, start, end);
- gtk_selection_data_set_text (selection_data, str, -1);
- g_free (str);
- }
-}
-
-static void
-primary_clear_cb (GtkClipboard *clipboard,
- gpointer data)
-{
- GtkEntry *entry = GTK_ENTRY (data);
- GtkEntryPrivate *priv = entry->priv;
-
- gtk_editable_select_region (GTK_EDITABLE (entry), priv->current_pos, priv->current_pos);
+ gdk_clipboard_read_text_async (clipboard,
+ NULL,
+ paste_received,
+ entry);
}
static void
gtk_entry_update_primary_selection (GtkEntry *entry)
{
- GdkContentFormats *list;
- GtkClipboard *clipboard;
+ GtkEntryPrivate *priv = entry->priv;
+ GdkClipboard *clipboard;
gint start, end;
if (!gtk_widget_get_realized (GTK_WIDGET (entry)))
return;
- list = gdk_content_formats_new (NULL, 0);
- list = gtk_content_formats_add_text_targets (list);
-
- clipboard = gtk_widget_get_old_clipboard (GTK_WIDGET (entry), GDK_SELECTION_PRIMARY);
+ clipboard = gtk_widget_get_primary_clipboard (GTK_WIDGET (entry));
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
{
- gtk_clipboard_set_with_owner (clipboard, list,
- primary_get_cb, primary_clear_cb, G_OBJECT (entry));
+ gdk_clipboard_set_content (clipboard, priv->selection_content);
}
else
{
- if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry))
- gtk_clipboard_clear (clipboard);
+ if (gdk_clipboard_get_content (clipboard) == priv->selection_content)
+ gdk_clipboard_set_content (clipboard, NULL);
}
-
- gdk_content_formats_unref (list);
}
static void
@@ -8471,20 +8529,18 @@ popup_menu_detach (GtkWidget *attach_widget,
priv_attach->popup_menu = NULL;
}
-typedef struct
-{
- GtkEntry *entry;
- GdkEvent *trigger_event;
-} PopupInfo;
-
static void
-popup_targets_received (GtkClipboard *clipboard,
- GtkSelectionData *data,
- gpointer user_data)
+gtk_entry_do_popup (GtkEntry *entry,
+ const GdkEvent *event)
{
- PopupInfo *info = user_data;
- GtkEntry *entry = info->entry;
GtkEntryPrivate *info_entry_priv = entry->priv;
+ GdkEvent *trigger_event;
+
+ /* 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.
+ */
+ trigger_event = event ? gdk_event_copy (event) : gtk_get_current_event ();
if (gtk_widget_get_realized (GTK_WIDGET (entry)))
{
@@ -8493,7 +8549,8 @@ popup_targets_received (GtkClipboard *clipboard,
GtkWidget *menu;
GtkWidget *menuitem;
- clipboard_contains_text = gtk_selection_data_targets_include_text (data);
+ clipboard_contains_text = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats
(gtk_widget_get_clipboard (GTK_WIDGET (entry))),
+ G_TYPE_STRING);
if (info_entry_priv->popup_menu)
gtk_widget_destroy (info_entry_priv->popup_menu);
@@ -8548,42 +8605,21 @@ popup_targets_received (GtkClipboard *clipboard,
g_signal_emit (entry, signals[POPULATE_POPUP], 0, menu);
- if (info->trigger_event && gdk_event_triggers_context_menu (info->trigger_event))
- gtk_menu_popup_at_pointer (GTK_MENU (menu), info->trigger_event);
+ if (trigger_event && gdk_event_triggers_context_menu (trigger_event))
+ gtk_menu_popup_at_pointer (GTK_MENU (menu), trigger_event);
else
{
gtk_menu_popup_at_widget (GTK_MENU (menu),
GTK_WIDGET (entry),
GDK_GRAVITY_SOUTH_EAST,
GDK_GRAVITY_NORTH_WEST,
- info->trigger_event);
+ trigger_event);
gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE);
}
}
- g_clear_pointer (&info->trigger_event, gdk_event_free);
- g_object_unref (entry);
- g_slice_free (PopupInfo, info);
-}
-
-static void
-gtk_entry_do_popup (GtkEntry *entry,
- 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->entry = g_object_ref (entry);
- info->trigger_event = event ? gdk_event_copy (event) : gtk_get_current_event ();
-
- gtk_clipboard_request_contents (gtk_widget_get_old_clipboard (GTK_WIDGET (entry), GDK_SELECTION_CLIPBOARD),
- gdk_atom_intern_static_string ("TARGETS"),
- popup_targets_received,
- info);
+ g_clear_pointer (&trigger_event, gdk_event_free);
}
static gboolean
@@ -8656,10 +8692,8 @@ append_bubble_action (GtkEntry *entry,
gtk_container_add (GTK_CONTAINER (toolbar), item);
}
-static void
-bubble_targets_received (GtkClipboard *clipboard,
- GtkSelectionData *data,
- gpointer user_data)
+static gboolean
+gtk_entry_selection_bubble_popup_show (gpointer user_data)
{
GtkEntry *entry = user_data;
GtkEntryPrivate *priv = entry->priv;
@@ -8684,7 +8718,7 @@ bubble_targets_received (GtkClipboard *clipboard,
if (!has_selection && !priv->editable)
{
priv->selection_bubble_timeout_id = 0;
- return;
+ return G_SOURCE_REMOVE;
}
if (priv->selection_bubble)
@@ -8706,7 +8740,8 @@ bubble_targets_received (GtkClipboard *clipboard,
gtk_container_add (GTK_CONTAINER (priv->selection_bubble), box);
gtk_container_add (GTK_CONTAINER (box), toolbar);
- has_clipboard = gtk_selection_data_targets_include_text (data);
+ has_clipboard = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (gtk_widget_get_clipboard
(GTK_WIDGET (entry))),
+ G_TYPE_STRING);
mode = gtk_entry_get_display_mode (entry);
if (priv->editable && has_selection && mode == DISPLAY_NORMAL)
@@ -8756,17 +8791,7 @@ bubble_targets_received (GtkClipboard *clipboard,
gtk_widget_show (priv->selection_bubble);
priv->selection_bubble_timeout_id = 0;
-}
-
-static gboolean
-gtk_entry_selection_bubble_popup_show (gpointer user_data)
-{
- GtkEntry *entry = user_data;
- gtk_clipboard_request_contents (gtk_widget_get_old_clipboard (GTK_WIDGET (entry), GDK_SELECTION_CLIPBOARD),
- gdk_atom_intern_static_string ("TARGETS"),
- bubble_targets_received,
- entry);
return G_SOURCE_REMOVE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]