[gtk+] x11: Various clipboard cleanups



commit fe9045d82e1c7ee6478e668f59757adec1e8b07f
Author: Benjamin Otte <otte redhat com>
Date:   Sun Nov 19 19:52:07 2017 +0100

    x11: Various clipboard cleanups
    
    (1) Turn X11 clipboard event handling into a regular filter function
    (2) Maintain a timestamp in the clipboard, so we can pass it when
        querying selections.

 gdk/x11/gdkclipboard-x11.c            |  122 +++++++++++++++++++--------------
 gdk/x11/gdkclipboard-x11.h            |    4 -
 gdk/x11/gdkdisplay-x11.c              |   28 +++-----
 gdk/x11/gdkselectioninputstream-x11.c |    7 +-
 gdk/x11/gdkselectioninputstream-x11.h |    3 +-
 5 files changed, 87 insertions(+), 77 deletions(-)
---
diff --git a/gdk/x11/gdkclipboard-x11.c b/gdk/x11/gdkclipboard-x11.c
index eb2f6d1..28def4e 100644
--- a/gdk/x11/gdkclipboard-x11.c
+++ b/gdk/x11/gdkclipboard-x11.c
@@ -41,7 +41,7 @@ struct _GdkX11Clipboard
 
   char       *selection;
   Atom        xselection;
-  guint32     time;
+  guint32     timestamp;
 };
 
 struct _GdkX11ClipboardClass
@@ -51,30 +51,6 @@ struct _GdkX11ClipboardClass
 
 G_DEFINE_TYPE (GdkX11Clipboard, gdk_x11_clipboard, GDK_TYPE_CLIPBOARD)
 
-static void
-gdk_x11_clipboard_finalize (GObject *object)
-{
-  GdkX11Clipboard *cb = GDK_X11_CLIPBOARD (object);
-
-  g_free (cb->selection);
-
-  G_OBJECT_CLASS (gdk_x11_clipboard_parent_class)->finalize (object);
-}
-
-static void
-gdk_x11_clipboard_class_init (GdkX11ClipboardClass *class)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-  //GdkClipboardClass *clipboard_class = GDK_CLIPBOARD_CLASS (class);
-
-  object_class->finalize = gdk_x11_clipboard_finalize;
-}
-
-static void
-gdk_x11_clipboard_init (GdkX11Clipboard *clipboard)
-{
-}
-
 #define SELECTION_MAX_SIZE(display)                                     \
   MIN(262144,                                                           \
       XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0     \
@@ -141,7 +117,8 @@ gdk_x11_clipboard_request_targets (GdkX11Clipboard *cb)
 
   stream = gdk_x11_selection_input_stream_new (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)),
                                                cb->selection,
-                                               "TARGETS");
+                                               "TARGETS",
+                                               cb->timestamp);
 
   g_input_stream_read_bytes_async (stream,
                                    SELECTION_MAX_SIZE (display),
@@ -151,6 +128,73 @@ gdk_x11_clipboard_request_targets (GdkX11Clipboard *cb)
                                    g_object_ref (cb));
 }
 
