eis: Use either standalone or shared devices for absolute input

Sometimes it makes no sense to have a shared pointer device, for example
when they have no set region occupying the global stage coordinate
space. This applies to for example window screen cast based pointer
device regions - they are always local to the window, and have no
position.

We do need shared absolute devices in some cases though, primarily
multi-head remote desktop, where it must be possible to keep a button
reliably pressed when crossing monitors that have their own
corresponding regions.

To handle this, outsource all this policy to the one who drives the
emulated input devices. Remote desktop sessions where the screen casts
correspond to specific monitors (physical or virtual), we need to make
sure they map to the stage coordinate space, while for window screencast
or area screencasts, we create standalone absolute pointer devices with
a single region each.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3228>
This commit is contained in:
Jonas Ådahl
2023-08-28 23:13:16 +02:00
committed by Robert Mader
parent d4559a9ca4
commit 69fad154b9
6 changed files with 324 additions and 70 deletions

View File

@ -38,6 +38,16 @@
#define META_SCREEN_CAST_SESSION_DBUS_PATH "/org/gnome/Mutter/ScreenCast/Session"
enum
{
STREAM_ADDED,
STREAM_REMOVED,
N_SIGNALS,
};
static int signals[N_SIGNALS];
enum
{
PROP_0,
@ -184,6 +194,12 @@ meta_screen_cast_session_close (MetaDbusSession *dbus_session)
g_object_unref (session);
}
GList *
meta_screen_cast_session_peek_streams (MetaScreenCastSession *session)
{
return session->streams;
}
MetaScreenCastStream *
meta_screen_cast_session_get_stream (MetaScreenCastSession *session,
const char *path)
@ -366,6 +382,7 @@ on_stream_closed (MetaScreenCastStream *stream,
MetaScreenCastSession *session)
{
session->streams = g_list_remove (session->streams, stream);
g_signal_emit (session, signals[STREAM_REMOVED], 0, stream);
g_object_unref (stream);
switch (session->session_type)
@ -392,6 +409,16 @@ is_valid_cursor_mode (MetaScreenCastCursorMode cursor_mode)
return FALSE;
}
static void
add_stream (MetaScreenCastSession *session,
MetaScreenCastStream *stream)
{
session->streams = g_list_append (session->streams, stream);
g_signal_emit (session, signals[STREAM_ADDED], 0, stream);
g_signal_connect (stream, "closed", G_CALLBACK (on_stream_closed), session);
}
static gboolean
handle_record_monitor (MetaDBusScreenCastSession *skeleton,
GDBusMethodInvocation *invocation,
@ -484,9 +511,7 @@ handle_record_monitor (MetaDBusScreenCastSession *skeleton,
stream = META_SCREEN_CAST_STREAM (monitor_stream);
stream_path = meta_screen_cast_stream_get_object_path (stream);
session->streams = g_list_append (session->streams, stream);
g_signal_connect (stream, "closed", G_CALLBACK (on_stream_closed), session);
add_stream (session, stream);
meta_dbus_screen_cast_session_complete_record_monitor (skeleton,
invocation,
@ -890,6 +915,23 @@ meta_screen_cast_session_class_init (MetaScreenCastSessionClass *klass)
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, obj_props);
meta_dbus_session_install_properties (object_class, N_PROPS);
signals[STREAM_ADDED] =
g_signal_new ("stream-added",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1,
META_TYPE_SCREEN_CAST_STREAM);
signals[STREAM_REMOVED] =
g_signal_new ("stream-removed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1,
META_TYPE_SCREEN_CAST_STREAM);
}
static gboolean