[gnome-remote-desktop] clipboard: Split up SelectionTransfer handling
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-remote-desktop] clipboard: Split up SelectionTransfer handling
- Date: Wed, 24 Nov 2021 18:04:39 +0000 (UTC)
commit 8e855503eb6eae84d71498c896fe6ebb78c91100
Author: Pascal Nowack <Pascal Nowack gmx de>
Date: Thu Oct 28 10:37:55 2021 +0200
clipboard: Split up SelectionTransfer handling
Currently, when gnome-remote-desktop handles a SelectionTransfer-
signal, the mime type content is requested synchronously from the
respective backend.
Since this process is done synchronously, the main thread is blocked
and cannot handle any other events, such as input events.
With additional network latency, this becomes worse.
To allow the backend implementations to transform to an asynchronous
implementation, split up the SelectionTransfer handling.
The signal will now just emit the request on the backend and the
backend will, when it has the response ready submit the response
itself.
Both the RDP and VNC backend will currently still function as before,
as the handling is just split up.
Since the VNC backend does not support delayed rendering of clipboard
data, no further changes will happen for the VNC backend.
The RDP backend, on the other hand, will be reworked in the next commit
to handle mime type content requests asynchronously.
src/grd-clipboard-rdp.c | 32 +++++++++++-----
src/grd-clipboard-vnc.c | 13 ++++---
src/grd-clipboard.c | 45 +++++++++++++++--------
src/grd-clipboard.h | 19 ++++++----
src/grd-session.c | 97 ++++++++++++++++++++++++++++---------------------
src/grd-session.h | 7 +++-
6 files changed, 133 insertions(+), 80 deletions(-)
---
diff --git a/src/grd-clipboard-rdp.c b/src/grd-clipboard-rdp.c
index f4091a7..ec8df70 100644
--- a/src/grd-clipboard-rdp.c
+++ b/src/grd-clipboard-rdp.c
@@ -819,10 +819,10 @@ convert_client_content_for_server (GrdClipboardRdp *clipboard_rdp,
return dst_data;
}
-static uint8_t *
+static void
grd_clipboard_rdp_request_client_content_for_mime_type (GrdClipboard *clipboard,
GrdMimeTypeTable *mime_type_table,
- uint32_t *size)
+ unsigned int serial)
{
GrdClipboardRdp *clipboard_rdp = GRD_CLIPBOARD_RDP (clipboard);
GrdRdpFuseClipboard *rdp_fuse_clipboard = clipboard_rdp->rdp_fuse_clipboard;
@@ -833,9 +833,12 @@ grd_clipboard_rdp_request_client_content_for_mime_type (GrdClipboard *clipbo
uint32_t src_size, dst_size;
uint32_t clip_data_id = 0;
- *size = 0;
if (mime_type == GRD_MIME_TYPE_NONE)
- return NULL;
+ {
+ grd_clipboard_submit_client_content_for_mime_type (clipboard, serial,
+ NULL, 0);
+ return;
+ }
if (g_hash_table_contains (clipboard_rdp->format_data_cache,
GUINT_TO_POINTER (mime_type)))
@@ -844,13 +847,19 @@ grd_clipboard_rdp_request_client_content_for_mime_type (GrdClipboard *clipbo
format_data = g_hash_table_lookup (clipboard_rdp->format_data_cache,
GUINT_TO_POINTER (mime_type));
- *size = format_data->size;
- return g_memdup2 (format_data->data, format_data->size);
+ grd_clipboard_submit_client_content_for_mime_type (clipboard, serial,
+ format_data->data,
+ format_data->size);
+ return;
}
if (WaitForSingleObject (completed_format_list_event, 0) == WAIT_TIMEOUT)
- return NULL;
+ {
+ grd_clipboard_submit_client_content_for_mime_type (clipboard, serial,
+ NULL, 0);
+ return;
+ }
if (clipboard_rdp->cliprdr_context->canLockClipData &&
(mime_type == GRD_MIME_TYPE_TEXT_URILIST ||
@@ -866,7 +875,9 @@ grd_clipboard_rdp_request_client_content_for_mime_type (GrdClipboard *clipbo
mime_type == GRD_MIME_TYPE_XS_GNOME_COPIED_FILES))
grd_rdp_fuse_clipboard_clip_data_id_free (rdp_fuse_clipboard, clip_data_id);
- return NULL;
+ grd_clipboard_submit_client_content_for_mime_type (clipboard, serial,
+ NULL, 0);
+ return;
}
dst_data = NULL;
@@ -899,7 +910,7 @@ grd_clipboard_rdp_request_client_content_for_mime_type (GrdClipboard *clipbo
{
FormatData *format_data = g_malloc0 (sizeof (FormatData));
- format_data->size = *size = dst_size;
+ format_data->size = dst_size;
format_data->data = dst_data;
g_hash_table_insert (clipboard_rdp->format_data_cache,
@@ -909,7 +920,8 @@ grd_clipboard_rdp_request_client_content_for_mime_type (GrdClipboard *clipbo
g_free (src_data);
- return g_memdup2 (dst_data, dst_size);
+ grd_clipboard_submit_client_content_for_mime_type (clipboard, serial,
+ dst_data, dst_size);
}
static void
diff --git a/src/grd-clipboard-vnc.c b/src/grd-clipboard-vnc.c
index d0a8df4..ca6daba 100644
--- a/src/grd-clipboard-vnc.c
+++ b/src/grd-clipboard-vnc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 Pascal Nowack
+ * Copyright (C) 2020-2021 Pascal Nowack
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -79,16 +79,17 @@ grd_clipboard_vnc_update_client_mime_type_list (GrdClipboard *clipboard,
g_list_free (mime_type_list);
}
-static uint8_t *
+static void
grd_clipboard_vnc_request_client_content_for_mime_type (GrdClipboard *clipboard,
GrdMimeTypeTable *mime_type_table,
- uint32_t *size)
+ unsigned int serial)
{
GrdClipboardVnc *clipboard_vnc = GRD_CLIPBOARD_VNC (clipboard);
+ uint32_t size;
- *size = strlen (clipboard_vnc->clipboard_utf8_string);
-
- return g_memdup2 (clipboard_vnc->clipboard_utf8_string, *size);
+ size = strlen (clipboard_vnc->clipboard_utf8_string);
+ grd_clipboard_submit_client_content_for_mime_type (
+ clipboard, serial, (uint8_t *) clipboard_vnc->clipboard_utf8_string, size);
}
static void
diff --git a/src/grd-clipboard.c b/src/grd-clipboard.c
index 1b1e40e..81b9155 100644
--- a/src/grd-clipboard.c
+++ b/src/grd-clipboard.c
@@ -396,36 +396,51 @@ grd_clipboard_update_client_mime_type_list (GrdClipboard *clipboard,
g_debug ("Clipboard[SelectionOwnerChanged]: Update complete");
}
-uint8_t *
+void
+grd_clipboard_submit_client_content_for_mime_type (GrdClipboard *clipboard,
+ unsigned int serial,
+ const uint8_t *data,
+ uint32_t size)
+{
+ GrdClipboardPrivate *priv = grd_clipboard_get_instance_private (clipboard);
+
+ g_assert (priv->enabled);
+
+ if (data && size)
+ g_debug ("Clipboard[SelectionTransfer]: Request for serial %u was successful", serial);
+ else
+ g_debug ("Clipboard[SelectionTransfer]: Request for serial %u failed", serial);
+
+ grd_session_selection_write (priv->session, serial, data, size);
+}
+
+void
grd_clipboard_request_client_content_for_mime_type (GrdClipboard *clipboard,
GrdMimeType mime_type,
- uint32_t *size)
+ unsigned int serial)
{
GrdClipboardClass *klass = GRD_CLIPBOARD_GET_CLASS (clipboard);
GrdClipboardPrivate *priv = grd_clipboard_get_instance_private (clipboard);
GrdMimeTypeTable *mime_type_table = NULL;
- uint8_t *mime_type_content = NULL;
- *size = 0;
+ g_assert (priv->enabled);
- if (!klass->request_client_content_for_mime_type)
- return NULL;
+ g_return_if_fail (klass->request_client_content_for_mime_type);
g_debug ("Clipboard[SelectionTransfer]: Requesting data from clients clipboard"
- " (mime type: %s)", grd_mime_type_to_string (mime_type));
+ " (mime type: %s, serial: %u)",
+ grd_mime_type_to_string (mime_type), serial);
mime_type_table = g_hash_table_lookup (priv->client_mime_type_tables,
GUINT_TO_POINTER (mime_type));
- if (mime_type_table)
+ if (!mime_type_table)
{
- mime_type_content = klass->request_client_content_for_mime_type (
- clipboard, mime_type_table, size);
+ grd_clipboard_submit_client_content_for_mime_type (clipboard, serial,
+ NULL, 0);
+ return;
}
- if (mime_type_content)
- g_debug ("Clipboard[SelectionTransfer]: Request successful");
- else
- g_debug ("Clipboard[SelectionTransfer]: Request failed");
- return mime_type_content;
+ klass->request_client_content_for_mime_type (clipboard, mime_type_table,
+ serial);
}
static void
diff --git a/src/grd-clipboard.h b/src/grd-clipboard.h
index 93249d0..81bfe1b 100644
--- a/src/grd-clipboard.h
+++ b/src/grd-clipboard.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 Pascal Nowack
+ * Copyright (C) 2020-2021 Pascal Nowack
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -35,9 +35,9 @@ struct _GrdClipboardClass
void (*update_client_mime_type_list) (GrdClipboard *clipboard,
GList *mime_type_list);
- uint8_t *(*request_client_content_for_mime_type) (GrdClipboard *clipboard,
- GrdMimeTypeTable *mime_type_table,
- uint32_t *size);
+ void (*request_client_content_for_mime_type) (GrdClipboard *clipboard,
+ GrdMimeTypeTable *mime_type_table,
+ unsigned int serial);
void (*submit_requested_server_content) (GrdClipboard *clipboard,
uint8_t *data,
uint32_t size);
@@ -59,8 +59,13 @@ void grd_clipboard_disable_clipboard (GrdClipboard *clipboard);
void grd_clipboard_update_client_mime_type_list (GrdClipboard *clipboard,
GList *mime_type_list);
-uint8_t *grd_clipboard_request_client_content_for_mime_type (GrdClipboard *clipboard,
- GrdMimeType mime_type,
- uint32_t *size);
+void grd_clipboard_submit_client_content_for_mime_type (GrdClipboard *clipboard,
+ unsigned int serial,
+ const uint8_t *data,
+ uint32_t size);
+
+void grd_clipboard_request_client_content_for_mime_type (GrdClipboard *clipboard,
+ GrdMimeType mime_type,
+ unsigned int serial);
#endif /* GRD_CLIPBOARD_H */
diff --git a/src/grd-session.c b/src/grd-session.c
index 0bcc9bf..39d7410 100644
--- a/src/grd-session.c
+++ b/src/grd-session.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 Red Hat Inc.
- * Copyright (C) 2020 Pascal Nowack
+ * Copyright (C) 2020-2021 Pascal Nowack
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -325,6 +325,59 @@ acquire_fd_from_list (GUnixFDList *fd_list,
return fd;
}
+void
+grd_session_selection_write (GrdSession *session,
+ unsigned int serial,
+ const uint8_t *data,
+ uint32_t size)
+{
+ GrdSessionPrivate *priv = grd_session_get_instance_private (session);
+ g_autoptr (GError) error = NULL;
+ g_autoptr (GVariant) fd_variant = NULL;
+ g_autoptr (GUnixFDList) fd_list = NULL;
+ int fd_idx;
+ int fd;
+
+ if (!data || !size)
+ {
+ grd_dbus_remote_desktop_session_call_selection_write_done (
+ priv->remote_desktop_session, serial, FALSE, NULL, NULL, NULL);
+ return;
+ }
+
+ if (!grd_dbus_remote_desktop_session_call_selection_write_sync (
+ priv->remote_desktop_session, serial, NULL, &fd_variant, &fd_list,
+ NULL, &error))
+ {
+ g_warning ("Failed to write selection for serial %u: %s",
+ serial, error->message);
+ return;
+ }
+
+ g_variant_get (fd_variant, "h", &fd_idx);
+ fd = acquire_fd_from_list (fd_list, fd_idx, &error);
+ if (fd == -1)
+ {
+ g_warning ("Failed to acquire file descriptor for serial %u: %s",
+ serial, error->message);
+ return;
+ }
+
+ if (write (fd, data, size) < 0)
+ {
+ grd_dbus_remote_desktop_session_call_selection_write_done (
+ priv->remote_desktop_session, serial, FALSE, NULL, NULL, NULL);
+
+ close (fd);
+ return;
+ }
+
+ grd_dbus_remote_desktop_session_call_selection_write_done (
+ priv->remote_desktop_session, serial, TRUE, NULL, NULL, NULL);
+
+ close (fd);
+}
+
int
grd_session_selection_read (GrdSession *session,
GrdMimeType mime_type)
@@ -617,13 +670,6 @@ on_remote_desktop_session_selection_transfer (GrdDBusRemoteDesktopSession *sessi
GrdSession *session)
{
GrdSessionPrivate *priv = grd_session_get_instance_private (session);
- uint8_t *data;
- uint32_t size;
- g_autoptr (GError) error = NULL;
- g_autoptr (GVariant) fd_variant = NULL;
- g_autoptr (GUnixFDList) fd_list = NULL;
- int fd_idx;
- int fd;
GrdMimeType mime_type;
if (!priv->clipboard)
@@ -637,39 +683,8 @@ on_remote_desktop_session_selection_transfer (GrdDBusRemoteDesktopSession *sessi
return;
}
- if (!grd_dbus_remote_desktop_session_call_selection_write_sync (
- priv->remote_desktop_session, serial, NULL, &fd_variant, &fd_list,
- NULL, &error))
- {
- g_warning ("Failed to write selection: %s", error->message);
- return;
- }
-
- g_variant_get (fd_variant, "h", &fd_idx);
- fd = acquire_fd_from_list (fd_list, fd_idx, &error);
- if (fd == -1)
- {
- g_warning ("Failed to acquire file descriptor: %s", error->message);
- return;
- }
-
- data = grd_clipboard_request_client_content_for_mime_type (priv->clipboard,
- mime_type, &size);
- if (!size || write (fd, data, size) < 0)
- {
- grd_dbus_remote_desktop_session_call_selection_write_done (
- priv->remote_desktop_session, serial, FALSE, NULL, NULL, NULL);
-
- close (fd);
- g_free (data);
- return;
- }
-
- grd_dbus_remote_desktop_session_call_selection_write_done (
- priv->remote_desktop_session, serial, TRUE, NULL, NULL, NULL);
-
- close (fd);
- g_free (data);
+ grd_clipboard_request_client_content_for_mime_type (priv->clipboard,
+ mime_type, serial);
}
static void
diff --git a/src/grd-session.h b/src/grd-session.h
index cc0d136..cca7d9e 100644
--- a/src/grd-session.h
+++ b/src/grd-session.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 Red Hat Inc.
- * Copyright (C) 2020 Pascal Nowack
+ * Copyright (C) 2020-2021 Pascal Nowack
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -110,6 +110,11 @@ void grd_session_disable_clipboard (GrdSession *session);
void grd_session_set_selection (GrdSession *session,
GList *mime_type_tables);
+void grd_session_selection_write (GrdSession *session,
+ unsigned int serial,
+ const uint8_t *data,
+ uint32_t size);
+
int grd_session_selection_read (GrdSession *session,
GrdMimeType mime_type);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]