+static GdkFilterReturn
+gdk_x11_clipboard_filter_event (GdkXEvent *xev,
+                                GdkEvent  *gdkevent,
+                                gpointer   data)
+{
+  GdkX11Clipboard *cb = GDK_X11_CLIPBOARD (data);
+  GdkDisplay *display;
+  XEvent *xevent = xev;
+  Window xwindow;
+
+  display = gdk_clipboard_get_display (GDK_CLIPBOARD (cb));
+  xwindow = GDK_X11_DISPLAY (display)->leader_window;
+
+  if (xevent->xany.window != xwindow)
+    return GDK_FILTER_CONTINUE;
+
+  switch (xevent->type)
+  {
+    default:
+#ifdef HAVE_XFIXES
+      if (xevent->type - GDK_X11_DISPLAY (display)->xfixes_event_base == XFixesSelectionNotify)
+       {
+         XFixesSelectionNotifyEvent *sn = (XFixesSelectionNotifyEvent *) xevent;
+
+          if (sn->selection == cb->xselection)
+            {
+              GdkContentFormats *empty;
+              
+              GDK_NOTE(CLIPBOARD, g_printerr ("%s: got FixesSelectionNotify\n", cb->selection));
+              empty = gdk_content_formats_new (NULL, 0);
+              gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb), empty);
+              gdk_content_formats_unref (empty);
+              cb->timestamp = sn->selection_timestamp;
+              gdk_x11_clipboard_request_targets (cb);
+            }
+        }
+#endif
+      return GDK_FILTER_CONTINUE;
+  }
+}
+
+static void
+gdk_x11_clipboard_finalize (GObject *object)
+{
+  GdkX11Clipboard *cb = GDK_X11_CLIPBOARD (object);
+
+  gdk_window_remove_filter (NULL, gdk_x11_clipboard_filter_event, cb);
+  g_free (cb->selection);
+
+  G_OBJECT_CLASS (gdk_x11_clipboard_parent_class)->finalize (object);
+}
+
+static void
+gdk_x11_clipboard_class_init (GdkX11ClipboardClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  //GdkClipboardClass *clipboard_class = GDK_CLIPBOARD_CLASS (class);
+
+  object_class->finalize = gdk_x11_clipboard_finalize;
+}
+
+static void
+gdk_x11_clipboard_init (GdkX11Clipboard *cb)
+{
+  cb->timestamp = CurrentTime;
+}
+
 GdkClipboard *
 gdk_x11_clipboard_new (GdkDisplay  *display,
                        const gchar *selection)
@@ -165,33 +209,9 @@ gdk_x11_clipboard_new (GdkDisplay  *display,
   cb->xselection = gdk_x11_get_xatom_by_name_for_display (display, selection);
 
   gdk_display_request_selection_notification (display, gdk_atom_intern (selection, FALSE));
+  gdk_window_add_filter (NULL, gdk_x11_clipboard_filter_event, cb);
   gdk_x11_clipboard_request_targets (cb);
 
   return GDK_CLIPBOARD (cb);
 }
 
-gboolean
-gdk_x11_clipboard_handle_event (GdkX11Clipboard *cb,
-                                XEvent          *xevent)
-{
-  return FALSE;
-}
-
-gboolean
-gdk_x11_clipboard_handle_selection_notify (GdkX11Clipboard *cb,
-                                           XEvent          *xevent)
-{
-#ifdef HAVE_XFIXES
-  GdkDisplay *display = gdk_clipboard_get_display (GDK_CLIPBOARD (cb));
-  XFixesSelectionNotifyEvent *event = (XFixesSelectionNotifyEvent *)xevent;
-
-  if (event->window != GDK_X11_DISPLAY (display)->leader_window ||
-      event->selection != cb->xselection)
-    return FALSE;
-
-  return TRUE;
-#else
-  return FALSE;
-#endif
-}
-
diff --git a/gdk/x11/gdkclipboard-x11.h b/gdk/x11/gdkclipboard-x11.h
index fa8485d..a4ed9d4 100644
--- a/gdk/x11/gdkclipboard-x11.h
+++ b/gdk/x11/gdkclipboard-x11.h
@@ -36,10 +36,6 @@ GType                   gdk_x11_clipboard_get_type              (void) G_GNUC_CO
 GdkClipboard *          gdk_x11_clipboard_new                   (GdkDisplay             *display,
                                                                  const gchar            *selection);
 
-gboolean                gdk_x11_clipboard_handle_event          (GdkX11Clipboard        *clipboard,
-                                                                 XEvent                 *xevent);
-gboolean                gdk_x11_clipboard_handle_selection_notify(GdkX11Clipboard       *clipboard,
-                                                                 XEvent                 *xevent);
 
 G_END_DECLS
 
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 4c4da88..1aecc75 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1142,24 +1142,16 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
               gdk_display_set_composited (display, composited);
             }
 
