[xdg-desktop-portal-gnome] screencast: Add support for 'VIRTUAL' source type
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [xdg-desktop-portal-gnome] screencast: Add support for 'VIRTUAL' source type
- Date: Wed, 10 Nov 2021 18:18:10 +0000 (UTC)
commit 340533035b897d40a2c4e36ccb41ab9cc060d0bc
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Thu Jun 17 09:54:05 2021 +0200
screencast: Add support for 'VIRTUAL' source type
This maps to the 'RecordVirtual' D-Bus method on the mutter screen cast
API.
src/gnomescreencast.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
src/screencast.h | 1 +
src/screencastwidget.c | 44 +++++++++++++++++++++++--
src/screencastwidget.ui | 61 +++++++++++++++++++++++++++++++++++
4 files changed, 189 insertions(+), 2 deletions(-)
---
diff --git a/src/gnomescreencast.c b/src/gnomescreencast.c
index fd80ca7..70938cc 100644
--- a/src/gnomescreencast.c
+++ b/src/gnomescreencast.c
@@ -435,6 +435,84 @@ gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_c
return TRUE;
}
+static gboolean
+gnome_screen_cast_session_record_virtual (GnomeScreenCastSession *gnome_screen_cast_session,
+ ScreenCastSelection *select,
+ GError **error)
+{
+ OrgGnomeMutterScreenCastSession *session_proxy =
+ gnome_screen_cast_session->proxy;
+ GVariantBuilder properties_builder;
+ GVariant *properties;
+ g_autofree char *stream_path = NULL;
+ GDBusConnection *connection;
+ OrgGnomeMutterScreenCastStream *stream_proxy;
+ GnomeScreenCastStream *stream;
+ GVariant *parameters;
+
+ g_variant_builder_init (&properties_builder, G_VARIANT_TYPE_VARDICT);
+ if (select->cursor_mode)
+ {
+ uint32_t gnome_cursor_mode;
+
+ gnome_cursor_mode = cursor_mode_to_gnome_cursor_mode (select->cursor_mode);
+ g_variant_builder_add (&properties_builder, "{sv}",
+ "cursor-mode",
+ g_variant_new_uint32 (gnome_cursor_mode));
+ }
+ properties = g_variant_builder_end (&properties_builder);
+
+ if (!org_gnome_mutter_screen_cast_session_call_record_virtual_sync (session_proxy,
+ properties,
+ &stream_path,
+ NULL,
+ error))
+ return FALSE;
+
+ connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (session_proxy));
+ stream_proxy =
+ org_gnome_mutter_screen_cast_stream_proxy_new_sync (connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ "org.gnome.Mutter.ScreenCast",
+ stream_path,
+ NULL,
+ error);
+ if (!stream_proxy)
+ return FALSE;
+
+ stream = g_object_new (gnome_screen_cast_stream_get_type (), NULL);
+ stream->source_type = SCREEN_CAST_SOURCE_TYPE_VIRTUAL;
+ stream->session = gnome_screen_cast_session;
+ stream->path = g_strdup (stream_path);
+ stream->proxy = stream_proxy;
+
+ parameters = org_gnome_mutter_screen_cast_stream_get_parameters (stream->proxy);
+ if (parameters)
+ {
+ if (g_variant_lookup (parameters, "position", "(ii)",
+ &stream->x, &stream->y))
+ stream->has_position = TRUE;
+ if (g_variant_lookup (parameters, "size", "(ii)",
+ &stream->width, &stream->height))
+ stream->has_size = TRUE;
+ }
+ else
+ {
+ g_warning ("Screen cast stream %s missing parameters",
+ stream->path);
+ }
+
+ g_signal_connect (stream_proxy, "pipewire-stream-added",
+ G_CALLBACK (on_pipewire_stream_added),
+ stream);
+
+ gnome_screen_cast_session->streams =
+ g_list_prepend (gnome_screen_cast_session->streams, stream);
+ gnome_screen_cast_session->n_needed_stream_node_ids++;
+
+ return TRUE;
+}
+
gboolean
gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_screen_cast_session,
GVariant *selections,
@@ -473,6 +551,13 @@ gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_scree
select,
error))
return FALSE;
+ break;
+ case SCREEN_CAST_SOURCE_TYPE_VIRTUAL:
+ if (!gnome_screen_cast_session_record_virtual (gnome_screen_cast_session,
+ select,
+ error))
+ return FALSE;
+ break;
}
}
diff --git a/src/screencast.h b/src/screencast.h
index f5033b2..00f939c 100644
--- a/src/screencast.h
+++ b/src/screencast.h
@@ -25,6 +25,7 @@ typedef enum _ScreenCastSourceType
{
SCREEN_CAST_SOURCE_TYPE_MONITOR = 1,
SCREEN_CAST_SOURCE_TYPE_WINDOW = 2,
+ SCREEN_CAST_SOURCE_TYPE_VIRTUAL = 4,
} ScreenCastSourceType;
typedef enum _ScreenCastCursorMode
diff --git a/src/screencastwidget.c b/src/screencastwidget.c
index cdd57dc..64a43b5 100644
--- a/src/screencastwidget.c
+++ b/src/screencastwidget.c
@@ -43,6 +43,7 @@ struct _ScreenCastWidget
GtkWidget *source_type;
GtkWidget *window_selection;
GtkWidget *monitor_selection;
+ GtkWidget *virtual_selection;
GtkWidget *monitor_heading;
GtkWidget *monitor_list;
@@ -51,6 +52,10 @@ struct _ScreenCastWidget
GtkWidget *window_list;
GtkWidget *window_list_scrolled;
+ GtkWidget *virtual_heading;
+ GtkWidget *virtual_switch;
+ GtkWidget *virtual_switch_label;
+
DisplayStateTracker *display_state_tracker;
gulong monitors_changed_handler_id;
@@ -351,6 +356,7 @@ emit_selection_change_in_idle_cb (gpointer data)
ScreenCastWidget *widget = (ScreenCastWidget *)data;
GList *selected_monitor_rows;
GList *selected_window_rows;
+ gboolean selected_virtual;
/* Update the selected rows */
update_selected_rows (GTK_LIST_BOX (widget->monitor_list));
@@ -358,8 +364,9 @@ emit_selection_change_in_idle_cb (gpointer data)
selected_monitor_rows = gtk_list_box_get_selected_rows (GTK_LIST_BOX (widget->monitor_list));
selected_window_rows = gtk_list_box_get_selected_rows (GTK_LIST_BOX (widget->window_list));
+ selected_virtual = gtk_switch_get_state (GTK_SWITCH (widget->virtual_switch));
g_signal_emit (widget, signals[HAS_SELECTION_CHANGED], 0,
- !!selected_monitor_rows || !!selected_window_rows);
+ !!selected_monitor_rows || !!selected_window_rows || selected_virtual);
g_list_free (selected_monitor_rows);
g_list_free (selected_window_rows);
@@ -386,6 +393,15 @@ on_selected_rows_changed (GtkListBox *box,
schedule_selection_change (widget);
}
+static gboolean
+on_virtual_switch_state_set (GtkSwitch *virtual_switch,
+ gboolean state,
+ ScreenCastWidget *widget)
+{
+ schedule_selection_change (widget);
+ return FALSE;
+}
+
static void
update_list_box_header (GtkListBoxRow *row,
GtkListBoxRow *before,
@@ -414,13 +430,15 @@ add_selections (ScreenCastWidget *widget,
{
GList *selected_monitor_rows;
GList *selected_window_rows;
+ gboolean selected_virtual;
GList *l;
selected_monitor_rows =
gtk_list_box_get_selected_rows (GTK_LIST_BOX (widget->monitor_list));
selected_window_rows =
gtk_list_box_get_selected_rows (GTK_LIST_BOX (widget->window_list));
- if (!selected_monitor_rows && !selected_window_rows)
+ selected_virtual = gtk_switch_get_state (GTK_SWITCH (widget->virtual_switch));
+ if (!selected_monitor_rows && !selected_window_rows && !selected_virtual)
return FALSE;
for (l = selected_monitor_rows; l; l = l->next)
@@ -450,6 +468,13 @@ add_selections (ScreenCastWidget *widget,
}
g_list_free (selected_window_rows);
+ if (selected_virtual)
+ {
+ g_variant_builder_add (source_selections_builder, "(ud)",
+ SCREEN_CAST_SOURCE_TYPE_VIRTUAL,
+ 1);
+ }
+
return TRUE;
}
@@ -478,6 +503,7 @@ screen_cast_widget_set_app_id (ScreenCastWidget *widget,
{
g_autofree char *monitor_heading = NULL;
g_autofree char *window_heading = NULL;
+ g_autofree char *virtual_heading = NULL;
if (app_id && strcmp (app_id, "") != 0)
{
@@ -495,15 +521,19 @@ screen_cast_widget_set_app_id (ScreenCastWidget *widget,
display_name);
window_heading = g_strdup_printf (_("Select window to share with %s"),
display_name);
+ virtual_heading = g_strdup_printf (_("Select whether to create a vitrual monitor for %s"),
+ display_name);
}
else
{
monitor_heading = g_strdup (_("Select monitor to share with the requesting application"));
window_heading = g_strdup (_("Select window to share with the requesting application"));
+ virtual_heading = g_strdup (_("Select whether to create a virtual monitor for the requesting
application"));
}
gtk_label_set_label (GTK_LABEL (widget->monitor_heading), monitor_heading);
gtk_label_set_label (GTK_LABEL (widget->window_heading), window_heading);
+ gtk_label_set_label (GTK_LABEL (widget->virtual_heading), virtual_heading);
}
void
@@ -528,6 +558,9 @@ screen_cast_widget_set_source_types (ScreenCastWidget *screen_cast_widget,
if (source_types & SCREEN_CAST_SOURCE_TYPE_WINDOW)
gtk_widget_show (screen_cast_widget->window_selection);
+ if (source_types & SCREEN_CAST_SOURCE_TYPE_VIRTUAL)
+ gtk_widget_show (screen_cast_widget->virtual_selection);
+
if (__builtin_popcount (source_types) > 1)
gtk_widget_show (screen_cast_widget->source_type_switcher);
}
@@ -588,6 +621,9 @@ screen_cast_widget_init (ScreenCastWidget *widget)
g_signal_connect (widget->window_list, "selected-rows-changed",
G_CALLBACK (on_selected_rows_changed),
widget);
+ g_signal_connect (widget->virtual_switch, "state-set",
+ G_CALLBACK (on_virtual_switch_state_set),
+ widget);
widget->display_state_tracker = display_state_tracker_get ();
widget->monitors_changed_handler_id =
@@ -602,6 +638,7 @@ screen_cast_widget_init (ScreenCastWidget *widget)
gtk_widget_show (widget->monitor_list);
gtk_widget_show (widget->window_list);
+ gtk_widget_show (widget->virtual_switch);
}
static void
@@ -626,11 +663,14 @@ screen_cast_widget_class_init (ScreenCastWidgetClass *klass)
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, source_type);
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, monitor_selection);
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, window_selection);
+ gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, virtual_selection);
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, monitor_heading);
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, monitor_list);
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, window_heading);
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, window_list);
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, window_list_scrolled);
+ gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, virtual_heading);
+ gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, virtual_switch);
quark_monitor_widget_data = g_quark_from_static_string ("-monitor-widget-connector-quark");
quark_window_widget_data = g_quark_from_static_string ("-window-widget-connector-quark");
diff --git a/src/screencastwidget.ui b/src/screencastwidget.ui
index 2417ca5..fbabfa7 100644
--- a/src/screencastwidget.ui
+++ b/src/screencastwidget.ui
@@ -19,6 +19,7 @@
<child>
<object class="GtkStack" id="source_type">
<property name="transition-type">crossfade</property>
+ <!-- Window selection page -->
<child>
<object class="GtkStackPage">
<property name="name">windows_page</property>
@@ -80,6 +81,8 @@
</property>
</object>
</child>
+
+ <!-- Physical monitor selection page -->
<child>
<object class="GtkStackPage">
<property name="name">monitors_page</property>
@@ -141,6 +144,64 @@
</property>
</object>
</child>
+
+ <!-- Virtual monitor selection page -->
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">virtual_page</property>
+ <property name="title" translatable="yes">Virtual monitor</property>
+ <property name="child">
+ <object class="GtkBox" id="virtual_selection">
+ <property name="orientation">vertical</property>
+ <property name="visible">0</property>
+ <property name="margin_top">12</property>
+
+ <!-- Virtual monitor selection label -->
+ <child>
+ <object class="GtkBox">
+ <property name="hexpand">True</property>
+ <property name="halign">start</property>
+ <child>
+ <object class="GtkLabel" id="virtual_heading">
+ <property name="label"/>
+ <property name="xalign">0.0</property>
+ <property name="margin_bottom">12</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <!-- Virtual monitor switch view -->
+ <child>
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">horizontal</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">
+ Create virtual monitor?
+ </property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSwitch" id="virtual_switch">
+ <property name="can_focus">True</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">False</property>
+ <property name="valign">center</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </child>
<layout>
<property name="column">0</property>
<property name="row">1</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]