diff --git a/src/grd-enums.h b/src/grd-enums.h
index 44b181d635c2006418e8bd5c46f12d112119d6a2..59efada65b3f0b11c0f28f7238f9c66192c7439f 100644
--- a/src/grd-enums.h
+++ b/src/grd-enums.h
@@ -27,6 +27,13 @@ typedef enum
GRD_RDP_SCREEN_SHARE_MODE_EXTEND,
} GrdRdpScreenShareMode;
+typedef enum
+{
+ GRD_RDP_CURSOR_MODE_HIDDEN,
+ GRD_RDP_CURSOR_MODE_EMBEDDED,
+ GRD_RDP_CURSOR_MODE_METADATA,
+} GrdRdpCursorMode;
+
typedef enum
{
GRD_VNC_AUTH_METHOD_PROMPT,
diff --git a/src/grd-session-rdp.c b/src/grd-session-rdp.c
index ae21e120ec901aa1a757bfd605be26e7cdc515d3..6efaaddde848092de401cbd5c09898e562f304b4 100644
--- a/src/grd-session-rdp.c
+++ b/src/grd-session-rdp.c
@@ -140,6 +140,7 @@ struct _GrdSessionRdp
GrdRdpSAMFile *sam_file;
uint32_t rdp_error_info;
GrdRdpScreenShareMode screen_share_mode;
+ GrdScreenCastCursorMode cursor_mode;
gboolean session_should_stop;
SessionMetrics session_metrics;
@@ -724,6 +725,24 @@ is_view_only (GrdSessionRdp *session_rdp)
return grd_settings_get_rdp_view_only (settings);
}
+static GrdScreenCastCursorMode
+get_screen_cast_cursor_mode (GrdSessionRdp *session_rdp)
+{
+ GrdContext *context = grd_session_get_context (GRD_SESSION (session_rdp));
+ GrdSettings *settings = grd_context_get_settings (context);
+
+ switch(grd_settings_get_rdp_cursor_mode(settings))
+ {
+ case GRD_RDP_CURSOR_MODE_HIDDEN:
+ return GRD_SCREEN_CAST_CURSOR_MODE_HIDDEN;
+ case GRD_RDP_CURSOR_MODE_EMBEDDED:
+ return GRD_SCREEN_CAST_CURSOR_MODE_EMBEDDED;
+ case GRD_RDP_CURSOR_MODE_METADATA:
+ return GRD_SCREEN_CAST_CURSOR_MODE_METADATA;
+ }
+ return GRD_SCREEN_CAST_CURSOR_MODE_METADATA;
+}
+
static void
get_current_monitor_layout (GrdSessionRdp *session_rdp,
MONITOR_DEF **monitors,
@@ -2280,6 +2299,7 @@ grd_session_rdp_new (GrdRdpServer *rdp_server,
session_rdp->hwaccel_nvidia = hwaccel_nvidia;
session_rdp->screen_share_mode = grd_settings_get_rdp_screen_share_mode (settings);
+ session_rdp->cursor_mode = grd_settings_get_rdp_cursor_mode (settings);
if (!init_rdp_session (session_rdp, username, password, &error))
{
@@ -2536,7 +2556,7 @@ grd_session_rdp_remote_desktop_session_started (GrdSession *session)
if (session_rdp->monitor_config->is_virtual)
{
grd_session_record_virtual (session,
- GRD_SCREEN_CAST_CURSOR_MODE_METADATA,
+ get_screen_cast_cursor_mode(session_rdp),
TRUE);
}
else
@@ -2545,7 +2565,7 @@ grd_session_rdp_remote_desktop_session_started (GrdSession *session)
connector = session_rdp->monitor_config->connectors[0];
grd_session_record_monitor (session, connector,
- GRD_SCREEN_CAST_CURSOR_MODE_METADATA);
+ get_screen_cast_cursor_mode(session_rdp));
}
}
diff --git a/src/grd-settings.c b/src/grd-settings.c
index a95628f544ce3f4a0837bf8d99df7c63c618aed9..b345cc4aba02f4f0f590b057f881b2c2b7811a80 100644
--- a/src/grd-settings.c
+++ b/src/grd-settings.c
@@ -40,6 +40,7 @@ enum
RDP_SERVER_CERT_CHANGED,
RDP_SERVER_KEY_CHANGED,
RDP_VIEW_ONLY_CHANGED,
+ RDP_CURSOR_MODE_CHANGED,
VNC_ENABLED_CHANGED,
VNC_VIEW_ONLY_CHANGED,
VNC_AUTH_METHOD_CHANGED,
@@ -62,6 +63,7 @@ struct _GrdSettings
gboolean is_enabled;
GrdRdpScreenShareMode screen_share_mode;
+ GrdRdpCursorMode cursor_mode;
char *server_cert;
char *server_key;
gboolean view_only;
@@ -117,6 +119,12 @@ grd_settings_get_vnc_screen_share_mode (GrdSettings *settings)
return settings->vnc.screen_share_mode;
}
+GrdRdpCursorMode
+grd_settings_get_rdp_cursor_mode (GrdSettings *settings)
+{
+ return settings->rdp.cursor_mode;
+}
+
char *
grd_settings_get_rdp_server_cert (GrdSettings *settings)
{
@@ -292,6 +300,13 @@ update_rdp_view_only (GrdSettings *settings)
"view-only");
}
+static void
+update_rdp_cursor_mode (GrdSettings *settings)
+{
+ settings->rdp.cursor_mode = g_settings_get_enum (settings->rdp.settings,
+ "cursor-mode");
+}
+
static void
update_vnc_enabled (GrdSettings *settings)
{
@@ -343,6 +358,11 @@ on_rdp_settings_changed (GSettings *rdp_settings,
update_rdp_view_only (settings);
g_signal_emit (settings, signals[RDP_VIEW_ONLY_CHANGED], 0);
}
+ else if (strcmp (key, "cursor-mode") == 0)
+ {
+ update_rdp_cursor_mode (settings);
+ g_signal_emit (settings, signals[RDP_CURSOR_MODE_CHANGED], 0);
+ }
}
static void
@@ -412,6 +432,7 @@ grd_settings_init (GrdSettings *settings)
update_rdp_tls_cert (settings);
update_rdp_tls_key (settings);
update_rdp_view_only (settings);
+ update_rdp_cursor_mode(settings);
update_vnc_enabled (settings);
update_vnc_view_only (settings);
update_vnc_auth_method (settings);
@@ -463,6 +484,13 @@ grd_settings_class_init (GrdSettingsClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
+ signals[RDP_VIEW_ONLY_CHANGED] =
+ g_signal_new ("rdp-cursor-mode-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
signals[VNC_ENABLED_CHANGED] =
g_signal_new ("vnc-enabled-changed",
G_TYPE_FROM_CLASS (klass),
diff --git a/src/grd-settings.h b/src/grd-settings.h
index 1fe641995a7f9ec23c27abc122fd2e25f05d389b..accc08560ac29013b9f4d497dbbfec774fbc261f 100644
--- a/src/grd-settings.h
+++ b/src/grd-settings.h
@@ -66,6 +66,8 @@ gboolean grd_settings_get_rdp_view_only (GrdSettings *settings);
gboolean grd_settings_get_vnc_view_only (GrdSettings *settings);
+GrdRdpCursorMode grd_settings_get_rdp_cursor_mode (GrdSettings *settings);
+
GrdVncAuthMethod grd_settings_get_vnc_auth_method (GrdSettings *settings);
#endif /* GRD_SETTINGS_H */
diff --git a/src/org.gnome.desktop.remote-desktop.gschema.xml.in b/src/org.gnome.desktop.remote-desktop.gschema.xml.in
index 5b39a5de432e4926cf52c5193298ac1bc1cc2e1c..0942360e3b4ff6ff782d8506755d931513c134ed 100644
--- a/src/org.gnome.desktop.remote-desktop.gschema.xml.in
+++ b/src/org.gnome.desktop.remote-desktop.gschema.xml.in
@@ -60,6 +60,21 @@
devices (e.g. mouse and keyboard).
+
+ 'metadata'
+ Method used to capture the cursor
+
+ Controls how the cursor is captured by Mutter to allow hiding the cursor, embedding the local
+ cursor or sending data to enable a remote cursor.
+
+ When using screen-share-mode extend, setting cursor-mode to embedded allows the RDP client
+ to be used as a second monitor, with the local cursor visible.
+
+ * hidden - cursor is not included in the stream
+ * embedded - cursor is included in the framebuffer
+ * metadata - cursor is included as metadata in the PipeWire stream
+
+