-          if (gdk_x11_clipboard_handle_selection_notify (GDK_X11_CLIPBOARD (display->clipboard), xevent) ||
-              gdk_x11_clipboard_handle_selection_notify (GDK_X11_CLIPBOARD (display->primary_clipboard), 
xevent))
-            {
-              return_val = FALSE;
-            }
-          else
-            {
-              event->owner_change.type = GDK_OWNER_CHANGE;
-              event->owner_change.window = window;
-              event->owner_change.reason = selection_notify->subtype;
-              event->owner_change.selection =
-                gdk_x11_xatom_to_atom_for_display (display,
-                                                   selection_notify->selection);
-              event->owner_change.time = selection_notify->timestamp;
-              event->owner_change.selection_time = selection_notify->selection_timestamp;
-
-             return_val = TRUE;
-            }
+          event->owner_change.type = GDK_OWNER_CHANGE;
+          event->owner_change.window = window;
+          event->owner_change.reason = selection_notify->subtype;
+          event->owner_change.selection =
+            gdk_x11_xatom_to_atom_for_display (display,
+                                               selection_notify->selection);
+          event->owner_change.time = selection_notify->timestamp;
+          event->owner_change.selection_time = selection_notify->selection_timestamp;
+
+          return_val = TRUE;
        }
       else
 #endif
diff --git a/gdk/x11/gdkselectioninputstream-x11.c b/gdk/x11/gdkselectioninputstream-x11.c
index 9a4965c..e4704ab 100644
--- a/gdk/x11/gdkselectioninputstream-x11.c
+++ b/gdk/x11/gdkselectioninputstream-x11.c
@@ -134,7 +134,7 @@ gdk_x11_selection_input_stream_complete (GdkX11SelectionInputStream *stream)
   gdk_x11_selection_input_stream_flush (stream);
 
   GDK_X11_DISPLAY (priv->display)->input_streams = g_slist_remove (GDK_X11_DISPLAY 
(priv->display)->input_streams, stream);
-  gdk_window_remove_filter (GDK_X11_DISPLAY (priv->display)->leader_gdk_window, 
gdk_x11_selection_input_stream_filter_event, stream);
+  gdk_window_remove_filter (NULL, gdk_x11_selection_input_stream_filter_event, stream);
 
   g_object_unref (stream);
 }
@@ -412,7 +412,8 @@ gdk_x11_selection_input_stream_filter_event (GdkXEvent *xev,
 GInputStream *
 gdk_x11_selection_input_stream_new (GdkDisplay *display,
                                     const char *selection,
-                                    const char *target)
+                                    const char *target,
+                                    guint32     timestamp)
 {
   GdkX11SelectionInputStream *stream;
   GdkX11SelectionInputStreamPrivate *priv;
@@ -436,7 +437,7 @@ gdk_x11_selection_input_stream_new (GdkDisplay *display,
                      priv->xtarget,
                      priv->xproperty,
                      GDK_X11_DISPLAY (display)->leader_window,
-                     CurrentTime);
+                     timestamp);
 
   return g_object_ref (stream);
 }
diff --git a/gdk/x11/gdkselectioninputstream-x11.h b/gdk/x11/gdkselectioninputstream-x11.h
index 9947329..ad4364f 100644
--- a/gdk/x11/gdkselectioninputstream-x11.h
+++ b/gdk/x11/gdkselectioninputstream-x11.h
@@ -52,7 +52,8 @@ GType          gdk_x11_selection_input_stream_get_type      (void) G_GNUC_CONST;
 
 GInputStream * gdk_x11_selection_input_stream_new           (GdkDisplay *display,
                                                              const char *selection,
-                                                             const char *target);
+                                                             const char *target,
+                                                             guint32     timestamp);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]