[gnome-shell/wip/carlosg/x11less-clipboard] st: Reimplement StClipboard on top of MetaSelection
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/carlosg/x11less-clipboard] st: Reimplement StClipboard on top of MetaSelection
- Date: Thu, 14 Feb 2019 17:08:37 +0000 (UTC)
commit 0d7c28be29bdb2279c7ae07b0827dcc7e47b2421
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon Nov 26 12:54:23 2018 +0100
st: Reimplement StClipboard on top of MetaSelection
And stop using X11/gdk for this.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/331
src/st/meson.build | 2 +-
src/st/st-clipboard.c | 360 +++++++++-----------------------------------------
src/st/st-clipboard.h | 2 -
3 files changed, 65 insertions(+), 299 deletions(-)
---
diff --git a/src/st/meson.build b/src/st/meson.build
index 21756eb07..c611c60a3 100644
--- a/src/st/meson.build
+++ b/src/st/meson.build
@@ -123,7 +123,7 @@ st_cflags = [
libst = shared_library('st-1.0',
sources: st_gir_sources + st_non_gir_sources,
c_args: st_cflags,
- dependencies: [clutter_dep, gtk_dep, croco_dep, x11_dep, m_dep],
+ dependencies: [clutter_dep, gtk_dep, croco_dep, mutter_dep, m_dep],
install_rpath: mutter_typelibdir,
install_dir: pkglibdir,
install: true
diff --git a/src/st/st-clipboard.c b/src/st/st-clipboard.c
index d5b1395e4..36086dd96 100644
--- a/src/st/st-clipboard.c
+++ b/src/st/st-clipboard.c
@@ -19,279 +19,40 @@
/**
* SECTION:st-clipboard
- * @short_description: a simple representation of the X clipboard
+ * @short_description: a simple representation of the clipboard
*
* #StCliboard is a very simple object representation of the clipboard
* available to applications. Text is always assumed to be UTF-8 and non-text
* items are not handled.
*/
+#include "config.h"
#include "st-clipboard.h"
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-#include <string.h>
-struct _StClipboardPrivate
-{
- Window clipboard_window;
- gchar *clipboard_text;
-
- Atom *supported_targets;
- gint n_targets;
-};
+#include <meta/display.h>
+#include <meta/meta-selection-source-memory.h>
+#include <meta/meta-selection.h>
-G_DEFINE_TYPE_WITH_PRIVATE (StClipboard, st_clipboard, G_TYPE_OBJECT)
+G_DEFINE_TYPE (StClipboard, st_clipboard, G_TYPE_OBJECT)
-typedef struct _EventFilterData EventFilterData;
-struct _EventFilterData
+typedef struct _TransferData TransferData;
+struct _TransferData
{
StClipboard *clipboard;
StClipboardCallbackFunc callback;
gpointer user_data;
+ GOutputStream *stream;
};
-static Atom __atom_primary = None;
-static Atom __atom_clip = None;
-static Atom __utf8_string = None;
-static Atom __atom_targets = None;
-
-static void
-st_clipboard_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-st_clipboard_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-st_clipboard_dispose (GObject *object)
-{
- G_OBJECT_CLASS (st_clipboard_parent_class)->dispose (object);
-}
-
-static void
-st_clipboard_finalize (GObject *object)
-{
- StClipboardPrivate *priv = ((StClipboard *) object)->priv;
-
- g_free (priv->clipboard_text);
- priv->clipboard_text = NULL;
-
- g_free (priv->supported_targets);
- priv->supported_targets = NULL;
- priv->n_targets = 0;
-
- G_OBJECT_CLASS (st_clipboard_parent_class)->finalize (object);
-}
-
-static GdkFilterReturn
-st_clipboard_provider (GdkXEvent *xevent_p,
- GdkEvent *gev,
- void *user_data)
-{
- StClipboard *clipboard = user_data;
- XEvent *xev = (XEvent *) xevent_p;
- XSelectionEvent notify_event;
- XSelectionRequestEvent *req_event;
- GdkDisplay *display = gdk_display_get_default ();
-
- if (xev->type != SelectionRequest ||
- xev->xany.window != clipboard->priv->clipboard_window ||
- !clipboard->priv->clipboard_text)
- return GDK_FILTER_CONTINUE;
-
- req_event = &xev->xselectionrequest;
-
- gdk_x11_display_error_trap_push (display);
-
- if (req_event->target == __atom_targets)
- {
- XChangeProperty (req_event->display,
- req_event->requestor,
- req_event->property,
- XA_ATOM,
- 32,
- PropModeReplace,
- (guchar*) clipboard->priv->supported_targets,
- clipboard->priv->n_targets);
- }
- else
- {
- XChangeProperty (req_event->display,
- req_event->requestor,
- req_event->property,
- req_event->target,
- 8,
- PropModeReplace,
- (guchar*) clipboard->priv->clipboard_text,
- strlen (clipboard->priv->clipboard_text));
- }
-
- notify_event.type = SelectionNotify;
- notify_event.display = req_event->display;
- notify_event.requestor = req_event->requestor;
- notify_event.selection = req_event->selection;
- notify_event.target = req_event->target;
- notify_event.time = req_event->time;
-
- if (req_event->property == None)
- notify_event.property = req_event->target;
- else
- notify_event.property = req_event->property;
-
- /* notify the requestor that they have a copy of the selection */
- XSendEvent (req_event->display, req_event->requestor, False, 0,
- (XEvent *) ¬ify_event);
- /* Make it happen non async */
- XSync (GDK_DISPLAY_XDISPLAY (display), FALSE);
-
- if (gdk_x11_display_error_trap_pop (display))
- {
- /* FIXME: Warn here on fail ? */
- }
-
- return GDK_FILTER_REMOVE;
-}
-
-
static void
st_clipboard_class_init (StClipboardClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = st_clipboard_get_property;
- object_class->set_property = st_clipboard_set_property;
- object_class->dispose = st_clipboard_dispose;
- object_class->finalize = st_clipboard_finalize;
}
static void
st_clipboard_init (StClipboard *self)
{
- GdkDisplay *gdk_display;
- Display *dpy;
- StClipboardPrivate *priv;
-
- priv = self->priv = st_clipboard_get_instance_private (self);
-
- gdk_display = gdk_display_get_default ();
- dpy = GDK_DISPLAY_XDISPLAY (gdk_display);
-
- priv->clipboard_window =
- XCreateSimpleWindow (dpy,
- gdk_x11_get_default_root_xwindow (),
- -1, -1, 1, 1, 0, 0, 0);
-
- /* Only create once */
- if (__atom_primary == None)
- __atom_primary = XInternAtom (dpy, "PRIMARY", 0);
-
- if (__atom_clip == None)
- __atom_clip = XInternAtom (dpy, "CLIPBOARD", 0);
-
- if (__utf8_string == None)
- __utf8_string = XInternAtom (dpy, "UTF8_STRING", 0);
-
- if (__atom_targets == None)
- __atom_targets = XInternAtom (dpy, "TARGETS", 0);
-
- priv->n_targets = 2;
- priv->supported_targets = g_new (Atom, priv->n_targets);
-
- priv->supported_targets[0] = __utf8_string;
- priv->supported_targets[1] = __atom_targets;
-
- gdk_window_add_filter (NULL, /* all windows */
- st_clipboard_provider,
- self);
-}
-
-static GdkFilterReturn
-st_clipboard_x11_event_filter (GdkXEvent *xevent_p,
- GdkEvent *gev,
- void *user_data)
-{
- XEvent *xev = (XEvent *) xevent_p;
- EventFilterData *filter_data = user_data;
- StClipboardPrivate *priv = filter_data->clipboard->priv;
- Atom actual_type;
- int actual_format, result;
- unsigned long nitems, bytes_after;
- unsigned char *data = NULL;
- GdkDisplay *display = gdk_display_get_default ();
-
- if(xev->type != SelectionNotify ||
- xev->xany.window != priv->clipboard_window)
- return GDK_FILTER_CONTINUE;
-
- if (xev->xselection.property == None)
- {
- /* clipboard empty */
- filter_data->callback (filter_data->clipboard,
- NULL,
- filter_data->user_data);
-
- gdk_window_remove_filter (NULL,
- st_clipboard_x11_event_filter,
- filter_data);
- g_free (filter_data);
- return GDK_FILTER_REMOVE;
- }
-
- gdk_x11_display_error_trap_push (display);
-
- result = XGetWindowProperty (xev->xselection.display,
- xev->xselection.requestor,
- xev->xselection.property,
- 0L, G_MAXINT,
- True,
- AnyPropertyType,
- &actual_type,
- &actual_format,
- &nitems,
- &bytes_after,
- &data);
-
- if (gdk_x11_display_error_trap_pop (display) || result != Success)
- {
- /* FIXME: handle failure better */
- g_warning ("Clipboard: prop retrival failed");
- }
-
- filter_data->callback (filter_data->clipboard, (char*) data,
- filter_data->user_data);
-
- gdk_window_remove_filter (NULL,
- st_clipboard_x11_event_filter,
- filter_data);
-
- g_free (filter_data);
-
- if (data)
- XFree (data);
-
- return GDK_FILTER_REMOVE;
}
/**
@@ -315,10 +76,34 @@ st_clipboard_get_default (void)
return default_clipboard;
}
-static Atom
-atom_for_clipboard_type (StClipboardType type)
+static gboolean
+convert_type (StClipboardType type,
+ MetaSelectionType *type_out)
{
- return type == ST_CLIPBOARD_TYPE_CLIPBOARD ? __atom_clip : __atom_primary;
+ if (type == ST_CLIPBOARD_TYPE_PRIMARY)
+ *type_out = META_SELECTION_PRIMARY;
+ else if (type == ST_CLIPBOARD_TYPE_CLIPBOARD)
+ *type_out = META_SELECTION_CLIPBOARD;
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+transfer_cb (MetaSelection *selection,
+ GAsyncResult *res,
+ TransferData *data)
+{
+ const gchar *text = NULL;
+
+ if (meta_selection_transfer_finish (selection, res, NULL))
+ text = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->stream));
+
+ data->callback (data->clipboard, text, data->user_data);
+
+ g_object_unref (data->stream);
+ g_free (data);
}
/**
@@ -338,37 +123,29 @@ st_clipboard_get_text (StClipboard *clipboard,
StClipboardCallbackFunc callback,
gpointer user_data)
{
- EventFilterData *data;
- GdkDisplay *gdk_display;
- Display *dpy;
+ MetaSelectionType selection_type;
+ MetaDisplay *display;
+ TransferData *data;
g_return_if_fail (ST_IS_CLIPBOARD (clipboard));
g_return_if_fail (callback != NULL);
- data = g_new0 (EventFilterData, 1);
+ if (!convert_type (type, &selection_type))
+ return;
+
+ data = g_new0 (TransferData, 1);
data->clipboard = clipboard;
data->callback = callback;
data->user_data = user_data;
-
- gdk_window_add_filter (NULL, /* all windows */
- st_clipboard_x11_event_filter,
- data);
-
- gdk_display = gdk_display_get_default ();
- dpy = GDK_DISPLAY_XDISPLAY (gdk_display);
-
- gdk_x11_display_error_trap_push (gdk_display);
-
- XConvertSelection (dpy,
- atom_for_clipboard_type (type),
- __utf8_string, __utf8_string,
- clipboard->priv->clipboard_window,
- CurrentTime);
-
- if (gdk_x11_display_error_trap_pop (gdk_display))
- {
- /* FIXME */
- }
+ data->stream = g_memory_output_stream_new_resizable ();
+
+ display = meta_get_display ();
+ meta_selection_transfer_async (meta_display_get_selection (display),
+ selection_type,
+ "text/plain;charset=utf-8", -1,
+ data->stream, NULL,
+ (GAsyncReadyCallback) transfer_cb,
+ data);
}
/**
@@ -384,31 +161,22 @@ st_clipboard_set_text (StClipboard *clipboard,
StClipboardType type,
const gchar *text)
{
- StClipboardPrivate *priv;
- GdkDisplay *gdk_display;
- Display *dpy;
+ MetaSelectionType selection_type;
+ MetaSelectionSource *source;
+ MetaDisplay *display;
+ GBytes *bytes;
g_return_if_fail (ST_IS_CLIPBOARD (clipboard));
g_return_if_fail (text != NULL);
- priv = clipboard->priv;
+ if (!convert_type (type, &selection_type))
+ return;
- /* make a copy of the text */
- g_free (priv->clipboard_text);
- priv->clipboard_text = g_strdup (text);
+ bytes = g_bytes_new_take (g_strdup (text), strlen (text));
+ source = meta_selection_source_memory_new ("text/plain;charset=utf-8", bytes);
+ g_bytes_unref (bytes);
- /* tell X we own the clipboard selection */
- gdk_display = gdk_display_get_default ();
- dpy = GDK_DISPLAY_XDISPLAY (gdk_display);
-
- gdk_x11_display_error_trap_push (gdk_display);
-
- XSetSelectionOwner (dpy, atom_for_clipboard_type (type), priv->clipboard_window, CurrentTime);
-
- XSync (dpy, FALSE);
-
- if (gdk_x11_display_error_trap_pop (gdk_display))
- {
- /* FIXME */
- }
+ display = meta_get_display ();
+ meta_selection_set_owner (meta_display_get_selection (display),
+ selection_type, source);
}
diff --git a/src/st/st-clipboard.h b/src/st/st-clipboard.h
index 9ea412e3b..71d046c74 100644
--- a/src/st/st-clipboard.h
+++ b/src/st/st-clipboard.h
@@ -32,7 +32,6 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (StClipboard, st_clipboard, ST, CLIPBOARD, GObject)
typedef struct _StClipboard StClipboard;
-typedef struct _StClipboardPrivate StClipboardPrivate;
/**
* StClipboard:
@@ -44,7 +43,6 @@ struct _StClipboard
{
/*< private >*/
GObject parent;
- StClipboardPrivate *priv;
};
typedef enum {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]