mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-14 14:20:21 +00:00
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.
This commit is contained in:
parent
a5ab9a9671
commit
fe9045d82e
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
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;
|
||||
}
|
||||
return_val = TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user