From f0bb54079798e9e5cfb4fba4cef93873e4d32f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 30 Aug 2023 21:37:44 +0200 Subject: [PATCH] remote-desktop/session: Add regions for all monitors if input-only If we're a input-only remote desktop session, create libei regions on an absolute pointer device corresponding to all logical monitors. This allows absolute pointer motions without screen casting. Part-of: --- src/backends/meta-eis-client.c | 4 +- src/backends/meta-eis.c | 15 ++ src/backends/meta-eis.h | 5 + src/backends/meta-remote-desktop-session.c | 171 +++++++++++++++++++++ 4 files changed, 193 insertions(+), 2 deletions(-) diff --git a/src/backends/meta-eis-client.c b/src/backends/meta-eis-client.c index 59ed2082a..ad0e219d3 100644 --- a/src/backends/meta-eis-client.c +++ b/src/backends/meta-eis-client.c @@ -272,8 +272,8 @@ add_viewport_region (struct eis_device *eis_device, eis_region_set_physical_scale (eis_region, scale); mapping_id = meta_eis_viewport_get_mapping_id (viewport); - g_warn_if_fail (mapping_id); - eis_region_set_mapping_id (eis_region, mapping_id); + if (mapping_id) + eis_region_set_mapping_id (eis_region, mapping_id); eis_region_set_user_data (eis_region, viewport); eis_region_add (eis_region); diff --git a/src/backends/meta-eis.c b/src/backends/meta-eis.c index 9d1649961..e51e9582a 100644 --- a/src/backends/meta-eis.c +++ b/src/backends/meta-eis.c @@ -331,6 +331,21 @@ meta_eis_remove_viewport (MetaEis *eis, g_signal_emit (eis, signals[VIEWPORTS_CHANGED], 0); } +void +meta_eis_take_viewports (MetaEis *eis, + GList *viewports) +{ + eis->viewports = g_list_concat (eis->viewports, viewports); + g_signal_emit (eis, signals[VIEWPORTS_CHANGED], 0); +} + +void +meta_eis_remove_all_viewports (MetaEis *eis) +{ + g_clear_pointer (&eis->viewports, g_list_free); + g_signal_emit (eis, signals[VIEWPORTS_CHANGED], 0); +} + GList * meta_eis_peek_viewports (MetaEis *eis) { diff --git a/src/backends/meta-eis.h b/src/backends/meta-eis.h index e915c576e..95b93bdf7 100644 --- a/src/backends/meta-eis.h +++ b/src/backends/meta-eis.h @@ -50,6 +50,11 @@ void meta_eis_add_viewport (MetaEis *eis, void meta_eis_remove_viewport (MetaEis *eis, MetaEisViewport *viewport); +void meta_eis_take_viewports (MetaEis *eis, + GList *viewports); + +void meta_eis_remove_all_viewports (MetaEis *eis); + GList * meta_eis_peek_viewports (MetaEis *eis); MetaEisDeviceTypes meta_eis_get_device_types (MetaEis *eis); diff --git a/src/backends/meta-remote-desktop-session.c b/src/backends/meta-remote-desktop-session.c index ec35e719f..08a441d24 100644 --- a/src/backends/meta-remote-desktop-session.c +++ b/src/backends/meta-remote-desktop-session.c @@ -34,6 +34,7 @@ #include "backends/meta-dbus-session-watcher.h" #include "backends/meta-dbus-session-manager.h" #include "backends/meta-eis.h" +#include "backends/meta-logical-monitor.h" #include "backends/meta-screen-cast-session.h" #include "backends/meta-remote-access-controller-private.h" #include "backends/x11/meta-backend-x11.h" @@ -104,6 +105,8 @@ struct _MetaRemoteDesktopSession guint transfer_request_timeout_id; GHashTable *mapping_ids; + + gulong monitors_changed_handler_id; }; static void initable_init_iface (GInitableIface *iface); @@ -135,9 +138,124 @@ G_DEFINE_TYPE (MetaRemoteDesktopSessionHandle, meta_remote_desktop_session_handle, META_TYPE_REMOTE_ACCESS_HANDLE) +struct _MetaLogicalMonitorViewport +{ + GObject parent; + + MetaLogicalMonitor *logical_monitor; +}; + +#define META_TYPE_LOGICAL_MONITOR_VIEWPORT (meta_logical_monitor_viewport_get_type ()) +G_DECLARE_FINAL_TYPE (MetaLogicalMonitorViewport, meta_logical_monitor_viewport, + META, LOGICAL_MONITOR_VIEWPORT, + GObject) + +static void meta_eis_viewport_init_iface (MetaEisViewportInterface *iface); + +G_DEFINE_FINAL_TYPE_WITH_CODE (MetaLogicalMonitorViewport, + meta_logical_monitor_viewport, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (META_TYPE_EIS_VIEWPORT, + meta_eis_viewport_init_iface)) + static MetaRemoteDesktopSessionHandle * meta_remote_desktop_session_handle_new (MetaRemoteDesktopSession *session); +static gboolean +meta_logical_monitor_viewport_is_standalone (MetaEisViewport *viewport) +{ + return FALSE; +} + +static const char * +meta_logical_monitor_viewport_get_mapping_id (MetaEisViewport *viewport) +{ + return NULL; +} + +static gboolean +meta_logical_monitor_viewport_get_position (MetaEisViewport *viewport, + int *out_x, + int *out_y) +{ + MetaLogicalMonitorViewport *logical_monitor_viewport = + META_LOGICAL_MONITOR_VIEWPORT (viewport); + MtkRectangle layout; + + layout = meta_logical_monitor_get_layout (logical_monitor_viewport->logical_monitor); + *out_x = layout.x; + *out_y = layout.y; + return TRUE; +} + +static void +meta_logical_monitor_viewport_get_size (MetaEisViewport *viewport, + int *out_width, + int *out_height) +{ + MetaLogicalMonitorViewport *logical_monitor_viewport = + META_LOGICAL_MONITOR_VIEWPORT (viewport); + MtkRectangle layout; + + layout = meta_logical_monitor_get_layout (logical_monitor_viewport->logical_monitor); + *out_width = layout.width; + *out_height = layout.height; +} + +static double +meta_logical_monitor_viewport_get_physical_scale (MetaEisViewport *viewport) +{ + MetaLogicalMonitorViewport *logical_monitor_viewport = + META_LOGICAL_MONITOR_VIEWPORT (viewport); + + return meta_logical_monitor_get_scale (logical_monitor_viewport->logical_monitor); +} + +static gboolean +meta_logical_monitor_viewport_transform_coordinate (MetaEisViewport *viewport, + double x, + double y, + double *out_x, + double *out_y) +{ + *out_x = x; + *out_y = y; + return TRUE; +} + +static void +meta_eis_viewport_init_iface (MetaEisViewportInterface *eis_viewport_iface) +{ + eis_viewport_iface->is_standalone = meta_logical_monitor_viewport_is_standalone; + eis_viewport_iface->get_mapping_id = meta_logical_monitor_viewport_get_mapping_id; + eis_viewport_iface->get_position = meta_logical_monitor_viewport_get_position; + eis_viewport_iface->get_size = meta_logical_monitor_viewport_get_size; + eis_viewport_iface->get_physical_scale = meta_logical_monitor_viewport_get_physical_scale; + eis_viewport_iface->transform_coordinate = meta_logical_monitor_viewport_transform_coordinate; +} + +static void +meta_logical_monitor_viewport_class_init (MetaLogicalMonitorViewportClass *klass) +{ +} + +static void +meta_logical_monitor_viewport_init (MetaLogicalMonitorViewport *logical_monitor_viewport) +{ +} + +static MetaLogicalMonitorViewport * +meta_logical_monitor_viewport_new (MetaLogicalMonitor *logical_monitor) +{ + MetaLogicalMonitorViewport *logical_monitor_viewport; + + logical_monitor_viewport = g_object_new (META_TYPE_LOGICAL_MONITOR_VIEWPORT, + NULL); + logical_monitor_viewport->logical_monitor = logical_monitor; + + return logical_monitor_viewport; +} + static MetaDisplay * display_from_session (MetaRemoteDesktopSession *session) { @@ -219,6 +337,40 @@ on_stream_removed (MetaScreenCastSession *screen_cast_session, meta_eis_remove_viewport (session->eis, META_EIS_VIEWPORT (stream)); } +static void +add_logical_monitor_viewports (MetaRemoteDesktopSession *session) +{ + MetaBackend *backend = + meta_dbus_session_manager_get_backend (session->session_manager); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *logical_monitors; + GList *l; + GList *viewports = NULL; + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (l = logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + MetaLogicalMonitorViewport *logical_monitor_viewport; + + logical_monitor_viewport = + meta_logical_monitor_viewport_new (logical_monitor); + viewports = g_list_append (viewports, logical_monitor_viewport); + } + + meta_eis_remove_all_viewports (session->eis); + meta_eis_take_viewports (session->eis, viewports); +} + +static void +on_monitors_changed (MetaMonitorManager *monitor_manager, + MetaRemoteDesktopSession *session) +{ + add_logical_monitor_viewports (session); +} + static void initialize_viewports (MetaRemoteDesktopSession *session) { @@ -245,6 +397,18 @@ initialize_viewports (MetaRemoteDesktopSession *session) G_CALLBACK (on_stream_removed), session); } + else + { + MetaBackend *backend = + meta_dbus_session_manager_get_backend (session->session_manager); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + + add_logical_monitor_viewports (session); + session->monitors_changed_handler_id = + g_signal_connect (monitor_manager, "monitors-changed", + G_CALLBACK (on_monitors_changed), session); + } } static gboolean @@ -275,6 +439,10 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session) META_REMOTE_DESKTOP_SESSION (dbus_session); MetaDBusRemoteDesktopSession *skeleton = META_DBUS_REMOTE_DESKTOP_SESSION (session); + MetaBackend *backend = + meta_dbus_session_manager_get_backend (session->session_manager); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); session->started = FALSE; @@ -289,6 +457,9 @@ meta_remote_desktop_session_close (MetaDbusSession *dbus_session) session->screen_cast_session = NULL; } + g_clear_signal_handler (&session->monitors_changed_handler_id, + monitor_manager); + g_clear_object (&session->virtual_pointer); g_clear_object (&session->virtual_keyboard); g_clear_object (&session->virtual_touchscreen);