Add screencast stream restoration support
Resolves: RHEL-4526
This commit is contained in:
parent
08f1f9377b
commit
6e8c012b33
638
0001-screencast-trivial-style-cleanups.patch
Normal file
638
0001-screencast-trivial-style-cleanups.patch
Normal file
@ -0,0 +1,638 @@
|
|||||||
|
From d9c897c8b91165f95f011d44f2fea731b4b7eb16 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Wed, 10 Nov 2021 15:32:18 -0300
|
||||||
|
Subject: [PATCH] screencast: Trivial style cleanups
|
||||||
|
|
||||||
|
Move some code around, and cleanup some of the styling.
|
||||||
|
It's getting increasingly harder to follow these files,
|
||||||
|
so start this series of cleanups with them.
|
||||||
|
---
|
||||||
|
src/screencast.c | 30 ++--
|
||||||
|
src/screencastdialog.c | 62 +++----
|
||||||
|
src/screencastdialog.h | 2 +-
|
||||||
|
src/screencastwidget.c | 356 +++++++++++++++++++++--------------------
|
||||||
|
src/screencastwidget.h | 10 +-
|
||||||
|
5 files changed, 238 insertions(+), 222 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/gnomescreencast.c b/src/gnomescreencast.c
|
||||||
|
index fd80ca7..abf5b53 100644
|
||||||
|
--- a/src/gnomescreencast.c
|
||||||
|
+++ b/src/gnomescreencast.c
|
||||||
|
@@ -473,6 +473,7 @@ gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_scree
|
||||||
|
select,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 27d8946..38d1d05 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -572,21 +572,6 @@ on_gnome_screen_cast_disabled (GDBusConnection *connection,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-gboolean
|
||||||
|
-screen_cast_init (GDBusConnection *connection,
|
||||||
|
- GError **error)
|
||||||
|
-{
|
||||||
|
- impl_connection = connection;
|
||||||
|
- gnome_screen_cast = gnome_screen_cast_new (connection);
|
||||||
|
-
|
||||||
|
- g_signal_connect (gnome_screen_cast, "enabled",
|
||||||
|
- G_CALLBACK (on_gnome_screen_cast_enabled), NULL);
|
||||||
|
- g_signal_connect (gnome_screen_cast, "disabled",
|
||||||
|
- G_CALLBACK (on_gnome_screen_cast_disabled), NULL);
|
||||||
|
-
|
||||||
|
- return TRUE;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void
|
||||||
|
screen_cast_session_close (Session *session)
|
||||||
|
{
|
||||||
|
@@ -636,3 +621,18 @@ screen_cast_session_class_init (ScreenCastSessionClass *klass)
|
||||||
|
session_class = (SessionClass *)klass;
|
||||||
|
session_class->close = screen_cast_session_close;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+gboolean
|
||||||
|
+screen_cast_init (GDBusConnection *connection,
|
||||||
|
+ GError **error)
|
||||||
|
+{
|
||||||
|
+ impl_connection = connection;
|
||||||
|
+ gnome_screen_cast = gnome_screen_cast_new (connection);
|
||||||
|
+
|
||||||
|
+ g_signal_connect (gnome_screen_cast, "enabled",
|
||||||
|
+ G_CALLBACK (on_gnome_screen_cast_enabled), NULL);
|
||||||
|
+ g_signal_connect (gnome_screen_cast, "disabled",
|
||||||
|
+ G_CALLBACK (on_gnome_screen_cast_disabled), NULL);
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
diff --git a/src/screencastdialog.c b/src/screencastdialog.c
|
||||||
|
index 306992d..56d4d49 100644
|
||||||
|
--- a/src/screencastdialog.c
|
||||||
|
+++ b/src/screencastdialog.c
|
||||||
|
@@ -51,6 +51,10 @@ static guint signals[N_SIGNALS];
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ScreenCastDialog, screen_cast_dialog, GTK_TYPE_WINDOW)
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Callbacks
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
button_clicked (GtkWidget *button,
|
||||||
|
ScreenCastDialog *dialog)
|
||||||
|
@@ -84,7 +88,7 @@ button_clicked (GtkWidget *button,
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_has_selection_changed (ScreenCastWidget *screen_cast_widget,
|
||||||
|
- gboolean has_selection,
|
||||||
|
+ gboolean has_selection,
|
||||||
|
ScreenCastDialog *dialog)
|
||||||
|
{
|
||||||
|
if (has_selection)
|
||||||
|
@@ -93,32 +97,9 @@ on_has_selection_changed (ScreenCastWidget *screen_cast_widget,
|
||||||
|
gtk_widget_set_sensitive (dialog->accept_button, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
-ScreenCastDialog *
|
||||||
|
-screen_cast_dialog_new (const char *app_id,
|
||||||
|
- ScreenCastSelection *select)
|
||||||
|
-{
|
||||||
|
- ScreenCastDialog *dialog;
|
||||||
|
- ScreenCastWidget *screen_cast_widget;
|
||||||
|
-
|
||||||
|
- dialog = g_object_new (SCREEN_CAST_TYPE_DIALOG, NULL);
|
||||||
|
- screen_cast_widget = SCREEN_CAST_WIDGET (dialog->screen_cast_widget);
|
||||||
|
- screen_cast_widget_set_app_id (screen_cast_widget, app_id);
|
||||||
|
- screen_cast_widget_set_allow_multiple (screen_cast_widget, select->multiple);
|
||||||
|
- screen_cast_widget_set_source_types (screen_cast_widget,
|
||||||
|
- select->source_types);
|
||||||
|
-
|
||||||
|
- return dialog;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-screen_cast_dialog_init (ScreenCastDialog *dialog)
|
||||||
|
-{
|
||||||
|
- gtk_widget_init_template (GTK_WIDGET (dialog));
|
||||||
|
-
|
||||||
|
- g_signal_connect (dialog->screen_cast_widget, "has-selection-changed",
|
||||||
|
- G_CALLBACK (on_has_selection_changed), dialog);
|
||||||
|
- gtk_widget_show (dialog->screen_cast_widget);
|
||||||
|
-}
|
||||||
|
+/*
|
||||||
|
+ * GtkWindow overrides
|
||||||
|
+ */
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
screen_cast_dialog_close_request (GtkWindow *dialog)
|
||||||
|
@@ -155,3 +136,30 @@ screen_cast_dialog_class_init (ScreenCastDialogClass *klass)
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ScreenCastDialog, screen_cast_widget);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, button_clicked);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+screen_cast_dialog_init (ScreenCastDialog *dialog)
|
||||||
|
+{
|
||||||
|
+ gtk_widget_init_template (GTK_WIDGET (dialog));
|
||||||
|
+
|
||||||
|
+ g_signal_connect (dialog->screen_cast_widget, "has-selection-changed",
|
||||||
|
+ G_CALLBACK (on_has_selection_changed), dialog);
|
||||||
|
+ gtk_widget_show (dialog->screen_cast_widget);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+ScreenCastDialog *
|
||||||
|
+screen_cast_dialog_new (const char *app_id,
|
||||||
|
+ ScreenCastSelection *select)
|
||||||
|
+{
|
||||||
|
+ ScreenCastDialog *dialog;
|
||||||
|
+ ScreenCastWidget *screen_cast_widget;
|
||||||
|
+
|
||||||
|
+ dialog = g_object_new (SCREEN_CAST_TYPE_DIALOG, NULL);
|
||||||
|
+ screen_cast_widget = SCREEN_CAST_WIDGET (dialog->screen_cast_widget);
|
||||||
|
+ screen_cast_widget_set_app_id (screen_cast_widget, app_id);
|
||||||
|
+ screen_cast_widget_set_allow_multiple (screen_cast_widget, select->multiple);
|
||||||
|
+ screen_cast_widget_set_source_types (screen_cast_widget,
|
||||||
|
+ select->source_types);
|
||||||
|
+
|
||||||
|
+ return dialog;
|
||||||
|
+}
|
||||||
|
diff --git a/src/screencastdialog.h b/src/screencastdialog.h
|
||||||
|
index 247d93b..1fca470 100644
|
||||||
|
--- a/src/screencastdialog.h
|
||||||
|
+++ b/src/screencastdialog.h
|
||||||
|
@@ -26,5 +26,5 @@
|
||||||
|
G_DECLARE_FINAL_TYPE (ScreenCastDialog, screen_cast_dialog,
|
||||||
|
SCREEN_CAST, DIALOG, GtkWindow)
|
||||||
|
|
||||||
|
-ScreenCastDialog * screen_cast_dialog_new (const char *app_id,
|
||||||
|
+ScreenCastDialog * screen_cast_dialog_new (const char *app_id,
|
||||||
|
ScreenCastSelection *select);
|
||||||
|
diff --git a/src/screencastwidget.c b/src/screencastwidget.c
|
||||||
|
index cdd57dc..454c93e 100644
|
||||||
|
--- a/src/screencastwidget.c
|
||||||
|
+++ b/src/screencastwidget.c
|
||||||
|
@@ -65,6 +65,55 @@ static GQuark quark_window_widget_data;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ScreenCastWidget, screen_cast_widget, GTK_TYPE_BOX)
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Auxiliary methods
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static gboolean
|
||||||
|
+add_selections (ScreenCastWidget *widget,
|
||||||
|
+ GVariantBuilder *source_selections_builder)
|
||||||
|
+{
|
||||||
|
+ GList *selected_monitor_rows;
|
||||||
|
+ GList *selected_window_rows;
|
||||||
|
+ 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)
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ for (l = selected_monitor_rows; l; l = l->next)
|
||||||
|
+ {
|
||||||
|
+ GtkWidget *monitor_widget = gtk_list_box_row_get_child (l->data);
|
||||||
|
+ Monitor *monitor;
|
||||||
|
+
|
||||||
|
+ monitor = g_object_get_qdata (G_OBJECT (monitor_widget),
|
||||||
|
+ quark_monitor_widget_data);
|
||||||
|
+
|
||||||
|
+ g_variant_builder_add (source_selections_builder, "(us)",
|
||||||
|
+ SCREEN_CAST_SOURCE_TYPE_MONITOR,
|
||||||
|
+ monitor_get_connector (monitor));
|
||||||
|
+ }
|
||||||
|
+ g_list_free (selected_monitor_rows);
|
||||||
|
+ for (l = selected_window_rows; l; l = l->next)
|
||||||
|
+ {
|
||||||
|
+ GtkWidget *window_widget = gtk_list_box_row_get_child (l->data);
|
||||||
|
+ Window *window;
|
||||||
|
+
|
||||||
|
+ window = g_object_get_qdata (G_OBJECT (window_widget),
|
||||||
|
+ quark_window_widget_data);
|
||||||
|
+
|
||||||
|
+ g_variant_builder_add (source_selections_builder, "(ut)",
|
||||||
|
+ SCREEN_CAST_SOURCE_TYPE_WINDOW,
|
||||||
|
+ window_get_id (window));
|
||||||
|
+ }
|
||||||
|
+ g_list_free (selected_window_rows);
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static GtkWidget *
|
||||||
|
create_window_widget (Window *window)
|
||||||
|
{
|
||||||
|
@@ -131,7 +180,7 @@ create_monitor_widget (LogicalMonitor *logical_monitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
-should_skip_window (Window *window,
|
||||||
|
+should_skip_window (Window *window,
|
||||||
|
GtkWindow *toplevel)
|
||||||
|
{
|
||||||
|
g_autofree char *processed_app_id = NULL;
|
||||||
|
@@ -254,7 +303,7 @@ unselect_rows (GtkListBox *listbox)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-on_windows_changed (ShellIntrospect *shell_introspect,
|
||||||
|
+on_windows_changed (ShellIntrospect *shell_introspect,
|
||||||
|
ScreenCastWidget *widget)
|
||||||
|
{
|
||||||
|
update_windows_list (widget);
|
||||||
|
@@ -283,9 +332,9 @@ disconnect_windows_changed_listener (ScreenCastWidget *widget)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-on_stack_switch (GtkStack *stack,
|
||||||
|
+on_stack_switch (GtkStack *stack,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
- gpointer *data)
|
||||||
|
+ gpointer *data)
|
||||||
|
{
|
||||||
|
ScreenCastWidget *widget = (ScreenCastWidget *)data;
|
||||||
|
GtkWidget *visible_child;
|
||||||
|
@@ -307,9 +356,9 @@ on_stack_switch (GtkStack *stack,
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-on_row_activated (GtkListBox *box,
|
||||||
|
+on_row_activated (GtkListBox *box,
|
||||||
|
GtkListBoxRow *row,
|
||||||
|
- gpointer *data)
|
||||||
|
+ gpointer *data)
|
||||||
|
{
|
||||||
|
if (!row)
|
||||||
|
return;
|
||||||
|
@@ -378,7 +427,7 @@ schedule_selection_change (ScreenCastWidget *widget)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-on_selected_rows_changed (GtkListBox *box,
|
||||||
|
+on_selected_rows_changed (GtkListBox *box,
|
||||||
|
ScreenCastWidget *widget)
|
||||||
|
{
|
||||||
|
/* GtkListBox activates rows after selecting them, which prevents
|
||||||
|
@@ -403,59 +452,128 @@ update_list_box_header (GtkListBoxRow *row,
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_monitors_changed (DisplayStateTracker *display_state_tracker,
|
||||||
|
- ScreenCastWidget *widget)
|
||||||
|
+ ScreenCastWidget *widget)
|
||||||
|
{
|
||||||
|
update_monitors_list (widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static gboolean
|
||||||
|
-add_selections (ScreenCastWidget *widget,
|
||||||
|
- GVariantBuilder *source_selections_builder)
|
||||||
|
+/*
|
||||||
|
+ * GObject overrides
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+screen_cast_widget_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
- GList *selected_monitor_rows;
|
||||||
|
- GList *selected_window_rows;
|
||||||
|
- GList *l;
|
||||||
|
+ ScreenCastWidget *widget = SCREEN_CAST_WIDGET (object);
|
||||||
|
|
||||||
|
- 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)
|
||||||
|
- return FALSE;
|
||||||
|
+ g_signal_handler_disconnect (widget->display_state_tracker,
|
||||||
|
+ widget->monitors_changed_handler_id);
|
||||||
|
|
||||||
|
- for (l = selected_monitor_rows; l; l = l->next)
|
||||||
|
+ if (widget->windows_changed_handler_id)
|
||||||
|
+ disconnect_windows_changed_listener (widget);
|
||||||
|
+
|
||||||
|
+ if (widget->selection_changed_timeout_id > 0)
|
||||||
|
{
|
||||||
|
- GtkWidget *monitor_widget = gtk_list_box_row_get_child (l->data);
|
||||||
|
- Monitor *monitor;
|
||||||
|
+ g_source_remove (widget->selection_changed_timeout_id);
|
||||||
|
+ widget->selection_changed_timeout_id = 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- monitor = g_object_get_qdata (G_OBJECT (monitor_widget),
|
||||||
|
- quark_monitor_widget_data);
|
||||||
|
+ G_OBJECT_CLASS (screen_cast_widget_parent_class)->finalize (object);
|
||||||
|
+}
|
||||||
|
|
||||||
|
- g_variant_builder_add (source_selections_builder, "(us)",
|
||||||
|
- SCREEN_CAST_SOURCE_TYPE_MONITOR,
|
||||||
|
- monitor_get_connector (monitor));
|
||||||
|
- }
|
||||||
|
- g_list_free (selected_monitor_rows);
|
||||||
|
- for (l = selected_window_rows; l; l = l->next)
|
||||||
|
- {
|
||||||
|
- GtkWidget *window_widget = gtk_list_box_row_get_child (l->data);
|
||||||
|
- Window *window;
|
||||||
|
+static void
|
||||||
|
+screen_cast_widget_class_init (ScreenCastWidgetClass *klass)
|
||||||
|
+{
|
||||||
|
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
|
||||||
|
- window = g_object_get_qdata (G_OBJECT (window_widget),
|
||||||
|
- quark_window_widget_data);
|
||||||
|
+ object_class->finalize = screen_cast_widget_finalize;
|
||||||
|
|
||||||
|
- g_variant_builder_add (source_selections_builder, "(ut)",
|
||||||
|
- SCREEN_CAST_SOURCE_TYPE_WINDOW,
|
||||||
|
- window_get_id (window));
|
||||||
|
- }
|
||||||
|
- g_list_free (selected_window_rows);
|
||||||
|
+ signals[HAS_SELECTION_CHANGED] = g_signal_new ("has-selection-changed",
|
||||||
|
+ G_TYPE_FROM_CLASS (klass),
|
||||||
|
+ G_SIGNAL_RUN_LAST,
|
||||||
|
+ 0,
|
||||||
|
+ NULL, NULL,
|
||||||
|
+ NULL,
|
||||||
|
+ G_TYPE_NONE, 1,
|
||||||
|
+ G_TYPE_BOOLEAN);
|
||||||
|
|
||||||
|
- return TRUE;
|
||||||
|
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/freedesktop/portal/desktop/gnome/screencastwidget.ui");
|
||||||
|
+ gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, source_type_switcher);
|
||||||
|
+ 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, 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);
|
||||||
|
+
|
||||||
|
+ 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");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+screen_cast_widget_init (ScreenCastWidget *widget)
|
||||||
|
+{
|
||||||
|
+ GtkScrolledWindow *scrolled_window;
|
||||||
|
+ GtkAdjustment *vadjustment;
|
||||||
|
+
|
||||||
|
+ gtk_widget_init_template (GTK_WIDGET (widget));
|
||||||
|
+
|
||||||
|
+ screen_cast_widget_set_app_id (widget, NULL);
|
||||||
|
+ screen_cast_widget_set_allow_multiple (widget, FALSE);
|
||||||
|
+
|
||||||
|
+ gtk_list_box_set_header_func (GTK_LIST_BOX (widget->monitor_list),
|
||||||
|
+ update_list_box_header,
|
||||||
|
+ NULL, NULL);
|
||||||
|
+ gtk_list_box_set_header_func (GTK_LIST_BOX (widget->window_list),
|
||||||
|
+ update_list_box_header,
|
||||||
|
+ NULL, NULL);
|
||||||
|
+ scrolled_window = GTK_SCROLLED_WINDOW (widget->window_list_scrolled);
|
||||||
|
+ vadjustment = gtk_scrolled_window_get_vadjustment (scrolled_window);
|
||||||
|
+ gtk_list_box_set_adjustment (GTK_LIST_BOX (widget->window_list), vadjustment);
|
||||||
|
+
|
||||||
|
+ g_signal_connect (widget->source_type, "notify::visible-child",
|
||||||
|
+ G_CALLBACK (on_stack_switch),
|
||||||
|
+ widget);
|
||||||
|
+ g_signal_connect (widget->monitor_list, "row-activated",
|
||||||
|
+ G_CALLBACK (on_row_activated),
|
||||||
|
+ NULL);
|
||||||
|
+ g_signal_connect (widget->window_list, "row-activated",
|
||||||
|
+ G_CALLBACK (on_row_activated),
|
||||||
|
+ NULL);
|
||||||
|
+ g_signal_connect (widget->monitor_list, "selected-rows-changed",
|
||||||
|
+ G_CALLBACK (on_selected_rows_changed),
|
||||||
|
+ widget);
|
||||||
|
+ g_signal_connect (widget->window_list, "selected-rows-changed",
|
||||||
|
+ G_CALLBACK (on_selected_rows_changed),
|
||||||
|
+ widget);
|
||||||
|
+
|
||||||
|
+ widget->display_state_tracker = display_state_tracker_get ();
|
||||||
|
+ widget->monitors_changed_handler_id =
|
||||||
|
+ g_signal_connect (widget->display_state_tracker,
|
||||||
|
+ "monitors-changed",
|
||||||
|
+ G_CALLBACK (on_monitors_changed),
|
||||||
|
+ widget);
|
||||||
|
+ widget->shell_introspect = shell_introspect_get ();
|
||||||
|
+
|
||||||
|
+ update_monitors_list (widget);
|
||||||
|
+ update_windows_list (widget);
|
||||||
|
+
|
||||||
|
+ gtk_widget_show (widget->monitor_list);
|
||||||
|
+ gtk_widget_show (widget->window_list);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+init_screen_cast_widget (void)
|
||||||
|
+{
|
||||||
|
+ g_type_ensure (screen_cast_widget_get_type ());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
screen_cast_widget_add_selections (ScreenCastWidget *widget,
|
||||||
|
- GVariantBuilder *selections_builder)
|
||||||
|
+ GVariantBuilder *selections_builder)
|
||||||
|
{
|
||||||
|
GVariantBuilder source_selections_builder;
|
||||||
|
|
||||||
|
@@ -474,7 +592,7 @@ screen_cast_widget_add_selections (ScreenCastWidget *widget,
|
||||||
|
|
||||||
|
void
|
||||||
|
screen_cast_widget_set_app_id (ScreenCastWidget *widget,
|
||||||
|
- const char *app_id)
|
||||||
|
+ const char *app_id)
|
||||||
|
{
|
||||||
|
g_autofree char *monitor_heading = NULL;
|
||||||
|
g_autofree char *window_heading = NULL;
|
||||||
|
@@ -508,7 +626,7 @@ screen_cast_widget_set_app_id (ScreenCastWidget *widget,
|
||||||
|
|
||||||
|
void
|
||||||
|
screen_cast_widget_set_allow_multiple (ScreenCastWidget *widget,
|
||||||
|
- gboolean multiple)
|
||||||
|
+ gboolean multiple)
|
||||||
|
{
|
||||||
|
gtk_list_box_set_selection_mode (GTK_LIST_BOX (widget->monitor_list),
|
||||||
|
multiple ? GTK_SELECTION_MULTIPLE
|
||||||
|
@@ -519,8 +637,8 @@ screen_cast_widget_set_allow_multiple (ScreenCastWidget *widget,
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
-screen_cast_widget_set_source_types (ScreenCastWidget *screen_cast_widget,
|
||||||
|
- ScreenCastSourceType source_types)
|
||||||
|
+screen_cast_widget_set_source_types (ScreenCastWidget *screen_cast_widget,
|
||||||
|
+ ScreenCastSourceType source_types)
|
||||||
|
{
|
||||||
|
if (source_types & SCREEN_CAST_SOURCE_TYPE_MONITOR)
|
||||||
|
gtk_widget_show (screen_cast_widget->monitor_selection);
|
||||||
|
@@ -531,113 +649,3 @@ screen_cast_widget_set_source_types (ScreenCastWidget *screen_cast_widget,
|
||||||
|
if (__builtin_popcount (source_types) > 1)
|
||||||
|
gtk_widget_show (screen_cast_widget->source_type_switcher);
|
||||||
|
}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-screen_cast_widget_finalize (GObject *object)
|
||||||
|
-{
|
||||||
|
- ScreenCastWidget *widget = SCREEN_CAST_WIDGET (object);
|
||||||
|
-
|
||||||
|
- g_signal_handler_disconnect (widget->display_state_tracker,
|
||||||
|
- widget->monitors_changed_handler_id);
|
||||||
|
-
|
||||||
|
- if (widget->windows_changed_handler_id)
|
||||||
|
- disconnect_windows_changed_listener (widget);
|
||||||
|
-
|
||||||
|
- if (widget->selection_changed_timeout_id > 0)
|
||||||
|
- {
|
||||||
|
- g_source_remove (widget->selection_changed_timeout_id);
|
||||||
|
- widget->selection_changed_timeout_id = 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- G_OBJECT_CLASS (screen_cast_widget_parent_class)->finalize (object);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-screen_cast_widget_init (ScreenCastWidget *widget)
|
||||||
|
-{
|
||||||
|
- GtkScrolledWindow *scrolled_window;
|
||||||
|
- GtkAdjustment *vadjustment;
|
||||||
|
-
|
||||||
|
- gtk_widget_init_template (GTK_WIDGET (widget));
|
||||||
|
-
|
||||||
|
- screen_cast_widget_set_app_id (widget, NULL);
|
||||||
|
- screen_cast_widget_set_allow_multiple (widget, FALSE);
|
||||||
|
-
|
||||||
|
- gtk_list_box_set_header_func (GTK_LIST_BOX (widget->monitor_list),
|
||||||
|
- update_list_box_header,
|
||||||
|
- NULL, NULL);
|
||||||
|
- gtk_list_box_set_header_func (GTK_LIST_BOX (widget->window_list),
|
||||||
|
- update_list_box_header,
|
||||||
|
- NULL, NULL);
|
||||||
|
- scrolled_window = GTK_SCROLLED_WINDOW (widget->window_list_scrolled);
|
||||||
|
- vadjustment = gtk_scrolled_window_get_vadjustment (scrolled_window);
|
||||||
|
- gtk_list_box_set_adjustment (GTK_LIST_BOX (widget->window_list), vadjustment);
|
||||||
|
-
|
||||||
|
- g_signal_connect (widget->source_type, "notify::visible-child",
|
||||||
|
- G_CALLBACK (on_stack_switch),
|
||||||
|
- widget);
|
||||||
|
- g_signal_connect (widget->monitor_list, "row-activated",
|
||||||
|
- G_CALLBACK (on_row_activated),
|
||||||
|
- NULL);
|
||||||
|
- g_signal_connect (widget->window_list, "row-activated",
|
||||||
|
- G_CALLBACK (on_row_activated),
|
||||||
|
- NULL);
|
||||||
|
- g_signal_connect (widget->monitor_list, "selected-rows-changed",
|
||||||
|
- G_CALLBACK (on_selected_rows_changed),
|
||||||
|
- widget);
|
||||||
|
- g_signal_connect (widget->window_list, "selected-rows-changed",
|
||||||
|
- G_CALLBACK (on_selected_rows_changed),
|
||||||
|
- widget);
|
||||||
|
-
|
||||||
|
- widget->display_state_tracker = display_state_tracker_get ();
|
||||||
|
- widget->monitors_changed_handler_id =
|
||||||
|
- g_signal_connect (widget->display_state_tracker,
|
||||||
|
- "monitors-changed",
|
||||||
|
- G_CALLBACK (on_monitors_changed),
|
||||||
|
- widget);
|
||||||
|
- widget->shell_introspect = shell_introspect_get ();
|
||||||
|
-
|
||||||
|
- update_monitors_list (widget);
|
||||||
|
- update_windows_list (widget);
|
||||||
|
-
|
||||||
|
- gtk_widget_show (widget->monitor_list);
|
||||||
|
- gtk_widget_show (widget->window_list);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-screen_cast_widget_class_init (ScreenCastWidgetClass *klass)
|
||||||
|
-{
|
||||||
|
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
-
|
||||||
|
- object_class->finalize = screen_cast_widget_finalize;
|
||||||
|
-
|
||||||
|
- signals[HAS_SELECTION_CHANGED] = g_signal_new ("has-selection-changed",
|
||||||
|
- G_TYPE_FROM_CLASS (klass),
|
||||||
|
- G_SIGNAL_RUN_LAST,
|
||||||
|
- 0,
|
||||||
|
- NULL, NULL,
|
||||||
|
- NULL,
|
||||||
|
- G_TYPE_NONE, 1,
|
||||||
|
- G_TYPE_BOOLEAN);
|
||||||
|
-
|
||||||
|
- gtk_widget_class_set_template_from_resource (widget_class, "/org/freedesktop/portal/desktop/gnome/screencastwidget.ui");
|
||||||
|
- gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, source_type_switcher);
|
||||||
|
- 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, 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);
|
||||||
|
-
|
||||||
|
- 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");
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void
|
||||||
|
-init_screen_cast_widget (void)
|
||||||
|
-{
|
||||||
|
- g_type_ensure (screen_cast_widget_get_type ());
|
||||||
|
-}
|
||||||
|
diff --git a/src/screencastwidget.h b/src/screencastwidget.h
|
||||||
|
index 3a1ebd2..34360a3 100644
|
||||||
|
--- a/src/screencastwidget.h
|
||||||
|
+++ b/src/screencastwidget.h
|
||||||
|
@@ -31,13 +31,13 @@ G_DECLARE_FINAL_TYPE (ScreenCastWidget, screen_cast_widget,
|
||||||
|
void init_screen_cast_widget (void);
|
||||||
|
|
||||||
|
void screen_cast_widget_set_app_id (ScreenCastWidget *widget,
|
||||||
|
- const char *app_id);
|
||||||
|
+ const char *app_id);
|
||||||
|
|
||||||
|
void screen_cast_widget_set_allow_multiple (ScreenCastWidget *widget,
|
||||||
|
- gboolean multiple);
|
||||||
|
+ gboolean multiple);
|
||||||
|
|
||||||
|
-void screen_cast_widget_set_source_types (ScreenCastWidget *screen_cast_widget,
|
||||||
|
- ScreenCastSourceType source_types);
|
||||||
|
+void screen_cast_widget_set_source_types (ScreenCastWidget *screen_cast_widget,
|
||||||
|
+ ScreenCastSourceType source_types);
|
||||||
|
|
||||||
|
void screen_cast_widget_add_selections (ScreenCastWidget *widget,
|
||||||
|
- GVariantBuilder *selections_builder);
|
||||||
|
+ GVariantBuilder *selections_builder);
|
||||||
|
diff --git a/src/screencastwidget.ui b/src/screencastwidget.ui
|
||||||
|
index 2417ca5..fb83b94 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>
|
223
00014-screencasts-duplicate-monitor-and-window-stream-info.patch
Normal file
223
00014-screencasts-duplicate-monitor-and-window-stream-info.patch
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
diff --git a/src/displaystatetracker.c b/src/displaystatetracker.c
|
||||||
|
index fc9109e..ebe1105 100644
|
||||||
|
--- a/src/displaystatetracker.c
|
||||||
|
+++ b/src/displaystatetracker.c
|
||||||
|
@@ -62,7 +62,7 @@ G_DEFINE_TYPE (DisplayStateTracker, display_state_tracker, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static DisplayStateTracker *_display_state_tracker;
|
||||||
|
|
||||||
|
-static void
|
||||||
|
+void
|
||||||
|
monitor_free (Monitor *monitor)
|
||||||
|
{
|
||||||
|
g_free (monitor->connector);
|
||||||
|
@@ -71,6 +71,19 @@ monitor_free (Monitor *monitor)
|
||||||
|
g_free (monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
+Monitor *
|
||||||
|
+monitor_dup (Monitor *monitor)
|
||||||
|
+{
|
||||||
|
+ Monitor *new_monitor;
|
||||||
|
+
|
||||||
|
+ new_monitor = g_new0 (Monitor, 1);
|
||||||
|
+ new_monitor->connector = g_strdup (monitor->connector);
|
||||||
|
+ new_monitor->match_string = g_strdup (monitor->match_string);
|
||||||
|
+ new_monitor->display_name = g_strdup (monitor->display_name);
|
||||||
|
+
|
||||||
|
+ return new_monitor;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
const char *
|
||||||
|
monitor_get_connector (Monitor *monitor)
|
||||||
|
{
|
||||||
|
diff --git a/src/displaystatetracker.h b/src/displaystatetracker.h
|
||||||
|
index 1c3a7dc..e438dda 100644
|
||||||
|
--- a/src/displaystatetracker.h
|
||||||
|
+++ b/src/displaystatetracker.h
|
||||||
|
@@ -26,6 +26,10 @@ typedef struct _LogicalMonitor LogicalMonitor;
|
||||||
|
G_DECLARE_FINAL_TYPE (DisplayStateTracker, display_state_tracker,
|
||||||
|
DISPLAY, STATE_TRACKER, GObject)
|
||||||
|
|
||||||
|
+void monitor_free (Monitor *monitor);
|
||||||
|
+
|
||||||
|
+Monitor * monitor_dup (Monitor *monitor);
|
||||||
|
+
|
||||||
|
const char * monitor_get_connector (Monitor *monitor);
|
||||||
|
|
||||||
|
const char * monitor_get_match_string (Monitor *monitor);
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 0a15033..724ffc9 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -469,6 +469,22 @@ find_best_window_by_app_id_and_title (const char *app_id,
|
||||||
|
return best_match;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+screen_cast_stream_info_free (ScreenCastStreamInfo *info)
|
||||||
|
+{
|
||||||
|
+ switch (info->type)
|
||||||
|
+ {
|
||||||
|
+ case SCREEN_CAST_SOURCE_TYPE_MONITOR:
|
||||||
|
+ g_clear_pointer (&info->data.monitor, monitor_free);
|
||||||
|
+ break;
|
||||||
|
+ case SCREEN_CAST_SOURCE_TYPE_WINDOW:
|
||||||
|
+ g_clear_pointer (&info->data.window, window_free);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ g_free (info);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gboolean
|
||||||
|
restore_stream_from_data (ScreenCastSession *screen_cast_session)
|
||||||
|
|
||||||
|
@@ -486,7 +502,8 @@ restore_stream_from_data (ScreenCastSession *screen_cast_session)
|
||||||
|
if (!screen_cast_session->restored.data)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
- streams = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
+ streams =
|
||||||
|
+ g_ptr_array_new_with_free_func ((GDestroyNotify) screen_cast_stream_info_free);
|
||||||
|
|
||||||
|
g_variant_get (screen_cast_session->restored.data,
|
||||||
|
RESTORE_VARIANT_TYPE,
|
||||||
|
@@ -512,7 +529,7 @@ restore_stream_from_data (ScreenCastSession *screen_cast_session)
|
||||||
|
|
||||||
|
info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
info->type = SCREEN_CAST_SOURCE_TYPE_MONITOR;
|
||||||
|
- info->data.monitor = monitor;
|
||||||
|
+ info->data.monitor = monitor_dup (monitor);
|
||||||
|
info->id = id;
|
||||||
|
g_ptr_array_add (streams, info);
|
||||||
|
}
|
||||||
|
@@ -537,7 +554,7 @@ restore_stream_from_data (ScreenCastSession *screen_cast_session)
|
||||||
|
|
||||||
|
info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
info->type = SCREEN_CAST_SOURCE_TYPE_WINDOW;
|
||||||
|
- info->data.window = window;
|
||||||
|
+ info->data.window = window_dup (window);
|
||||||
|
info->id = id;
|
||||||
|
g_ptr_array_add (streams, info);
|
||||||
|
}
|
||||||
|
diff --git a/src/screencast.h b/src/screencast.h
|
||||||
|
index 3d64b4a..ae8988d 100644
|
||||||
|
--- a/src/screencast.h
|
||||||
|
+++ b/src/screencast.h
|
||||||
|
@@ -64,3 +64,5 @@ typedef struct
|
||||||
|
|
||||||
|
gboolean screen_cast_init (GDBusConnection *connection,
|
||||||
|
GError **error);
|
||||||
|
+
|
||||||
|
+void screen_cast_stream_info_free (ScreenCastStreamInfo *info);
|
||||||
|
diff --git a/src/screencastwidget.c b/src/screencastwidget.c
|
||||||
|
index 11743f7..a40c824 100644
|
||||||
|
--- a/src/screencastwidget.c
|
||||||
|
+++ b/src/screencastwidget.c
|
||||||
|
@@ -101,9 +101,10 @@ create_window_widget (Window *window)
|
||||||
|
gtk_widget_set_margin_bottom (window_label, 12);
|
||||||
|
gtk_box_append (GTK_BOX (window_widget), window_label);
|
||||||
|
|
||||||
|
- g_object_set_qdata (G_OBJECT (window_widget),
|
||||||
|
- quark_window_widget_data,
|
||||||
|
- window);
|
||||||
|
+ g_object_set_qdata_full (G_OBJECT (window_widget),
|
||||||
|
+ quark_window_widget_data,
|
||||||
|
+ window_dup (window),
|
||||||
|
+ (GDestroyNotify) window_free);
|
||||||
|
return window_widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -123,9 +124,12 @@ create_monitor_widget (LogicalMonitor *logical_monitor)
|
||||||
|
GtkWidget *monitor_label;
|
||||||
|
|
||||||
|
if (!l->prev)
|
||||||
|
- g_object_set_qdata (G_OBJECT (monitor_widget),
|
||||||
|
- quark_monitor_widget_data,
|
||||||
|
- monitor);
|
||||||
|
+ {
|
||||||
|
+ g_object_set_qdata_full (G_OBJECT (monitor_widget),
|
||||||
|
+ quark_monitor_widget_data,
|
||||||
|
+ monitor_dup (monitor),
|
||||||
|
+ (GDestroyNotify) monitor_free);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
monitor_label = gtk_label_new (monitor_get_display_name (monitor));
|
||||||
|
gtk_widget_set_margin_top (monitor_label, 12);
|
||||||
|
@@ -599,7 +603,8 @@ screen_cast_widget_get_selected_streams (ScreenCastWidget *self)
|
||||||
|
uint32_t id = 0;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
- streams = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
+ streams =
|
||||||
|
+ g_ptr_array_new_with_free_func ((GDestroyNotify) screen_cast_stream_info_free);
|
||||||
|
|
||||||
|
selected_monitor_rows =
|
||||||
|
gtk_list_box_get_selected_rows (GTK_LIST_BOX (self->monitor_list));
|
||||||
|
@@ -619,7 +624,7 @@ screen_cast_widget_get_selected_streams (ScreenCastWidget *self)
|
||||||
|
|
||||||
|
info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
info->type = SCREEN_CAST_SOURCE_TYPE_MONITOR;
|
||||||
|
- info->data.monitor = monitor;
|
||||||
|
+ info->data.monitor = monitor_dup (monitor);
|
||||||
|
info->id = id++;
|
||||||
|
g_ptr_array_add (streams, info);
|
||||||
|
}
|
||||||
|
@@ -634,7 +639,7 @@ screen_cast_widget_get_selected_streams (ScreenCastWidget *self)
|
||||||
|
|
||||||
|
info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
info->type = SCREEN_CAST_SOURCE_TYPE_WINDOW;
|
||||||
|
- info->data.window = window;
|
||||||
|
+ info->data.window = window_dup (window);
|
||||||
|
info->id = id++;
|
||||||
|
g_ptr_array_add (streams, info);
|
||||||
|
}
|
||||||
|
diff --git a/src/shellintrospect.c b/src/shellintrospect.c
|
||||||
|
index 8a81086..d1bcc8c 100644
|
||||||
|
--- a/src/shellintrospect.c
|
||||||
|
+++ b/src/shellintrospect.c
|
||||||
|
@@ -62,7 +62,7 @@ static guint signals[N_SIGNALS];
|
||||||
|
|
||||||
|
static ShellIntrospect *_shell_introspect;
|
||||||
|
|
||||||
|
-static void
|
||||||
|
+void
|
||||||
|
window_free (Window *window)
|
||||||
|
{
|
||||||
|
g_free (window->title);
|
||||||
|
@@ -70,6 +70,19 @@ window_free (Window *window)
|
||||||
|
g_free (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
+Window *
|
||||||
|
+window_dup (Window *window)
|
||||||
|
+{
|
||||||
|
+ Window *new_window;
|
||||||
|
+
|
||||||
|
+ new_window = g_new0 (Window, 1);
|
||||||
|
+ new_window->id = window->id;
|
||||||
|
+ new_window->title = g_strdup (window->title);
|
||||||
|
+ new_window->app_id = g_strdup (window->app_id);
|
||||||
|
+
|
||||||
|
+ return new_window;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
get_windows_cb (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
diff --git a/src/shellintrospect.h b/src/shellintrospect.h
|
||||||
|
index f63ecee..ea4188f 100644
|
||||||
|
--- a/src/shellintrospect.h
|
||||||
|
+++ b/src/shellintrospect.h
|
||||||
|
@@ -34,6 +34,10 @@ void shell_introspect_ref_listeners (ShellIntrospect *shell_introspect);
|
||||||
|
|
||||||
|
void shell_introspect_unref_listeners (ShellIntrospect *shell_introspect);
|
||||||
|
|
||||||
|
+void window_free (Window *window);
|
||||||
|
+
|
||||||
|
+Window * window_dup (Window *window);
|
||||||
|
+
|
||||||
|
const char * window_get_app_id (Window *window);
|
||||||
|
|
||||||
|
const char * window_get_title (Window *window);
|
@ -0,0 +1,23 @@
|
|||||||
|
From a7c03eb9642a244f5623bf5bbe0e29f759554567 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Wed, 10 Nov 2021 15:52:37 -0300
|
||||||
|
Subject: [PATCH] screencast: Cleanup unnecessary forward declaration
|
||||||
|
|
||||||
|
---
|
||||||
|
src/screencast.c | 3 ---
|
||||||
|
1 file changed, 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 38d1d05..98390ab 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -77,9 +77,6 @@ static GnomeScreenCast *gnome_screen_cast;
|
||||||
|
GType screen_cast_session_get_type (void);
|
||||||
|
G_DEFINE_TYPE (ScreenCastSession, screen_cast_session, session_get_type ())
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-start_done (ScreenCastSession *session);
|
||||||
|
-
|
||||||
|
static gboolean
|
||||||
|
start_session (ScreenCastSession *session,
|
||||||
|
GVariant *selections,
|
452
0003-screencast-more-code-shuffling-and-cleanups.patch
Normal file
452
0003-screencast-more-code-shuffling-and-cleanups.patch
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
From 367f05b980ab780ae3b3380164f2135ce4f487fa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Wed, 10 Nov 2021 16:04:59 -0300
|
||||||
|
Subject: [PATCH] screencast: More code shuffling and cleanups
|
||||||
|
|
||||||
|
No funcional changes.
|
||||||
|
---
|
||||||
|
src/screencast.c | 350 +++++++++++++++++++++++------------------------
|
||||||
|
1 file changed, 168 insertions(+), 182 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 98390ab..4ba67aa 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -82,10 +82,6 @@ start_session (ScreenCastSession *session,
|
||||||
|
GVariant *selections,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-cancel_start_session (ScreenCastSession *session,
|
||||||
|
- int response);
|
||||||
|
-
|
||||||
|
static gboolean
|
||||||
|
is_screen_cast_session (Session *session)
|
||||||
|
{
|
||||||
|
@@ -108,10 +104,23 @@ screen_cast_dialog_handle_close (ScreenCastDialogHandle *dialog_handle)
|
||||||
|
screen_cast_dialog_handle_free (dialog_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+cancel_start_session (ScreenCastSession *screen_cast_session,
|
||||||
|
+ int response)
|
||||||
|
+{
|
||||||
|
+ GVariantBuilder results_builder;
|
||||||
|
+
|
||||||
|
+ g_variant_builder_init (&results_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
+ xdp_impl_screen_cast_complete_start (XDP_IMPL_SCREEN_CAST (impl),
|
||||||
|
+ screen_cast_session->start_invocation,
|
||||||
|
+ response,
|
||||||
|
+ g_variant_builder_end (&results_builder));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gboolean
|
||||||
|
-handle_close (XdpImplRequest *object,
|
||||||
|
- GDBusMethodInvocation *invocation,
|
||||||
|
- ScreenCastDialogHandle *dialog_handle)
|
||||||
|
+on_request_handle_close_cb (XdpImplRequest *object,
|
||||||
|
+ GDBusMethodInvocation *invocation,
|
||||||
|
+ ScreenCastDialogHandle *dialog_handle)
|
||||||
|
{
|
||||||
|
cancel_start_session (dialog_handle->session, 2);
|
||||||
|
|
||||||
|
@@ -121,10 +130,10 @@ handle_close (XdpImplRequest *object,
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-screen_cast_dialog_done (GtkWidget *widget,
|
||||||
|
- int dialog_response,
|
||||||
|
- GVariant *selections,
|
||||||
|
- ScreenCastDialogHandle *dialog_handle)
|
||||||
|
+on_screen_cast_dialog_done_cb (GtkWidget *widget,
|
||||||
|
+ int dialog_response,
|
||||||
|
+ GVariant *selections,
|
||||||
|
+ ScreenCastDialogHandle *dialog_handle)
|
||||||
|
{
|
||||||
|
int response;
|
||||||
|
|
||||||
|
@@ -165,10 +174,10 @@ screen_cast_dialog_done (GtkWidget *widget,
|
||||||
|
}
|
||||||
|
|
||||||
|
static ScreenCastDialogHandle *
|
||||||
|
-create_screen_cast_dialog (ScreenCastSession *session,
|
||||||
|
+create_screen_cast_dialog (ScreenCastSession *session,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
- Request *request,
|
||||||
|
- const char *parent_window)
|
||||||
|
+ Request *request,
|
||||||
|
+ const char *parent_window)
|
||||||
|
{
|
||||||
|
ScreenCastDialogHandle *dialog_handle;
|
||||||
|
ExternalWindow *external_parent;
|
||||||
|
@@ -210,10 +219,9 @@ create_screen_cast_dialog (ScreenCastSession *session,
|
||||||
|
dialog_handle->dialog = dialog;
|
||||||
|
|
||||||
|
g_signal_connect (request, "handle-close",
|
||||||
|
- G_CALLBACK (handle_close), dialog_handle);
|
||||||
|
-
|
||||||
|
+ G_CALLBACK (on_request_handle_close_cb), dialog_handle);
|
||||||
|
g_signal_connect (dialog, "done",
|
||||||
|
- G_CALLBACK (screen_cast_dialog_done), dialog_handle);
|
||||||
|
+ G_CALLBACK (on_screen_cast_dialog_done_cb), dialog_handle);
|
||||||
|
|
||||||
|
gtk_widget_realize (dialog);
|
||||||
|
|
||||||
|
@@ -226,145 +234,6 @@ create_screen_cast_dialog (ScreenCastSession *session,
|
||||||
|
return dialog_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static ScreenCastSession *
|
||||||
|
-screen_cast_session_new (const char *app_id,
|
||||||
|
- const char *session_handle)
|
||||||
|
-{
|
||||||
|
- ScreenCastSession *screen_cast_session;
|
||||||
|
-
|
||||||
|
- screen_cast_session = g_object_new (screen_cast_session_get_type (),
|
||||||
|
- "id", session_handle,
|
||||||
|
- NULL);
|
||||||
|
-
|
||||||
|
- return screen_cast_session;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static gboolean
|
||||||
|
-handle_create_session (XdpImplScreenCast *object,
|
||||||
|
- GDBusMethodInvocation *invocation,
|
||||||
|
- const char *arg_handle,
|
||||||
|
- const char *arg_session_handle,
|
||||||
|
- const char *arg_app_id,
|
||||||
|
- GVariant *arg_options)
|
||||||
|
-{
|
||||||
|
- g_autoptr(GError) error = NULL;
|
||||||
|
- int response;
|
||||||
|
- Session *session;
|
||||||
|
- GVariantBuilder results_builder;
|
||||||
|
-
|
||||||
|
- session = (Session *)screen_cast_session_new (arg_app_id,
|
||||||
|
- arg_session_handle);
|
||||||
|
-
|
||||||
|
- if (!session_export (session,
|
||||||
|
- g_dbus_method_invocation_get_connection (invocation),
|
||||||
|
- &error))
|
||||||
|
- {
|
||||||
|
- g_clear_object (&session);
|
||||||
|
- g_warning ("Failed to create screen cast session: %s", error->message);
|
||||||
|
- response = 2;
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- response = 0;
|
||||||
|
-
|
||||||
|
-out:
|
||||||
|
- g_variant_builder_init (&results_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
- xdp_impl_screen_cast_complete_create_session (object,
|
||||||
|
- invocation,
|
||||||
|
- response,
|
||||||
|
- g_variant_builder_end (&results_builder));
|
||||||
|
-
|
||||||
|
- return TRUE;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static gboolean
|
||||||
|
-handle_select_sources (XdpImplScreenCast *object,
|
||||||
|
- GDBusMethodInvocation *invocation,
|
||||||
|
- const char *arg_handle,
|
||||||
|
- const char *arg_session_handle,
|
||||||
|
- const char *arg_app_id,
|
||||||
|
- GVariant *arg_options)
|
||||||
|
-{
|
||||||
|
- Session *session;
|
||||||
|
- int response;
|
||||||
|
- uint32_t types;
|
||||||
|
- gboolean multiple;
|
||||||
|
- ScreenCastCursorMode cursor_mode;
|
||||||
|
- ScreenCastSelection select;
|
||||||
|
- GVariantBuilder results_builder;
|
||||||
|
- GVariant *results;
|
||||||
|
-
|
||||||
|
- session = lookup_session (arg_session_handle);
|
||||||
|
- if (!session)
|
||||||
|
- {
|
||||||
|
- g_warning ("Tried to select sources on non-existing %s", arg_session_handle);
|
||||||
|
- response = 2;
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!g_variant_lookup (arg_options, "multiple", "b", &multiple))
|
||||||
|
- multiple = FALSE;
|
||||||
|
-
|
||||||
|
- if (!g_variant_lookup (arg_options, "types", "u", &types))
|
||||||
|
- types = SCREEN_CAST_SOURCE_TYPE_MONITOR;
|
||||||
|
-
|
||||||
|
- if (!(types & (SCREEN_CAST_SOURCE_TYPE_MONITOR |
|
||||||
|
- SCREEN_CAST_SOURCE_TYPE_WINDOW)))
|
||||||
|
- {
|
||||||
|
- g_warning ("Unknown screen cast source type");
|
||||||
|
- response = 2;
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!g_variant_lookup (arg_options, "cursor_mode", "u", &cursor_mode))
|
||||||
|
- cursor_mode = SCREEN_CAST_CURSOR_MODE_HIDDEN;
|
||||||
|
-
|
||||||
|
- switch (cursor_mode)
|
||||||
|
- {
|
||||||
|
- case SCREEN_CAST_CURSOR_MODE_HIDDEN:
|
||||||
|
- case SCREEN_CAST_CURSOR_MODE_EMBEDDED:
|
||||||
|
- case SCREEN_CAST_CURSOR_MODE_METADATA:
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- g_warning ("Unknown screen cast cursor mode");
|
||||||
|
- response = 2;
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- select.multiple = multiple;
|
||||||
|
- select.source_types = types;
|
||||||
|
- select.cursor_mode = cursor_mode;
|
||||||
|
-
|
||||||
|
- if (is_screen_cast_session (session))
|
||||||
|
- {
|
||||||
|
- ScreenCastSession *screen_cast_session = (ScreenCastSession *)session;
|
||||||
|
-
|
||||||
|
- screen_cast_session->select = select;
|
||||||
|
- response = 0;
|
||||||
|
- }
|
||||||
|
- else if (is_remote_desktop_session (session))
|
||||||
|
- {
|
||||||
|
- RemoteDesktopSession *remote_desktop_session =
|
||||||
|
- (RemoteDesktopSession *)session;
|
||||||
|
-
|
||||||
|
- remote_desktop_session_sources_selected (remote_desktop_session, &select);
|
||||||
|
- response = 0;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- g_warning ("Tried to select sources on invalid session type");
|
||||||
|
- response = 2;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-out:
|
||||||
|
- g_variant_builder_init (&results_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
- results = g_variant_builder_end (&results_builder);
|
||||||
|
- xdp_impl_screen_cast_complete_select_sources (object, invocation,
|
||||||
|
- response, results);
|
||||||
|
-
|
||||||
|
- return TRUE;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void
|
||||||
|
start_done (ScreenCastSession *screen_cast_session)
|
||||||
|
{
|
||||||
|
@@ -391,14 +260,14 @@ start_done (ScreenCastSession *screen_cast_session)
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_gnome_screen_cast_session_ready (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
- ScreenCastSession *screen_cast_session)
|
||||||
|
+ ScreenCastSession *screen_cast_session)
|
||||||
|
{
|
||||||
|
start_done (screen_cast_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_gnome_screen_cast_session_closed (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
- ScreenCastSession *screen_cast_session)
|
||||||
|
+ ScreenCastSession *screen_cast_session)
|
||||||
|
{
|
||||||
|
session_close ((Session *)screen_cast_session);
|
||||||
|
}
|
||||||
|
@@ -441,27 +310,14 @@ start_session (ScreenCastSession *screen_cast_session,
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-cancel_start_session (ScreenCastSession *screen_cast_session,
|
||||||
|
- int response)
|
||||||
|
-{
|
||||||
|
- GVariantBuilder results_builder;
|
||||||
|
-
|
||||||
|
- g_variant_builder_init (&results_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
- xdp_impl_screen_cast_complete_start (XDP_IMPL_SCREEN_CAST (impl),
|
||||||
|
- screen_cast_session->start_invocation,
|
||||||
|
- response,
|
||||||
|
- g_variant_builder_end (&results_builder));
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static gboolean
|
||||||
|
-handle_start (XdpImplScreenCast *object,
|
||||||
|
+handle_start (XdpImplScreenCast *object,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
- const char *arg_handle,
|
||||||
|
- const char *arg_session_handle,
|
||||||
|
- const char *arg_app_id,
|
||||||
|
- const char *arg_parent_window,
|
||||||
|
- GVariant *arg_options)
|
||||||
|
+ const char *arg_handle,
|
||||||
|
+ const char *arg_session_handle,
|
||||||
|
+ const char *arg_app_id,
|
||||||
|
+ const char *arg_parent_window,
|
||||||
|
+ GVariant *arg_options)
|
||||||
|
{
|
||||||
|
const char *sender;
|
||||||
|
g_autoptr(Request) request = NULL;
|
||||||
|
@@ -507,6 +363,133 @@ err:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static gboolean
|
||||||
|
+handle_select_sources (XdpImplScreenCast *object,
|
||||||
|
+ GDBusMethodInvocation *invocation,
|
||||||
|
+ const char *arg_handle,
|
||||||
|
+ const char *arg_session_handle,
|
||||||
|
+ const char *arg_app_id,
|
||||||
|
+ GVariant *arg_options)
|
||||||
|
+{
|
||||||
|
+ Session *session;
|
||||||
|
+ int response;
|
||||||
|
+ uint32_t types;
|
||||||
|
+ gboolean multiple;
|
||||||
|
+ ScreenCastCursorMode cursor_mode;
|
||||||
|
+ ScreenCastSelection select;
|
||||||
|
+ GVariantBuilder results_builder;
|
||||||
|
+ GVariant *results;
|
||||||
|
+
|
||||||
|
+ session = lookup_session (arg_session_handle);
|
||||||
|
+ if (!session)
|
||||||
|
+ {
|
||||||
|
+ g_warning ("Tried to select sources on non-existing %s", arg_session_handle);
|
||||||
|
+ response = 2;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!g_variant_lookup (arg_options, "multiple", "b", &multiple))
|
||||||
|
+ multiple = FALSE;
|
||||||
|
+
|
||||||
|
+ if (!g_variant_lookup (arg_options, "types", "u", &types))
|
||||||
|
+ types = SCREEN_CAST_SOURCE_TYPE_MONITOR;
|
||||||
|
+
|
||||||
|
+ if (!(types & (SCREEN_CAST_SOURCE_TYPE_MONITOR |
|
||||||
|
+ SCREEN_CAST_SOURCE_TYPE_WINDOW)))
|
||||||
|
+ {
|
||||||
|
+ g_warning ("Unknown screen cast source type");
|
||||||
|
+ response = 2;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!g_variant_lookup (arg_options, "cursor_mode", "u", &cursor_mode))
|
||||||
|
+ cursor_mode = SCREEN_CAST_CURSOR_MODE_HIDDEN;
|
||||||
|
+
|
||||||
|
+ switch (cursor_mode)
|
||||||
|
+ {
|
||||||
|
+ case SCREEN_CAST_CURSOR_MODE_HIDDEN:
|
||||||
|
+ case SCREEN_CAST_CURSOR_MODE_EMBEDDED:
|
||||||
|
+ case SCREEN_CAST_CURSOR_MODE_METADATA:
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ g_warning ("Unknown screen cast cursor mode");
|
||||||
|
+ response = 2;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ select.multiple = multiple;
|
||||||
|
+ select.source_types = types;
|
||||||
|
+ select.cursor_mode = cursor_mode;
|
||||||
|
+
|
||||||
|
+ if (is_screen_cast_session (session))
|
||||||
|
+ {
|
||||||
|
+ ScreenCastSession *screen_cast_session = (ScreenCastSession *)session;
|
||||||
|
+
|
||||||
|
+ screen_cast_session->select = select;
|
||||||
|
+ response = 0;
|
||||||
|
+ }
|
||||||
|
+ else if (is_remote_desktop_session (session))
|
||||||
|
+ {
|
||||||
|
+ RemoteDesktopSession *remote_desktop_session =
|
||||||
|
+ (RemoteDesktopSession *)session;
|
||||||
|
+
|
||||||
|
+ remote_desktop_session_sources_selected (remote_desktop_session, &select);
|
||||||
|
+ response = 0;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ g_warning ("Tried to select sources on invalid session type");
|
||||||
|
+ response = 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ g_variant_builder_init (&results_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
+ results = g_variant_builder_end (&results_builder);
|
||||||
|
+ xdp_impl_screen_cast_complete_select_sources (object, invocation,
|
||||||
|
+ response, results);
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static gboolean
|
||||||
|
+handle_create_session (XdpImplScreenCast *object,
|
||||||
|
+ GDBusMethodInvocation *invocation,
|
||||||
|
+ const char *arg_handle,
|
||||||
|
+ const char *arg_session_handle,
|
||||||
|
+ const char *arg_app_id,
|
||||||
|
+ GVariant *arg_options)
|
||||||
|
+{
|
||||||
|
+ g_autoptr(GError) error = NULL;
|
||||||
|
+ int response;
|
||||||
|
+ Session *session;
|
||||||
|
+ GVariantBuilder results_builder;
|
||||||
|
+
|
||||||
|
+ session = g_object_new (screen_cast_session_get_type (),
|
||||||
|
+ "id", arg_session_handle,
|
||||||
|
+ NULL);
|
||||||
|
+
|
||||||
|
+ if (!session_export (session,
|
||||||
|
+ g_dbus_method_invocation_get_connection (invocation),
|
||||||
|
+ &error))
|
||||||
|
+ {
|
||||||
|
+ g_clear_object (&session);
|
||||||
|
+ g_warning ("Failed to create screen cast session: %s", error->message);
|
||||||
|
+ response = 2;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ response = 0;
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ g_variant_builder_init (&results_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
+ xdp_impl_screen_cast_complete_create_session (object,
|
||||||
|
+ invocation,
|
||||||
|
+ response,
|
||||||
|
+ g_variant_builder_end (&results_builder));
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
on_gnome_screen_cast_enabled (GnomeScreenCast *gnome_screen_cast)
|
||||||
|
{
|
||||||
|
@@ -535,9 +518,12 @@ on_gnome_screen_cast_enabled (GnomeScreenCast *gnome_screen_cast)
|
||||||
|
|
||||||
|
available_cursor_modes = SCREEN_CAST_CURSOR_MODE_NONE;
|
||||||
|
if (gnome_api_version >= 2)
|
||||||
|
- available_cursor_modes |= (SCREEN_CAST_CURSOR_MODE_HIDDEN |
|
||||||
|
- SCREEN_CAST_CURSOR_MODE_EMBEDDED |
|
||||||
|
- SCREEN_CAST_CURSOR_MODE_METADATA);
|
||||||
|
+ {
|
||||||
|
+ available_cursor_modes |= SCREEN_CAST_CURSOR_MODE_HIDDEN |
|
||||||
|
+ SCREEN_CAST_CURSOR_MODE_EMBEDDED |
|
||||||
|
+ SCREEN_CAST_CURSOR_MODE_METADATA;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
g_object_set (G_OBJECT (impl),
|
||||||
|
"available-cursor-modes", available_cursor_modes,
|
||||||
|
NULL);
|
||||||
|
@@ -620,8 +606,8 @@ screen_cast_session_class_init (ScreenCastSessionClass *klass)
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
-screen_cast_init (GDBusConnection *connection,
|
||||||
|
- GError **error)
|
||||||
|
+screen_cast_init (GDBusConnection *connection,
|
||||||
|
+ GError **error)
|
||||||
|
{
|
||||||
|
impl_connection = connection;
|
||||||
|
gnome_screen_cast = gnome_screen_cast_new (connection);
|
744
0004-screencastwidget-rework-selection-api.patch
Normal file
744
0004-screencastwidget-rework-selection-api.patch
Normal file
@ -0,0 +1,744 @@
|
|||||||
|
From 0f6957254e32ab6dc1c132c0f7623bbac31309f6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Wed, 10 Nov 2021 19:54:39 -0300
|
||||||
|
Subject: [PATCH] screencastwidget: Rework selection APIs
|
||||||
|
|
||||||
|
Instead of passing data around using GVariants, add
|
||||||
|
properly types variables and structures all around.
|
||||||
|
This will vastly simplify future commits introducing
|
||||||
|
screencast stream restore.
|
||||||
|
---
|
||||||
|
src/gnomescreencast.c | 51 ++++++-------
|
||||||
|
src/gnomescreencast.h | 8 +-
|
||||||
|
src/remotedesktop.c | 40 +++++-----
|
||||||
|
src/remotedesktopdialog.c | 35 ++++-----
|
||||||
|
src/screencast.c | 151 +++++++++++++++++---------------------
|
||||||
|
src/screencast.h | 12 +++
|
||||||
|
src/screencastdialog.c | 15 ++--
|
||||||
|
src/screencastwidget.c | 132 +++++++++++++++------------------
|
||||||
|
src/screencastwidget.h | 3 +-
|
||||||
|
9 files changed, 203 insertions(+), 244 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/gnomescreencast.c b/src/gnomescreencast.c
|
||||||
|
index abf5b53..3f8539c 100644
|
||||||
|
--- a/src/gnomescreencast.c
|
||||||
|
+++ b/src/gnomescreencast.c
|
||||||
|
@@ -274,10 +274,10 @@ cursor_mode_to_gnome_cursor_mode (ScreenCastCursorMode cursor_mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
-gnome_screen_cast_session_record_window (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
- const guint64 id,
|
||||||
|
- ScreenCastSelection *select,
|
||||||
|
- GError **error)
|
||||||
|
+gnome_screen_cast_session_record_window (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
+ Window *window,
|
||||||
|
+ ScreenCastSelection *select,
|
||||||
|
+ GError **error)
|
||||||
|
{
|
||||||
|
OrgGnomeMutterScreenCastSession *session_proxy =
|
||||||
|
gnome_screen_cast_session->proxy;
|
||||||
|
@@ -292,7 +292,7 @@ gnome_screen_cast_session_record_window (GnomeScreenCastSession *gnome_screen_ca
|
||||||
|
g_variant_builder_init (&properties_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
g_variant_builder_add (&properties_builder, "{sv}",
|
||||||
|
"window-id",
|
||||||
|
- g_variant_new_uint64 (id));
|
||||||
|
+ g_variant_new_uint64 (window_get_id (window)));
|
||||||
|
if (select->cursor_mode)
|
||||||
|
{
|
||||||
|
uint32_t gnome_cursor_mode;
|
||||||
|
@@ -356,10 +356,10 @@ gnome_screen_cast_session_record_window (GnomeScreenCastSession *gnome_screen_ca
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
-gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
- const char *connector,
|
||||||
|
- ScreenCastSelection *select,
|
||||||
|
- GError **error)
|
||||||
|
+gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
+ Monitor *monitor,
|
||||||
|
+ ScreenCastSelection *select,
|
||||||
|
+ GError **error)
|
||||||
|
{
|
||||||
|
OrgGnomeMutterScreenCastSession *session_proxy =
|
||||||
|
gnome_screen_cast_session->proxy;
|
||||||
|
@@ -370,6 +370,7 @@ gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_c
|
||||||
|
OrgGnomeMutterScreenCastStream *stream_proxy;
|
||||||
|
GnomeScreenCastStream *stream;
|
||||||
|
GVariant *parameters;
|
||||||
|
+ const char *connector;
|
||||||
|
|
||||||
|
g_variant_builder_init (&properties_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
if (select->cursor_mode)
|
||||||
|
@@ -383,6 +384,7 @@ gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_c
|
||||||
|
}
|
||||||
|
properties = g_variant_builder_end (&properties_builder);
|
||||||
|
|
||||||
|
+ connector = monitor_get_connector (monitor);
|
||||||
|
if (!org_gnome_mutter_screen_cast_session_call_record_monitor_sync (session_proxy,
|
||||||
|
connector,
|
||||||
|
properties,
|
||||||
|
@@ -436,40 +438,29 @@ gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_c
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
-gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
- GVariant *selections,
|
||||||
|
- ScreenCastSelection *select,
|
||||||
|
- GError **error)
|
||||||
|
+gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
+ GPtrArray *streams,
|
||||||
|
+ ScreenCastSelection *select,
|
||||||
|
+ GError **error)
|
||||||
|
{
|
||||||
|
- GVariantIter selections_iter;
|
||||||
|
- GVariant *selection;
|
||||||
|
+ guint i;
|
||||||
|
|
||||||
|
- g_variant_iter_init (&selections_iter, selections);
|
||||||
|
- while ((selection = g_variant_iter_next_value (&selections_iter)))
|
||||||
|
+ for (i = 0; i < streams->len; i++)
|
||||||
|
{
|
||||||
|
- ScreenCastSourceType source_type;
|
||||||
|
- g_autofree char *key = NULL;
|
||||||
|
- g_autoptr(GVariant) variant = NULL;
|
||||||
|
- guint64 id;
|
||||||
|
+ ScreenCastStreamInfo *info = g_ptr_array_index (streams, i);
|
||||||
|
|
||||||
|
- g_variant_get (selection, "(u?)",
|
||||||
|
- &source_type,
|
||||||
|
- &variant);
|
||||||
|
-
|
||||||
|
- switch (source_type)
|
||||||
|
+ switch (info->type)
|
||||||
|
{
|
||||||
|
case SCREEN_CAST_SOURCE_TYPE_MONITOR:
|
||||||
|
- key = g_variant_dup_string (variant, NULL);
|
||||||
|
if (!gnome_screen_cast_session_record_monitor (gnome_screen_cast_session,
|
||||||
|
- key,
|
||||||
|
+ info->data.monitor,
|
||||||
|
select,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
case SCREEN_CAST_SOURCE_TYPE_WINDOW:
|
||||||
|
- id = g_variant_get_uint64 (variant);
|
||||||
|
if (!gnome_screen_cast_session_record_window (gnome_screen_cast_session,
|
||||||
|
- id,
|
||||||
|
+ info->data.window,
|
||||||
|
select,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
diff --git a/src/gnomescreencast.h b/src/gnomescreencast.h
|
||||||
|
index 06e4e1e..748cf7d 100644
|
||||||
|
--- a/src/gnomescreencast.h
|
||||||
|
+++ b/src/gnomescreencast.h
|
||||||
|
@@ -34,10 +34,10 @@ const char * gnome_screen_cast_session_get_stream_path_from_id (GnomeScreenCastS
|
||||||
|
void gnome_screen_cast_session_add_stream_properties (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
GVariantBuilder *streams_builder);
|
||||||
|
|
||||||
|
-gboolean gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
- GVariant *selections,
|
||||||
|
- ScreenCastSelection *select,
|
||||||
|
- GError **error);
|
||||||
|
+gboolean gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
+ GPtrArray *streams,
|
||||||
|
+ ScreenCastSelection *select,
|
||||||
|
+ GError **error);
|
||||||
|
|
||||||
|
gboolean gnome_screen_cast_session_stop (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
GError **error);
|
||||||
|
diff --git a/src/remotedesktop.c b/src/remotedesktop.c
|
||||||
|
index a1c688a..46d1dcc 100644
|
||||||
|
--- a/src/remotedesktop.c
|
||||||
|
+++ b/src/remotedesktop.c
|
||||||
|
@@ -104,9 +104,10 @@ static void
|
||||||
|
start_done (RemoteDesktopSession *session);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
-start_session (RemoteDesktopSession *session,
|
||||||
|
- GVariant *selections,
|
||||||
|
- GError **error);
|
||||||
|
+start_session (RemoteDesktopSession *session,
|
||||||
|
+ RemoteDesktopDeviceType device_types,
|
||||||
|
+ GPtrArray *streams,
|
||||||
|
+ GError **error);
|
||||||
|
|
||||||
|
static void
|
||||||
|
cancel_start_session (RemoteDesktopSession *session,
|
||||||
|
@@ -155,9 +156,10 @@ handle_close (XdpImplRequest *object,
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-remote_desktop_dialog_done (GtkWidget *widget,
|
||||||
|
- int dialog_response,
|
||||||
|
- GVariant *selections,
|
||||||
|
+remote_desktop_dialog_done (GtkWidget *widget,
|
||||||
|
+ int dialog_response,
|
||||||
|
+ RemoteDesktopDeviceType device_types,
|
||||||
|
+ GPtrArray *streams,
|
||||||
|
RemoteDesktopDialogHandle *dialog_handle)
|
||||||
|
{
|
||||||
|
int response;
|
||||||
|
@@ -184,7 +186,7 @@ remote_desktop_dialog_done (GtkWidget *widget,
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
- if (!start_session (dialog_handle->session, selections, &error))
|
||||||
|
+ if (!start_session (dialog_handle->session, device_types, streams, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to start session: %s", error->message);
|
||||||
|
response = 2;
|
||||||
|
@@ -453,9 +455,9 @@ on_gnome_screen_cast_session_ready (GnomeScreenCastSession *gnome_screen_cast_se
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
-open_screen_cast_session (RemoteDesktopSession *remote_desktop_session,
|
||||||
|
- GVariant *source_selections,
|
||||||
|
- GError **error)
|
||||||
|
+open_screen_cast_session (RemoteDesktopSession *remote_desktop_session,
|
||||||
|
+ GPtrArray *streams,
|
||||||
|
+ GError **error)
|
||||||
|
{
|
||||||
|
OrgGnomeMutterRemoteDesktopSession *session_proxy =
|
||||||
|
remote_desktop_session->mutter_session_proxy;
|
||||||
|
@@ -478,7 +480,7 @@ open_screen_cast_session (RemoteDesktopSession *remote_desktop_session,
|
||||||
|
remote_desktop_session);
|
||||||
|
|
||||||
|
if (!gnome_screen_cast_session_record_selections (gnome_screen_cast_session,
|
||||||
|
- source_selections,
|
||||||
|
+ streams,
|
||||||
|
&remote_desktop_session->select.screen_cast,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
@@ -487,23 +489,19 @@ open_screen_cast_session (RemoteDesktopSession *remote_desktop_session,
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
-start_session (RemoteDesktopSession *remote_desktop_session,
|
||||||
|
- GVariant *selections,
|
||||||
|
- GError **error)
|
||||||
|
+start_session (RemoteDesktopSession *remote_desktop_session,
|
||||||
|
+ RemoteDesktopDeviceType device_types,
|
||||||
|
+ GPtrArray *streams,
|
||||||
|
+ GError **error)
|
||||||
|
{
|
||||||
|
OrgGnomeMutterRemoteDesktopSession *session_proxy;
|
||||||
|
- RemoteDesktopDeviceType device_types = 0;
|
||||||
|
- g_autoptr(GVariant) source_selections = NULL;
|
||||||
|
gboolean need_streams;
|
||||||
|
|
||||||
|
- g_variant_lookup (selections, "selected_device_types", "u", &device_types);
|
||||||
|
remote_desktop_session->shared.device_types = device_types;
|
||||||
|
|
||||||
|
- if (g_variant_lookup (selections, "selected_screen_cast_sources", "@a(us)",
|
||||||
|
- &source_selections))
|
||||||
|
+ if (streams)
|
||||||
|
{
|
||||||
|
- if (!open_screen_cast_session (remote_desktop_session,
|
||||||
|
- source_selections, error))
|
||||||
|
+ if (!open_screen_cast_session (remote_desktop_session, streams, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
need_streams = TRUE;
|
||||||
|
diff --git a/src/remotedesktopdialog.c b/src/remotedesktopdialog.c
|
||||||
|
index a21b008..bae7678 100644
|
||||||
|
--- a/src/remotedesktopdialog.c
|
||||||
|
+++ b/src/remotedesktopdialog.c
|
||||||
|
@@ -61,9 +61,8 @@ static GQuark quark_device_widget_data;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (RemoteDesktopDialog, remote_desktop_dialog, GTK_TYPE_WINDOW)
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-add_device_type_selections (RemoteDesktopDialog *dialog,
|
||||||
|
- GVariantBuilder *selections_builder)
|
||||||
|
+static RemoteDesktopDeviceType
|
||||||
|
+get_selected_device_types (RemoteDesktopDialog *dialog)
|
||||||
|
{
|
||||||
|
GList *selected_rows;
|
||||||
|
GList *l;
|
||||||
|
@@ -81,43 +80,36 @@ add_device_type_selections (RemoteDesktopDialog *dialog,
|
||||||
|
}
|
||||||
|
g_list_free (selected_rows);
|
||||||
|
|
||||||
|
- g_variant_builder_add (selections_builder, "{sv}",
|
||||||
|
- "selected_device_types",
|
||||||
|
- g_variant_new_uint32 (selected_device_types));
|
||||||
|
+ return selected_device_types;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
button_clicked (GtkWidget *button,
|
||||||
|
RemoteDesktopDialog *dialog)
|
||||||
|
{
|
||||||
|
+ RemoteDesktopDeviceType device_types = 0;
|
||||||
|
+ g_autoptr(GPtrArray) streams = NULL;
|
||||||
|
int response;
|
||||||
|
- GVariant *selections;
|
||||||
|
|
||||||
|
gtk_widget_hide (GTK_WIDGET (dialog));
|
||||||
|
|
||||||
|
if (button == dialog->accept_button)
|
||||||
|
{
|
||||||
|
- GVariantBuilder selections_builder;
|
||||||
|
ScreenCastWidget *screen_cast_widget =
|
||||||
|
SCREEN_CAST_WIDGET (dialog->screen_cast_widget);
|
||||||
|
|
||||||
|
response = GTK_RESPONSE_OK;
|
||||||
|
-
|
||||||
|
- g_variant_builder_init (&selections_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
-
|
||||||
|
- add_device_type_selections (dialog, &selections_builder);
|
||||||
|
- if (dialog->screen_cast_enable)
|
||||||
|
- screen_cast_widget_add_selections (screen_cast_widget,
|
||||||
|
- &selections_builder);
|
||||||
|
- selections = g_variant_builder_end (&selections_builder);
|
||||||
|
+ device_types = get_selected_device_types (dialog);
|
||||||
|
+ streams = screen_cast_widget_get_selected_streams (screen_cast_widget);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response = GTK_RESPONSE_CANCEL;
|
||||||
|
- selections = NULL;
|
||||||
|
+ device_types = 0;
|
||||||
|
+ streams = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- g_signal_emit (dialog, signals[DONE], 0, response, selections);
|
||||||
|
+ g_signal_emit (dialog, signals[DONE], 0, response, device_types, streams);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -356,7 +348,7 @@ remote_desktop_dialog_close_request (GtkWindow *dialog)
|
||||||
|
{
|
||||||
|
gtk_widget_hide (GTK_WIDGET (dialog));
|
||||||
|
|
||||||
|
- g_signal_emit (dialog, signals[DONE], 0, GTK_RESPONSE_CANCEL, NULL);
|
||||||
|
+ g_signal_emit (dialog, signals[DONE], 0, GTK_RESPONSE_CANCEL, 0, NULL);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
@@ -375,9 +367,10 @@ remote_desktop_dialog_class_init (RemoteDesktopDialogClass *klass)
|
||||||
|
0,
|
||||||
|
NULL, NULL,
|
||||||
|
NULL,
|
||||||
|
- G_TYPE_NONE, 2,
|
||||||
|
+ G_TYPE_NONE, 3,
|
||||||
|
+ G_TYPE_INT,
|
||||||
|
G_TYPE_INT,
|
||||||
|
- G_TYPE_VARIANT);
|
||||||
|
+ G_TYPE_PTR_ARRAY);
|
||||||
|
|
||||||
|
init_screen_cast_widget ();
|
||||||
|
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 4ba67aa..2713d26 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -77,11 +77,6 @@ static GnomeScreenCast *gnome_screen_cast;
|
||||||
|
GType screen_cast_session_get_type (void);
|
||||||
|
G_DEFINE_TYPE (ScreenCastSession, screen_cast_session, session_get_type ())
|
||||||
|
|
||||||
|
-static gboolean
|
||||||
|
-start_session (ScreenCastSession *session,
|
||||||
|
- GVariant *selections,
|
||||||
|
- GError **error);
|
||||||
|
-
|
||||||
|
static gboolean
|
||||||
|
is_screen_cast_session (Session *session)
|
||||||
|
{
|
||||||
|
@@ -129,10 +124,76 @@ on_request_handle_close_cb (XdpImplRequest *object,
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+on_gnome_screen_cast_session_ready (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
+ ScreenCastSession *screen_cast_session)
|
||||||
|
+{
|
||||||
|
+ GVariantBuilder streams_builder;
|
||||||
|
+ GVariantBuilder results_builder;
|
||||||
|
+
|
||||||
|
+ g_variant_builder_init (&results_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
+ g_variant_builder_init (&streams_builder, G_VARIANT_TYPE ("a(ua{sv})"));
|
||||||
|
+
|
||||||
|
+ gnome_screen_cast_session = screen_cast_session->gnome_screen_cast_session;
|
||||||
|
+ gnome_screen_cast_session_add_stream_properties (gnome_screen_cast_session,
|
||||||
|
+ &streams_builder);
|
||||||
|
+
|
||||||
|
+ g_variant_builder_add (&results_builder, "{sv}",
|
||||||
|
+ "streams",
|
||||||
|
+ g_variant_builder_end (&streams_builder));
|
||||||
|
+
|
||||||
|
+ xdp_impl_screen_cast_complete_start (XDP_IMPL_SCREEN_CAST (impl),
|
||||||
|
+ screen_cast_session->start_invocation, 0,
|
||||||
|
+ g_variant_builder_end (&results_builder));
|
||||||
|
+ screen_cast_session->start_invocation = NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+on_gnome_screen_cast_session_closed (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
+ ScreenCastSession *screen_cast_session)
|
||||||
|
+{
|
||||||
|
+ session_close ((Session *)screen_cast_session);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static gboolean
|
||||||
|
+start_session (ScreenCastSession *screen_cast_session,
|
||||||
|
+ GPtrArray *streams,
|
||||||
|
+ GError **error)
|
||||||
|
+{
|
||||||
|
+ GnomeScreenCastSession *gnome_screen_cast_session;
|
||||||
|
+
|
||||||
|
+ gnome_screen_cast_session =
|
||||||
|
+ gnome_screen_cast_create_session (gnome_screen_cast, NULL, error);
|
||||||
|
+ if (!gnome_screen_cast_session)
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ screen_cast_session->gnome_screen_cast_session = gnome_screen_cast_session;
|
||||||
|
+
|
||||||
|
+ screen_cast_session->session_ready_handler_id =
|
||||||
|
+ g_signal_connect (gnome_screen_cast_session, "ready",
|
||||||
|
+ G_CALLBACK (on_gnome_screen_cast_session_ready),
|
||||||
|
+ screen_cast_session);
|
||||||
|
+ screen_cast_session->session_closed_handler_id =
|
||||||
|
+ g_signal_connect (gnome_screen_cast_session, "closed",
|
||||||
|
+ G_CALLBACK (on_gnome_screen_cast_session_closed),
|
||||||
|
+ screen_cast_session);
|
||||||
|
+
|
||||||
|
+ if (!gnome_screen_cast_session_record_selections (gnome_screen_cast_session,
|
||||||
|
+ streams,
|
||||||
|
+ &screen_cast_session->select,
|
||||||
|
+ error))
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ if (!gnome_screen_cast_session_start (gnome_screen_cast_session, error))
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
on_screen_cast_dialog_done_cb (GtkWidget *widget,
|
||||||
|
int dialog_response,
|
||||||
|
- GVariant *selections,
|
||||||
|
+ GPtrArray *streams,
|
||||||
|
ScreenCastDialogHandle *dialog_handle)
|
||||||
|
{
|
||||||
|
int response;
|
||||||
|
@@ -159,7 +220,7 @@ on_screen_cast_dialog_done_cb (GtkWidget *widget,
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
- if (!start_session (dialog_handle->session, selections, &error))
|
||||||
|
+ if (!start_session (dialog_handle->session, streams, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to start session: %s", error->message);
|
||||||
|
response = 2;
|
||||||
|
@@ -234,82 +295,6 @@ create_screen_cast_dialog (ScreenCastSession *session,
|
||||||
|
return dialog_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-start_done (ScreenCastSession *screen_cast_session)
|
||||||
|
-{
|
||||||
|
- GnomeScreenCastSession *gnome_screen_cast_session;
|
||||||
|
- GVariantBuilder streams_builder;
|
||||||
|
- GVariantBuilder results_builder;
|
||||||
|
-
|
||||||
|
- g_variant_builder_init (&results_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
- g_variant_builder_init (&streams_builder, G_VARIANT_TYPE ("a(ua{sv})"));
|
||||||
|
-
|
||||||
|
- gnome_screen_cast_session = screen_cast_session->gnome_screen_cast_session;
|
||||||
|
- gnome_screen_cast_session_add_stream_properties (gnome_screen_cast_session,
|
||||||
|
- &streams_builder);
|
||||||
|
-
|
||||||
|
- g_variant_builder_add (&results_builder, "{sv}",
|
||||||
|
- "streams",
|
||||||
|
- g_variant_builder_end (&streams_builder));
|
||||||
|
-
|
||||||
|
- xdp_impl_screen_cast_complete_start (XDP_IMPL_SCREEN_CAST (impl),
|
||||||
|
- screen_cast_session->start_invocation, 0,
|
||||||
|
- g_variant_builder_end (&results_builder));
|
||||||
|
- screen_cast_session->start_invocation = NULL;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-on_gnome_screen_cast_session_ready (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
- ScreenCastSession *screen_cast_session)
|
||||||
|
-{
|
||||||
|
- start_done (screen_cast_session);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-on_gnome_screen_cast_session_closed (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
- ScreenCastSession *screen_cast_session)
|
||||||
|
-{
|
||||||
|
- session_close ((Session *)screen_cast_session);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static gboolean
|
||||||
|
-start_session (ScreenCastSession *screen_cast_session,
|
||||||
|
- GVariant *selections,
|
||||||
|
- GError **error)
|
||||||
|
-{
|
||||||
|
- GnomeScreenCastSession *gnome_screen_cast_session;
|
||||||
|
- g_autoptr(GVariant) source_selections = NULL;
|
||||||
|
-
|
||||||
|
- gnome_screen_cast_session =
|
||||||
|
- gnome_screen_cast_create_session (gnome_screen_cast, NULL, error);
|
||||||
|
- if (!gnome_screen_cast_session)
|
||||||
|
- return FALSE;
|
||||||
|
-
|
||||||
|
- screen_cast_session->gnome_screen_cast_session = gnome_screen_cast_session;
|
||||||
|
-
|
||||||
|
- screen_cast_session->session_ready_handler_id =
|
||||||
|
- g_signal_connect (gnome_screen_cast_session, "ready",
|
||||||
|
- G_CALLBACK (on_gnome_screen_cast_session_ready),
|
||||||
|
- screen_cast_session);
|
||||||
|
- screen_cast_session->session_closed_handler_id =
|
||||||
|
- g_signal_connect (gnome_screen_cast_session, "closed",
|
||||||
|
- G_CALLBACK (on_gnome_screen_cast_session_closed),
|
||||||
|
- screen_cast_session);
|
||||||
|
-
|
||||||
|
- g_variant_lookup (selections, "selected_screen_cast_sources", "@a(u?)",
|
||||||
|
- &source_selections);
|
||||||
|
- if (!gnome_screen_cast_session_record_selections (gnome_screen_cast_session,
|
||||||
|
- source_selections,
|
||||||
|
- &screen_cast_session->select,
|
||||||
|
- error))
|
||||||
|
- return FALSE;
|
||||||
|
-
|
||||||
|
- if (!gnome_screen_cast_session_start (gnome_screen_cast_session, error))
|
||||||
|
- return FALSE;
|
||||||
|
-
|
||||||
|
- return TRUE;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static gboolean
|
||||||
|
handle_start (XdpImplScreenCast *object,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
diff --git a/src/screencast.h b/src/screencast.h
|
||||||
|
index f5033b2..a9be16b 100644
|
||||||
|
--- a/src/screencast.h
|
||||||
|
+++ b/src/screencast.h
|
||||||
|
@@ -21,6 +21,9 @@
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
+#include "displaystatetracker.h"
|
||||||
|
+#include "shellintrospect.h"
|
||||||
|
+
|
||||||
|
typedef enum _ScreenCastSourceType
|
||||||
|
{
|
||||||
|
SCREEN_CAST_SOURCE_TYPE_MONITOR = 1,
|
||||||
|
@@ -42,5 +45,14 @@ typedef struct _ScreenCastSelection
|
||||||
|
ScreenCastCursorMode cursor_mode;
|
||||||
|
} ScreenCastSelection;
|
||||||
|
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ ScreenCastSourceType type;
|
||||||
|
+ union {
|
||||||
|
+ Monitor *monitor;
|
||||||
|
+ Window *window;
|
||||||
|
+ } data;
|
||||||
|
+} ScreenCastStreamInfo;
|
||||||
|
+
|
||||||
|
gboolean screen_cast_init (GDBusConnection *connection,
|
||||||
|
GError **error);
|
||||||
|
diff --git a/src/screencastdialog.c b/src/screencastdialog.c
|
||||||
|
index 56d4d49..3e3b064 100644
|
||||||
|
--- a/src/screencastdialog.c
|
||||||
|
+++ b/src/screencastdialog.c
|
||||||
|
@@ -59,8 +59,8 @@ static void
|
||||||
|
button_clicked (GtkWidget *button,
|
||||||
|
ScreenCastDialog *dialog)
|
||||||
|
{
|
||||||
|
+ g_autoptr(GPtrArray) streams = NULL;
|
||||||
|
int response;
|
||||||
|
- GVariant *selections;
|
||||||
|
|
||||||
|
gtk_widget_hide (GTK_WIDGET (dialog));
|
||||||
|
|
||||||
|
@@ -68,22 +68,17 @@ button_clicked (GtkWidget *button,
|
||||||
|
{
|
||||||
|
ScreenCastWidget *screen_cast_widget =
|
||||||
|
SCREEN_CAST_WIDGET (dialog->screen_cast_widget);
|
||||||
|
- GVariantBuilder selections_builder;
|
||||||
|
|
||||||
|
response = GTK_RESPONSE_OK;
|
||||||
|
-
|
||||||
|
- g_variant_builder_init (&selections_builder, G_VARIANT_TYPE ("a{sv}"));
|
||||||
|
- screen_cast_widget_add_selections (screen_cast_widget,
|
||||||
|
- &selections_builder);
|
||||||
|
- selections = g_variant_builder_end (&selections_builder);
|
||||||
|
+ streams = screen_cast_widget_get_selected_streams (screen_cast_widget);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response = GTK_RESPONSE_CANCEL;
|
||||||
|
- selections = NULL;
|
||||||
|
+ streams = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- g_signal_emit (dialog, signals[DONE], 0, response, selections);
|
||||||
|
+ g_signal_emit (dialog, signals[DONE], 0, response, streams);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -127,7 +122,7 @@ screen_cast_dialog_class_init (ScreenCastDialogClass *klass)
|
||||||
|
NULL,
|
||||||
|
G_TYPE_NONE, 2,
|
||||||
|
G_TYPE_INT,
|
||||||
|
- G_TYPE_VARIANT);
|
||||||
|
+ G_TYPE_PTR_ARRAY);
|
||||||
|
|
||||||
|
init_screen_cast_widget ();
|
||||||
|
|
||||||
|
diff --git a/src/screencastwidget.c b/src/screencastwidget.c
|
||||||
|
index 454c93e..3119245 100644
|
||||||
|
--- a/src/screencastwidget.c
|
||||||
|
+++ b/src/screencastwidget.c
|
||||||
|
@@ -69,51 +69,6 @@ G_DEFINE_TYPE (ScreenCastWidget, screen_cast_widget, GTK_TYPE_BOX)
|
||||||
|
* Auxiliary methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static gboolean
|
||||||
|
-add_selections (ScreenCastWidget *widget,
|
||||||
|
- GVariantBuilder *source_selections_builder)
|
||||||
|
-{
|
||||||
|
- GList *selected_monitor_rows;
|
||||||
|
- GList *selected_window_rows;
|
||||||
|
- 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)
|
||||||
|
- return FALSE;
|
||||||
|
-
|
||||||
|
- for (l = selected_monitor_rows; l; l = l->next)
|
||||||
|
- {
|
||||||
|
- GtkWidget *monitor_widget = gtk_list_box_row_get_child (l->data);
|
||||||
|
- Monitor *monitor;
|
||||||
|
-
|
||||||
|
- monitor = g_object_get_qdata (G_OBJECT (monitor_widget),
|
||||||
|
- quark_monitor_widget_data);
|
||||||
|
-
|
||||||
|
- g_variant_builder_add (source_selections_builder, "(us)",
|
||||||
|
- SCREEN_CAST_SOURCE_TYPE_MONITOR,
|
||||||
|
- monitor_get_connector (monitor));
|
||||||
|
- }
|
||||||
|
- g_list_free (selected_monitor_rows);
|
||||||
|
- for (l = selected_window_rows; l; l = l->next)
|
||||||
|
- {
|
||||||
|
- GtkWidget *window_widget = gtk_list_box_row_get_child (l->data);
|
||||||
|
- Window *window;
|
||||||
|
-
|
||||||
|
- window = g_object_get_qdata (G_OBJECT (window_widget),
|
||||||
|
- quark_window_widget_data);
|
||||||
|
-
|
||||||
|
- g_variant_builder_add (source_selections_builder, "(ut)",
|
||||||
|
- SCREEN_CAST_SOURCE_TYPE_WINDOW,
|
||||||
|
- window_get_id (window));
|
||||||
|
- }
|
||||||
|
- g_list_free (selected_window_rows);
|
||||||
|
-
|
||||||
|
- return TRUE;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static GtkWidget *
|
||||||
|
create_window_widget (Window *window)
|
||||||
|
{
|
||||||
|
@@ -571,25 +526,6 @@ init_screen_cast_widget (void)
|
||||||
|
g_type_ensure (screen_cast_widget_get_type ());
|
||||||
|
}
|
||||||
|
|
||||||
|
-void
|
||||||
|
-screen_cast_widget_add_selections (ScreenCastWidget *widget,
|
||||||
|
- GVariantBuilder *selections_builder)
|
||||||
|
-{
|
||||||
|
- GVariantBuilder source_selections_builder;
|
||||||
|
-
|
||||||
|
- g_variant_builder_init (&source_selections_builder, G_VARIANT_TYPE ("a(u?)"));
|
||||||
|
- if (!add_selections (widget, &source_selections_builder))
|
||||||
|
- {
|
||||||
|
- g_variant_builder_clear (&source_selections_builder);
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- g_variant_builder_add (selections_builder, "{sv}",
|
||||||
|
- "selected_screen_cast_sources",
|
||||||
|
- g_variant_builder_end (&source_selections_builder));
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void
|
||||||
|
screen_cast_widget_set_app_id (ScreenCastWidget *widget,
|
||||||
|
const char *app_id)
|
||||||
|
@@ -649,3 +585,53 @@ screen_cast_widget_set_source_types (ScreenCastWidget *screen_cast_widget,
|
||||||
|
if (__builtin_popcount (source_types) > 1)
|
||||||
|
gtk_widget_show (screen_cast_widget->source_type_switcher);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+GPtrArray *
|
||||||
|
+screen_cast_widget_get_selected_streams (ScreenCastWidget *self)
|
||||||
|
+{
|
||||||
|
+ ScreenCastStreamInfo *info;
|
||||||
|
+ g_autoptr(GPtrArray) streams = NULL;
|
||||||
|
+ g_autoptr(GList) selected_monitor_rows = NULL;
|
||||||
|
+ g_autoptr(GList) selected_window_rows = NULL;
|
||||||
|
+ GList *l;
|
||||||
|
+
|
||||||
|
+ streams = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
+
|
||||||
|
+ selected_monitor_rows =
|
||||||
|
+ gtk_list_box_get_selected_rows (GTK_LIST_BOX (self->monitor_list));
|
||||||
|
+ selected_window_rows =
|
||||||
|
+ gtk_list_box_get_selected_rows (GTK_LIST_BOX (self->window_list));
|
||||||
|
+
|
||||||
|
+ if (!selected_monitor_rows && !selected_window_rows)
|
||||||
|
+ return g_steal_pointer (&streams);
|
||||||
|
+
|
||||||
|
+ for (l = selected_monitor_rows; l; l = l->next)
|
||||||
|
+ {
|
||||||
|
+ GtkWidget *monitor_widget = gtk_list_box_row_get_child (l->data);
|
||||||
|
+ Monitor *monitor;
|
||||||
|
+
|
||||||
|
+ monitor = g_object_get_qdata (G_OBJECT (monitor_widget),
|
||||||
|
+ quark_monitor_widget_data);
|
||||||
|
+
|
||||||
|
+ info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
+ info->type = SCREEN_CAST_SOURCE_TYPE_MONITOR;
|
||||||
|
+ info->data.monitor = monitor;
|
||||||
|
+ g_ptr_array_add (streams, info);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (l = selected_window_rows; l; l = l->next)
|
||||||
|
+ {
|
||||||
|
+ GtkWidget *window_widget = gtk_list_box_row_get_child (l->data);
|
||||||
|
+ Window *window;
|
||||||
|
+
|
||||||
|
+ window = g_object_get_qdata (G_OBJECT (window_widget),
|
||||||
|
+ quark_window_widget_data);
|
||||||
|
+
|
||||||
|
+ info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
+ info->type = SCREEN_CAST_SOURCE_TYPE_WINDOW;
|
||||||
|
+ info->data.window = window;
|
||||||
|
+ g_ptr_array_add (streams, info);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return g_steal_pointer (&streams);
|
||||||
|
+}
|
||||||
|
diff --git a/src/screencastwidget.h b/src/screencastwidget.h
|
||||||
|
index 34360a3..ad95903 100644
|
||||||
|
--- a/src/screencastwidget.h
|
||||||
|
+++ b/src/screencastwidget.h
|
||||||
|
@@ -39,5 +39,4 @@ void screen_cast_widget_set_allow_multiple (ScreenCastWidget *widget,
|
||||||
|
void screen_cast_widget_set_source_types (ScreenCastWidget *screen_cast_widget,
|
||||||
|
ScreenCastSourceType source_types);
|
||||||
|
|
||||||
|
-void screen_cast_widget_add_selections (ScreenCastWidget *widget,
|
||||||
|
- GVariantBuilder *selections_builder);
|
||||||
|
+GPtrArray *screen_cast_widget_get_selected_streams (ScreenCastWidget *self);
|
90
0005-displaystatetracker-add-match-string.patch
Normal file
90
0005-displaystatetracker-add-match-string.patch
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
From 36594e191980d84ca77ba09faddf3f160a9839cf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Tue, 28 Sep 2021 21:00:35 -0300
|
||||||
|
Subject: [PATCH] displaystatetracker: Add match string
|
||||||
|
|
||||||
|
The monitor's match string is a unique string that can be used to compare
|
||||||
|
monitors and check for equality. It's composed of the product, vendor, and
|
||||||
|
serial numbers. It'll be used by the next commit to restore sessions.
|
||||||
|
---
|
||||||
|
src/displaystatetracker.c | 18 +++++++++++++++---
|
||||||
|
src/displaystatetracker.h | 2 ++
|
||||||
|
2 files changed, 17 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/displaystatetracker.c b/src/displaystatetracker.c
|
||||||
|
index 6affd8a..fc9109e 100644
|
||||||
|
--- a/src/displaystatetracker.c
|
||||||
|
+++ b/src/displaystatetracker.c
|
||||||
|
@@ -35,6 +35,7 @@ static guint signals[N_SIGNALS];
|
||||||
|
typedef struct _Monitor
|
||||||
|
{
|
||||||
|
char *connector;
|
||||||
|
+ char *match_string;
|
||||||
|
char *display_name;
|
||||||
|
} Monitor;
|
||||||
|
|
||||||
|
@@ -65,6 +66,7 @@ static void
|
||||||
|
monitor_free (Monitor *monitor)
|
||||||
|
{
|
||||||
|
g_free (monitor->connector);
|
||||||
|
+ g_free (monitor->match_string);
|
||||||
|
g_free (monitor->display_name);
|
||||||
|
g_free (monitor);
|
||||||
|
}
|
||||||
|
@@ -75,6 +77,12 @@ monitor_get_connector (Monitor *monitor)
|
||||||
|
return monitor->connector;
|
||||||
|
}
|
||||||
|
|
||||||
|
+const char *
|
||||||
|
+monitor_get_match_string (Monitor *monitor)
|
||||||
|
+{
|
||||||
|
+ return monitor->match_string;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
const char *
|
||||||
|
monitor_get_display_name (Monitor *monitor)
|
||||||
|
{
|
||||||
|
@@ -109,6 +117,9 @@ generate_monitors (DisplayStateTracker *tracker,
|
||||||
|
g_variant_iter_init (&monitors_iter, monitors);
|
||||||
|
while ((monitor_variant = g_variant_iter_next_value (&monitors_iter)))
|
||||||
|
{
|
||||||
|
+ g_autofree char *vendor = NULL;
|
||||||
|
+ g_autofree char *product = NULL;
|
||||||
|
+ g_autofree char *serial = NULL;
|
||||||
|
Monitor *monitor;
|
||||||
|
char *connector;
|
||||||
|
char *display_name;
|
||||||
|
@@ -116,9 +127,9 @@ generate_monitors (DisplayStateTracker *tracker,
|
||||||
|
|
||||||
|
g_variant_get (monitor_variant, "((ssss)a(siiddada{sv})@a{sv})",
|
||||||
|
&connector,
|
||||||
|
- NULL /* vendor */,
|
||||||
|
- NULL /* product */,
|
||||||
|
- NULL /* serial */,
|
||||||
|
+ &vendor,
|
||||||
|
+ &product,
|
||||||
|
+ &serial,
|
||||||
|
NULL /* modes */,
|
||||||
|
&properties);
|
||||||
|
|
||||||
|
@@ -128,6 +139,7 @@ generate_monitors (DisplayStateTracker *tracker,
|
||||||
|
monitor = g_new0 (Monitor, 1);
|
||||||
|
*monitor = (Monitor) {
|
||||||
|
.connector = connector,
|
||||||
|
+ .match_string = g_strdup_printf ("%s:%s:%s", vendor, product, serial),
|
||||||
|
.display_name = display_name
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/src/displaystatetracker.h b/src/displaystatetracker.h
|
||||||
|
index 54c63fa..1c3a7dc 100644
|
||||||
|
--- a/src/displaystatetracker.h
|
||||||
|
+++ b/src/displaystatetracker.h
|
||||||
|
@@ -28,6 +28,8 @@ G_DECLARE_FINAL_TYPE (DisplayStateTracker, display_state_tracker,
|
||||||
|
|
||||||
|
const char * monitor_get_connector (Monitor *monitor);
|
||||||
|
|
||||||
|
+const char * monitor_get_match_string (Monitor *monitor);
|
||||||
|
+
|
||||||
|
const char * monitor_get_display_name (Monitor *monitor);
|
||||||
|
|
||||||
|
GList * logical_monitor_get_monitors (LogicalMonitor *logical_monitor);
|
724
0006-implement-screencast-stream-restoration.patch
Normal file
724
0006-implement-screencast-stream-restoration.patch
Normal file
@ -0,0 +1,724 @@
|
|||||||
|
From af25561e0f4e5aa2c3460ce7448b0c580f28532a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Tue, 28 Sep 2021 21:04:28 -0300
|
||||||
|
Subject: [PATCH] Implement screencast stream restoration
|
||||||
|
|
||||||
|
Handle receiving 'restore_data' and 'persist_mode'.
|
||||||
|
|
||||||
|
For monitors, use the match string introduced by the previous
|
||||||
|
commit to identify individual monitors. For windows, do a strict
|
||||||
|
check on the app id, and a best-match approach to window titles.
|
||||||
|
Virtual monitors don't have any particular data attached to them,
|
||||||
|
so they are merely stored as "virtual" and restored.
|
||||||
|
---
|
||||||
|
src/screencast.c | 327 +++++++++++++++++++++++++++++++++++++++-
|
||||||
|
src/screencast.h | 7 +
|
||||||
|
src/screencastdialog.c | 14 +-
|
||||||
|
src/screencastdialog.h | 5 +-
|
||||||
|
src/screencastwidget.c | 23 +++
|
||||||
|
src/screencastwidget.h | 6 +
|
||||||
|
src/screencastwidget.ui | 8 +
|
||||||
|
src/utils.c | 77 ++++++++++
|
||||||
|
src/utils.h | 3 +
|
||||||
|
9 files changed, 456 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 2713d26..55a3e5c 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -33,8 +33,15 @@
|
||||||
|
#include "externalwindow.h"
|
||||||
|
#include "request.h"
|
||||||
|
#include "session.h"
|
||||||
|
+#include "shellintrospect.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
+#define RESTORE_FORMAT_VERSION 1
|
||||||
|
+#define RESTORE_VARIANT_TYPE "(xxa(uuv))"
|
||||||
|
+#define MONITOR_TYPE "s"
|
||||||
|
+#define WINDOW_TYPE "(ss)"
|
||||||
|
+#define VIRTUAL_TYPE "b"
|
||||||
|
+
|
||||||
|
typedef struct _ScreenCastDialogHandle ScreenCastDialogHandle;
|
||||||
|
|
||||||
|
typedef struct _ScreenCastSession
|
||||||
|
@@ -49,6 +56,13 @@ typedef struct _ScreenCastSession
|
||||||
|
|
||||||
|
ScreenCastSelection select;
|
||||||
|
|
||||||
|
+ ScreenCastPersistMode persist_mode;
|
||||||
|
+ GPtrArray *streams_to_restore;
|
||||||
|
+ struct {
|
||||||
|
+ GVariant *data;
|
||||||
|
+ int64_t creation_time;
|
||||||
|
+ } restored;
|
||||||
|
+
|
||||||
|
GDBusMethodInvocation *start_invocation;
|
||||||
|
ScreenCastDialogHandle *dialog_handle;
|
||||||
|
} ScreenCastSession;
|
||||||
|
@@ -99,6 +113,68 @@ screen_cast_dialog_handle_close (ScreenCastDialogHandle *dialog_handle)
|
||||||
|
screen_cast_dialog_handle_free (dialog_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static GVariant *
|
||||||
|
+serialize_streams_as_restore_data (ScreenCastSession *screen_cast_session,
|
||||||
|
+ GPtrArray *streams)
|
||||||
|
+{
|
||||||
|
+ GVariantBuilder restore_data_builder;
|
||||||
|
+ GVariantBuilder impl_builder;
|
||||||
|
+ int64_t creation_time;
|
||||||
|
+ int64_t last_used_time;
|
||||||
|
+ guint i;
|
||||||
|
+
|
||||||
|
+ if (!streams || streams->len == 0)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ last_used_time = g_get_real_time ();
|
||||||
|
+ if (screen_cast_session->restored.creation_time != -1)
|
||||||
|
+ creation_time = screen_cast_session->restored.creation_time;
|
||||||
|
+ else
|
||||||
|
+ creation_time = g_get_real_time ();
|
||||||
|
+
|
||||||
|
+ g_variant_builder_init (&impl_builder, G_VARIANT_TYPE (RESTORE_VARIANT_TYPE));
|
||||||
|
+ g_variant_builder_add (&impl_builder, "x", creation_time);
|
||||||
|
+ g_variant_builder_add (&impl_builder, "x", last_used_time);
|
||||||
|
+
|
||||||
|
+ g_variant_builder_open (&impl_builder, G_VARIANT_TYPE ("a(uuv)"));
|
||||||
|
+ for (i = 0; i < streams->len; i++)
|
||||||
|
+ {
|
||||||
|
+ ScreenCastStreamInfo *info = g_ptr_array_index (streams, i);
|
||||||
|
+ GVariant *stream_variant;
|
||||||
|
+ Monitor *monitor;
|
||||||
|
+ Window *window;
|
||||||
|
+
|
||||||
|
+ switch (info->type)
|
||||||
|
+ {
|
||||||
|
+ case SCREEN_CAST_SOURCE_TYPE_MONITOR:
|
||||||
|
+ monitor = info->data.monitor;
|
||||||
|
+ stream_variant = g_variant_new (MONITOR_TYPE,
|
||||||
|
+ monitor_get_match_string (monitor));
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case SCREEN_CAST_SOURCE_TYPE_WINDOW:
|
||||||
|
+ window = info->data.window;
|
||||||
|
+ stream_variant = g_variant_new (WINDOW_TYPE,
|
||||||
|
+ window_get_app_id (window),
|
||||||
|
+ window_get_title (window));
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ g_variant_builder_add (&impl_builder,
|
||||||
|
+ "(uuv)",
|
||||||
|
+ i,
|
||||||
|
+ info->type,
|
||||||
|
+ stream_variant);
|
||||||
|
+ }
|
||||||
|
+ g_variant_builder_close (&impl_builder);
|
||||||
|
+
|
||||||
|
+ g_variant_builder_init (&restore_data_builder, G_VARIANT_TYPE ("(suv)"));
|
||||||
|
+ g_variant_builder_add (&restore_data_builder, "s", "GNOME");
|
||||||
|
+ g_variant_builder_add (&restore_data_builder, "u", RESTORE_FORMAT_VERSION);
|
||||||
|
+ g_variant_builder_add (&restore_data_builder, "v", g_variant_builder_end (&impl_builder));
|
||||||
|
+ return g_variant_builder_end (&restore_data_builder);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
cancel_start_session (ScreenCastSession *screen_cast_session,
|
||||||
|
int response)
|
||||||
|
@@ -142,6 +218,22 @@ on_gnome_screen_cast_session_ready (GnomeScreenCastSession *gnome_screen_cast_se
|
||||||
|
"streams",
|
||||||
|
g_variant_builder_end (&streams_builder));
|
||||||
|
|
||||||
|
+ if (screen_cast_session->persist_mode != SCREEN_CAST_PERSIST_MODE_NONE)
|
||||||
|
+ {
|
||||||
|
+ g_autoptr(GPtrArray) streams = g_steal_pointer (&screen_cast_session->streams_to_restore);
|
||||||
|
+ GVariant *restore_data;
|
||||||
|
+
|
||||||
|
+ restore_data = serialize_streams_as_restore_data (screen_cast_session, streams);
|
||||||
|
+
|
||||||
|
+ if (restore_data)
|
||||||
|
+ {
|
||||||
|
+ g_variant_builder_add (&results_builder, "{sv}", "persist_mode",
|
||||||
|
+ g_variant_new_uint32 (screen_cast_session->persist_mode));
|
||||||
|
+ g_variant_builder_add (&results_builder, "{sv}", "restore_data",
|
||||||
|
+ g_variant_new_variant (restore_data));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
xdp_impl_screen_cast_complete_start (XDP_IMPL_SCREEN_CAST (impl),
|
||||||
|
screen_cast_session->start_invocation, 0,
|
||||||
|
g_variant_builder_end (&results_builder));
|
||||||
|
@@ -178,6 +270,9 @@ start_session (ScreenCastSession *screen_cast_session,
|
||||||
|
G_CALLBACK (on_gnome_screen_cast_session_closed),
|
||||||
|
screen_cast_session);
|
||||||
|
|
||||||
|
+ if (screen_cast_session->persist_mode != SCREEN_CAST_PERSIST_MODE_NONE)
|
||||||
|
+ screen_cast_session->streams_to_restore = g_ptr_array_ref (streams);
|
||||||
|
+
|
||||||
|
if (!gnome_screen_cast_session_record_selections (gnome_screen_cast_session,
|
||||||
|
streams,
|
||||||
|
&screen_cast_session->select,
|
||||||
|
@@ -193,6 +288,7 @@ start_session (ScreenCastSession *screen_cast_session,
|
||||||
|
static void
|
||||||
|
on_screen_cast_dialog_done_cb (GtkWidget *widget,
|
||||||
|
int dialog_response,
|
||||||
|
+ ScreenCastPersistMode persist_mode,
|
||||||
|
GPtrArray *streams,
|
||||||
|
ScreenCastDialogHandle *dialog_handle)
|
||||||
|
{
|
||||||
|
@@ -218,8 +314,12 @@ on_screen_cast_dialog_done_cb (GtkWidget *widget,
|
||||||
|
|
||||||
|
if (response == 0)
|
||||||
|
{
|
||||||
|
+ ScreenCastSession *screen_cast_session = dialog_handle->session;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
+ screen_cast_session->persist_mode = MIN (screen_cast_session->persist_mode,
|
||||||
|
+ persist_mode);
|
||||||
|
+
|
||||||
|
if (!start_session (dialog_handle->session, streams, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to start session: %s", error->message);
|
||||||
|
@@ -269,7 +369,8 @@ create_screen_cast_dialog (ScreenCastSession *session,
|
||||||
|
g_object_ref_sink (fake_parent);
|
||||||
|
|
||||||
|
dialog = GTK_WIDGET (screen_cast_dialog_new (request->app_id,
|
||||||
|
- &session->select));
|
||||||
|
+ &session->select,
|
||||||
|
+ session->persist_mode));
|
||||||
|
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent));
|
||||||
|
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||||
|
|
||||||
|
@@ -295,6 +396,161 @@ create_screen_cast_dialog (ScreenCastSession *session,
|
||||||
|
return dialog_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static Monitor *
|
||||||
|
+find_monitor_by_string (const char *monitor_string)
|
||||||
|
+{
|
||||||
|
+ DisplayStateTracker *display_state_tracker = display_state_tracker_get ();
|
||||||
|
+ GList *l;
|
||||||
|
+
|
||||||
|
+ for (l = display_state_tracker_get_logical_monitors (display_state_tracker);
|
||||||
|
+ l;
|
||||||
|
+ l = l->next)
|
||||||
|
+ {
|
||||||
|
+ LogicalMonitor *logical_monitor = l->data;
|
||||||
|
+ GList *monitors;
|
||||||
|
+
|
||||||
|
+ for (monitors = logical_monitor_get_monitors (logical_monitor);
|
||||||
|
+ monitors;
|
||||||
|
+ monitors = monitors->next)
|
||||||
|
+ {
|
||||||
|
+ Monitor *monitor = monitors->data;
|
||||||
|
+
|
||||||
|
+ if (g_strcmp0 (monitor_get_match_string (monitor), monitor_string) == 0)
|
||||||
|
+ return monitor;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static Window *
|
||||||
|
+find_best_window_by_app_id_and_title (const char *app_id,
|
||||||
|
+ const char *title)
|
||||||
|
+{
|
||||||
|
+ ShellIntrospect *shell_introspect = shell_introspect_get ();
|
||||||
|
+ Window *best_match;
|
||||||
|
+ glong best_match_distance;
|
||||||
|
+ GList *l;
|
||||||
|
+
|
||||||
|
+ best_match = NULL;
|
||||||
|
+ best_match_distance = G_MAXLONG;
|
||||||
|
+
|
||||||
|
+ for (l = shell_introspect_get_windows (shell_introspect); l; l = l->next)
|
||||||
|
+ {
|
||||||
|
+ Window *window = l->data;
|
||||||
|
+ glong distance;
|
||||||
|
+
|
||||||
|
+ if (g_strcmp0 (window_get_app_id (window), app_id) != 0)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ distance = str_distance (window_get_title (window), title);
|
||||||
|
+
|
||||||
|
+ if (distance == 0)
|
||||||
|
+ return window;
|
||||||
|
+
|
||||||
|
+ if (distance < best_match_distance)
|
||||||
|
+ {
|
||||||
|
+ best_match = window;
|
||||||
|
+ best_match_distance = distance;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return best_match;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static gboolean
|
||||||
|
+restore_stream_from_data (ScreenCastSession *screen_cast_session)
|
||||||
|
+
|
||||||
|
+{
|
||||||
|
+ ScreenCastStreamInfo *info;
|
||||||
|
+ g_autoptr(GVariantIter) array_iter = NULL;
|
||||||
|
+ g_autoptr(GPtrArray) streams = NULL;
|
||||||
|
+ g_autoptr(GError) error = NULL;
|
||||||
|
+ ScreenCastSourceType source_type;
|
||||||
|
+ GVariant *data;
|
||||||
|
+ uint32_t id;
|
||||||
|
+ int64_t creation_time;
|
||||||
|
+ int64_t last_used_time;
|
||||||
|
+
|
||||||
|
+ if (!screen_cast_session->restored.data)
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ streams = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
+
|
||||||
|
+ g_variant_get (screen_cast_session->restored.data,
|
||||||
|
+ RESTORE_VARIANT_TYPE,
|
||||||
|
+ &creation_time,
|
||||||
|
+ &last_used_time,
|
||||||
|
+ &array_iter);
|
||||||
|
+
|
||||||
|
+ while (g_variant_iter_next (array_iter, "(uuv)", &id, &source_type, &data))
|
||||||
|
+ {
|
||||||
|
+ switch (source_type)
|
||||||
|
+ {
|
||||||
|
+ case SCREEN_CAST_SOURCE_TYPE_MONITOR:
|
||||||
|
+ {
|
||||||
|
+ if (!(screen_cast_session->select.source_types & SCREEN_CAST_SOURCE_TYPE_MONITOR) ||
|
||||||
|
+ !g_variant_check_format_string (data, MONITOR_TYPE, FALSE))
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ const char *match_string = g_variant_get_string (data, NULL);
|
||||||
|
+ Monitor *monitor = find_monitor_by_string (match_string);
|
||||||
|
+
|
||||||
|
+ if (!monitor)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
+ info->type = SCREEN_CAST_SOURCE_TYPE_MONITOR;
|
||||||
|
+ info->data.monitor = monitor;
|
||||||
|
+ g_ptr_array_add (streams, info);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case SCREEN_CAST_SOURCE_TYPE_WINDOW:
|
||||||
|
+ {
|
||||||
|
+ if (!(screen_cast_session->select.source_types & SCREEN_CAST_SOURCE_TYPE_WINDOW) ||
|
||||||
|
+ !g_variant_check_format_string (data, WINDOW_TYPE, FALSE))
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ const char *app_id = NULL;
|
||||||
|
+ const char *title = NULL;
|
||||||
|
+ Window *window;
|
||||||
|
+
|
||||||
|
+ g_variant_get (data, "(&s&s)", &app_id, &title);
|
||||||
|
+
|
||||||
|
+ window = find_best_window_by_app_id_and_title (app_id, title);
|
||||||
|
+
|
||||||
|
+ if (!window)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
+ info->type = SCREEN_CAST_SOURCE_TYPE_WINDOW;
|
||||||
|
+ info->data.window = window;
|
||||||
|
+ g_ptr_array_add (streams, info);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ screen_cast_session->restored.creation_time = creation_time;
|
||||||
|
+
|
||||||
|
+ start_session (screen_cast_session, streams, &error);
|
||||||
|
+
|
||||||
|
+ if (error)
|
||||||
|
+ {
|
||||||
|
+ g_warning ("Error restoring stream from session: %s", error->message);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return TRUE;
|
||||||
|
+
|
||||||
|
+fail:
|
||||||
|
+ return FALSE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gboolean
|
||||||
|
handle_start (XdpImplScreenCast *object,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
@@ -307,7 +563,6 @@ handle_start (XdpImplScreenCast *object,
|
||||||
|
const char *sender;
|
||||||
|
g_autoptr(Request) request = NULL;
|
||||||
|
ScreenCastSession *screen_cast_session;
|
||||||
|
- ScreenCastDialogHandle *dialog_handle;
|
||||||
|
GVariantBuilder results_builder;
|
||||||
|
|
||||||
|
sender = g_dbus_method_invocation_get_sender (invocation);
|
||||||
|
@@ -329,14 +584,19 @@ handle_start (XdpImplScreenCast *object,
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
- dialog_handle = create_screen_cast_dialog (screen_cast_session,
|
||||||
|
- invocation,
|
||||||
|
- request,
|
||||||
|
- arg_parent_window);
|
||||||
|
+ screen_cast_session->start_invocation = invocation;
|
||||||
|
|
||||||
|
+ if (!restore_stream_from_data (screen_cast_session))
|
||||||
|
+ {
|
||||||
|
+ ScreenCastDialogHandle *dialog_handle;
|
||||||
|
|
||||||
|
- screen_cast_session->start_invocation = invocation;
|
||||||
|
- screen_cast_session->dialog_handle = dialog_handle;
|
||||||
|
+ dialog_handle = create_screen_cast_dialog (screen_cast_session,
|
||||||
|
+ invocation,
|
||||||
|
+ request,
|
||||||
|
+ arg_parent_window);
|
||||||
|
+
|
||||||
|
+ screen_cast_session->dialog_handle = dialog_handle;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
@@ -356,6 +616,9 @@ handle_select_sources (XdpImplScreenCast *object,
|
||||||
|
const char *arg_app_id,
|
||||||
|
GVariant *arg_options)
|
||||||
|
{
|
||||||
|
+ g_autofree gchar *provider = NULL;
|
||||||
|
+ g_autoptr(GVariant) restore_data = NULL;
|
||||||
|
+ ScreenCastSession *screen_cast_session;
|
||||||
|
Session *session;
|
||||||
|
int response;
|
||||||
|
uint32_t types;
|
||||||
|
@@ -364,6 +627,7 @@ handle_select_sources (XdpImplScreenCast *object,
|
||||||
|
ScreenCastSelection select;
|
||||||
|
GVariantBuilder results_builder;
|
||||||
|
GVariant *results;
|
||||||
|
+ uint32_t version;
|
||||||
|
|
||||||
|
session = lookup_session (arg_session_handle);
|
||||||
|
if (!session)
|
||||||
|
@@ -427,6 +691,21 @@ handle_select_sources (XdpImplScreenCast *object,
|
||||||
|
response = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ screen_cast_session = (ScreenCastSession *)session;
|
||||||
|
+ g_variant_lookup (arg_options, "persist_mode", "u", &screen_cast_session->persist_mode);
|
||||||
|
+
|
||||||
|
+ if (g_variant_lookup (arg_options, "restore_data", "(suv)", &provider, &version, &restore_data))
|
||||||
|
+ {
|
||||||
|
+ if (!g_variant_check_format_string (restore_data, "(suv)", FALSE))
|
||||||
|
+ {
|
||||||
|
+ g_warning ("Cannot parse restore data, ignoring");
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (g_strcmp0 (provider, "GNOME") == 0 && version == RESTORE_FORMAT_VERSION)
|
||||||
|
+ screen_cast_session->restored.data = g_variant_ref (restore_data);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
out:
|
||||||
|
g_variant_builder_init (&results_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
results = g_variant_builder_end (&results_builder);
|
||||||
|
@@ -567,6 +846,8 @@ screen_cast_session_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
ScreenCastSession *screen_cast_session = (ScreenCastSession *)object;
|
||||||
|
|
||||||
|
+ g_clear_pointer (&screen_cast_session->streams_to_restore, g_ptr_array_unref);
|
||||||
|
+ g_clear_pointer (&screen_cast_session->restored.data, g_variant_unref);
|
||||||
|
g_clear_object (&screen_cast_session->gnome_screen_cast_session);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (screen_cast_session_parent_class)->finalize (object);
|
||||||
|
@@ -575,6 +856,8 @@ screen_cast_session_finalize (GObject *object)
|
||||||
|
static void
|
||||||
|
screen_cast_session_init (ScreenCastSession *screen_cast_session)
|
||||||
|
{
|
||||||
|
+ screen_cast_session->persist_mode = SCREEN_CAST_PERSIST_MODE_NONE;
|
||||||
|
+ screen_cast_session->restored.creation_time = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -594,6 +877,14 @@ gboolean
|
||||||
|
screen_cast_init (GDBusConnection *connection,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
+ /*
|
||||||
|
+ * Ensure ShellIntrospect and DisplayStateTracker are initialized before
|
||||||
|
+ * any screencast session is created to avoid race conditions when restoring
|
||||||
|
+ * previous streams.
|
||||||
|
+ */
|
||||||
|
+ display_state_tracker_get ();
|
||||||
|
+ shell_introspect_get ();
|
||||||
|
+
|
||||||
|
impl_connection = connection;
|
||||||
|
gnome_screen_cast = gnome_screen_cast_new (connection);
|
||||||
|
|
||||||
|
diff --git a/src/screencast.h b/src/screencast.h
|
||||||
|
index a9be16b..d78066e 100644
|
||||||
|
--- a/src/screencast.h
|
||||||
|
+++ b/src/screencast.h
|
||||||
|
@@ -38,6 +38,13 @@ typedef enum _ScreenCastCursorMode
|
||||||
|
SCREEN_CAST_CURSOR_MODE_METADATA = 4,
|
||||||
|
} ScreenCastCursorMode;
|
||||||
|
|
||||||
|
+typedef enum _ScreenCastPersistMode
|
||||||
|
+{
|
||||||
|
+ SCREEN_CAST_PERSIST_MODE_NONE = 0,
|
||||||
|
+ SCREEN_CAST_PERSIST_MODE_TRANSIENT = 1,
|
||||||
|
+ SCREEN_CAST_PERSIST_MODE_PERSISTENT = 2,
|
||||||
|
+} ScreenCastPersistMode;
|
||||||
|
+
|
||||||
|
typedef struct _ScreenCastSelection
|
||||||
|
{
|
||||||
|
gboolean multiple;
|
||||||
|
diff --git a/src/screencastdialog.c b/src/screencastdialog.c
|
||||||
|
index 3e3b064..d80329e 100644
|
||||||
|
--- a/src/screencastdialog.c
|
||||||
|
+++ b/src/screencastdialog.c
|
||||||
|
@@ -59,6 +59,7 @@ static void
|
||||||
|
button_clicked (GtkWidget *button,
|
||||||
|
ScreenCastDialog *dialog)
|
||||||
|
{
|
||||||
|
+ ScreenCastPersistMode persist_mode;
|
||||||
|
g_autoptr(GPtrArray) streams = NULL;
|
||||||
|
int response;
|
||||||
|
|
||||||
|
@@ -71,14 +72,16 @@ button_clicked (GtkWidget *button,
|
||||||
|
|
||||||
|
response = GTK_RESPONSE_OK;
|
||||||
|
streams = screen_cast_widget_get_selected_streams (screen_cast_widget);
|
||||||
|
+ persist_mode = screen_cast_widget_get_persist_mode (screen_cast_widget);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response = GTK_RESPONSE_CANCEL;
|
||||||
|
+ persist_mode = SCREEN_CAST_PERSIST_MODE_NONE;
|
||||||
|
streams = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- g_signal_emit (dialog, signals[DONE], 0, response, streams);
|
||||||
|
+ g_signal_emit (dialog, signals[DONE], 0, response, persist_mode, streams);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -120,7 +123,8 @@ screen_cast_dialog_class_init (ScreenCastDialogClass *klass)
|
||||||
|
0,
|
||||||
|
NULL, NULL,
|
||||||
|
NULL,
|
||||||
|
- G_TYPE_NONE, 2,
|
||||||
|
+ G_TYPE_NONE, 3,
|
||||||
|
+ G_TYPE_INT,
|
||||||
|
G_TYPE_INT,
|
||||||
|
G_TYPE_PTR_ARRAY);
|
||||||
|
|
||||||
|
@@ -143,8 +147,9 @@ screen_cast_dialog_init (ScreenCastDialog *dialog)
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenCastDialog *
|
||||||
|
-screen_cast_dialog_new (const char *app_id,
|
||||||
|
- ScreenCastSelection *select)
|
||||||
|
+screen_cast_dialog_new (const char *app_id,
|
||||||
|
+ ScreenCastSelection *select,
|
||||||
|
+ ScreenCastPersistMode persist_mode)
|
||||||
|
{
|
||||||
|
ScreenCastDialog *dialog;
|
||||||
|
ScreenCastWidget *screen_cast_widget;
|
||||||
|
@@ -155,6 +160,7 @@ screen_cast_dialog_new (const char *app_id,
|
||||||
|
screen_cast_widget_set_allow_multiple (screen_cast_widget, select->multiple);
|
||||||
|
screen_cast_widget_set_source_types (screen_cast_widget,
|
||||||
|
select->source_types);
|
||||||
|
+ screen_cast_widget_set_persist_mode (screen_cast_widget, persist_mode);
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
diff --git a/src/screencastdialog.h b/src/screencastdialog.h
|
||||||
|
index 1fca470..c132ecf 100644
|
||||||
|
--- a/src/screencastdialog.h
|
||||||
|
+++ b/src/screencastdialog.h
|
||||||
|
@@ -26,5 +26,6 @@
|
||||||
|
G_DECLARE_FINAL_TYPE (ScreenCastDialog, screen_cast_dialog,
|
||||||
|
SCREEN_CAST, DIALOG, GtkWindow)
|
||||||
|
|
||||||
|
-ScreenCastDialog * screen_cast_dialog_new (const char *app_id,
|
||||||
|
- ScreenCastSelection *select);
|
||||||
|
+ScreenCastDialog * screen_cast_dialog_new (const char *app_id,
|
||||||
|
+ ScreenCastSelection *select,
|
||||||
|
+ ScreenCastPersistMode persist_mode);
|
||||||
|
diff --git a/src/screencastwidget.c b/src/screencastwidget.c
|
||||||
|
index 3119245..c100ad9 100644
|
||||||
|
--- a/src/screencastwidget.c
|
||||||
|
+++ b/src/screencastwidget.c
|
||||||
|
@@ -51,6 +51,9 @@ struct _ScreenCastWidget
|
||||||
|
GtkWidget *window_list;
|
||||||
|
GtkWidget *window_list_scrolled;
|
||||||
|
|
||||||
|
+ GtkCheckButton *persist_check;
|
||||||
|
+ ScreenCastPersistMode persist_mode;
|
||||||
|
+
|
||||||
|
DisplayStateTracker *display_state_tracker;
|
||||||
|
gulong monitors_changed_handler_id;
|
||||||
|
|
||||||
|
@@ -454,6 +457,7 @@ screen_cast_widget_class_init (ScreenCastWidgetClass *klass)
|
||||||
|
G_TYPE_BOOLEAN);
|
||||||
|
|
||||||
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/freedesktop/portal/desktop/gnome/screencastwidget.ui");
|
||||||
|
+ gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, persist_check);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, source_type_switcher);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, source_type);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ScreenCastWidget, monitor_selection);
|
||||||
|
@@ -635,3 +639,22 @@ screen_cast_widget_get_selected_streams (ScreenCastWidget *self)
|
||||||
|
|
||||||
|
return g_steal_pointer (&streams);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+screen_cast_widget_set_persist_mode (ScreenCastWidget *screen_cast_widget,
|
||||||
|
+ ScreenCastPersistMode persist_mode)
|
||||||
|
+{
|
||||||
|
+ screen_cast_widget->persist_mode = persist_mode;
|
||||||
|
+
|
||||||
|
+ gtk_widget_set_visible (GTK_WIDGET (screen_cast_widget->persist_check),
|
||||||
|
+ persist_mode != SCREEN_CAST_PERSIST_MODE_NONE);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+ScreenCastPersistMode
|
||||||
|
+screen_cast_widget_get_persist_mode (ScreenCastWidget *screen_cast_widget)
|
||||||
|
+{
|
||||||
|
+ if (!gtk_check_button_get_active (screen_cast_widget->persist_check))
|
||||||
|
+ return SCREEN_CAST_PERSIST_MODE_NONE;
|
||||||
|
+
|
||||||
|
+ return screen_cast_widget->persist_mode;
|
||||||
|
+}
|
||||||
|
diff --git a/src/screencastwidget.h b/src/screencastwidget.h
|
||||||
|
index ad95903..a963f99 100644
|
||||||
|
--- a/src/screencastwidget.h
|
||||||
|
+++ b/src/screencastwidget.h
|
||||||
|
@@ -40,3 +40,9 @@ void screen_cast_widget_set_source_types (ScreenCastWidget *screen_cast_widg
|
||||||
|
ScreenCastSourceType source_types);
|
||||||
|
|
||||||
|
GPtrArray *screen_cast_widget_get_selected_streams (ScreenCastWidget *self);
|
||||||
|
+
|
||||||
|
+void screen_cast_widget_set_persist_mode (ScreenCastWidget *screen_cast_widget,
|
||||||
|
+ ScreenCastPersistMode persist_mode);
|
||||||
|
+
|
||||||
|
+ScreenCastPersistMode
|
||||||
|
+screen_cast_widget_get_persist_mode (ScreenCastWidget *screen_cast_widget);
|
||||||
|
diff --git a/src/screencastwidget.ui b/src/screencastwidget.ui
|
||||||
|
index fb83b94..0a9028e 100644
|
||||||
|
--- a/src/screencastwidget.ui
|
||||||
|
+++ b/src/screencastwidget.ui
|
||||||
|
@@ -152,5 +152,13 @@
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
+
|
||||||
|
+ <!-- Persist permission -->
|
||||||
|
+ <child>
|
||||||
|
+ <object class="GtkCheckButton" id="persist_check">
|
||||||
|
+ <property name="active">True</property>
|
||||||
|
+ <property name="label" translatable="yes">Remember this selection</property>
|
||||||
|
+ </object>
|
||||||
|
+ </child>
|
||||||
|
</template>
|
||||||
|
</interface>
|
||||||
|
diff --git a/src/utils.c b/src/utils.c
|
||||||
|
index b7dd472..5e0485c 100644
|
||||||
|
--- a/src/utils.c
|
||||||
|
+++ b/src/utils.c
|
||||||
|
@@ -45,3 +45,80 @@ xdg_desktop_portal_error_quark (void)
|
||||||
|
G_N_ELEMENTS (xdg_desktop_portal_error_entries));
|
||||||
|
return (GQuark) quark_volatile;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+glong
|
||||||
|
+str_distance (const char *a,
|
||||||
|
+ const char *b)
|
||||||
|
+{
|
||||||
|
+ g_autofree gint *v0 = NULL;
|
||||||
|
+ g_autofree gint *v1 = NULL;
|
||||||
|
+ const gchar *s;
|
||||||
|
+ const gchar *t;
|
||||||
|
+ gunichar sc;
|
||||||
|
+ gunichar tc;
|
||||||
|
+ glong b_char_len;
|
||||||
|
+ glong cost;
|
||||||
|
+ glong i;
|
||||||
|
+ glong j;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Handle degenerate cases.
|
||||||
|
+ */
|
||||||
|
+ if (g_strcmp0 (a, b) == 0)
|
||||||
|
+ return 0;
|
||||||
|
+ else if (!*a)
|
||||||
|
+ return g_utf8_strlen (a, -1);
|
||||||
|
+ else if (!*b)
|
||||||
|
+ return g_utf8_strlen (a, -1);
|
||||||
|
+
|
||||||
|
+ b_char_len = g_utf8_strlen (b, -1);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Create two vectors to hold our states.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ v0 = g_new0 (gint, b_char_len + 1);
|
||||||
|
+ v1 = g_new0 (gint, b_char_len + 1);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * initialize v0 (the previous row of distances).
|
||||||
|
+ * this row is A[0][i]: edit distance for an empty a.
|
||||||
|
+ * the distance is just the number of characters to delete from b.
|
||||||
|
+ */
|
||||||
|
+ for (i = 0; i < b_char_len + 1; i++)
|
||||||
|
+ v0[i] = i;
|
||||||
|
+
|
||||||
|
+ for (i = 0, s = a; s && *s; i++, s = g_utf8_next_char(s))
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Calculate v1 (current row distances) from the previous row v0.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ sc = g_utf8_get_char(s);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * first element of v1 is A[i+1][0]
|
||||||
|
+ *
|
||||||
|
+ * edit distance is delete (i+1) chars from a to match empty
|
||||||
|
+ * b.
|
||||||
|
+ */
|
||||||
|
+ v1[0] = i + 1;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * use formula to fill in the rest of the row.
|
||||||
|
+ */
|
||||||
|
+ for (j = 0, t = b; t && *t; j++, t = g_utf8_next_char(t))
|
||||||
|
+ {
|
||||||
|
+ tc = g_utf8_get_char(t);
|
||||||
|
+ cost = (sc == tc) ? 0 : 1;
|
||||||
|
+ v1[j+1] = MIN (v1[j] + 1, MIN (v0[j+1] + 1, v0[j] + cost));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * copy v1 (current row) to v0 (previous row) for next iteration.
|
||||||
|
+ */
|
||||||
|
+ memcpy (v0, v1, sizeof(gint) * b_char_len);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return v1[b_char_len];
|
||||||
|
+}
|
||||||
|
diff --git a/src/utils.h b/src/utils.h
|
||||||
|
index 5fdfda9..fa3f1b0 100644
|
||||||
|
--- a/src/utils.h
|
||||||
|
+++ b/src/utils.h
|
||||||
|
@@ -37,3 +37,6 @@ typedef enum {
|
||||||
|
#define XDG_DESKTOP_PORTAL_ERROR xdg_desktop_portal_error_quark ()
|
||||||
|
|
||||||
|
GQuark xdg_desktop_portal_error_quark (void);
|
||||||
|
+
|
||||||
|
+glong str_distance (const char *a,
|
||||||
|
+ const char *b);
|
166
0007-screencast-pass-stream-ids.patch
Normal file
166
0007-screencast-pass-stream-ids.patch
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
From c865ffdb24d1a945f36a1bf873fe0900cbbade14 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Thu, 11 Nov 2021 00:05:27 -0300
|
||||||
|
Subject: [PATCH] screencast: Pass stream ids
|
||||||
|
|
||||||
|
The stream id is any string that can uniquely
|
||||||
|
identify a stream within a screencast session.
|
||||||
|
Add that to the list of stream properties.
|
||||||
|
|
||||||
|
For now, only use a simple positional integer
|
||||||
|
as id.
|
||||||
|
---
|
||||||
|
src/gnomescreencast.c | 21 ++++++++++++++++++---
|
||||||
|
src/screencast.c | 5 ++++-
|
||||||
|
src/screencast.h | 1 +
|
||||||
|
src/screencastwidget.c | 4 ++++
|
||||||
|
4 files changed, 27 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/gnomescreencast.c b/src/gnomescreencast.c
|
||||||
|
index 3f8539c..482fcd0 100644
|
||||||
|
--- a/src/gnomescreencast.c
|
||||||
|
+++ b/src/gnomescreencast.c
|
||||||
|
@@ -59,6 +59,7 @@ typedef struct _GnomeScreenCastStream
|
||||||
|
|
||||||
|
ScreenCastSourceType source_type;
|
||||||
|
|
||||||
|
+ uint32_t id;
|
||||||
|
char *path;
|
||||||
|
OrgGnomeMutterScreenCastStream *proxy;
|
||||||
|
|
||||||
|
@@ -219,6 +220,7 @@ void
|
||||||
|
gnome_screen_cast_session_add_stream_properties (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
GVariantBuilder *streams_builder)
|
||||||
|
{
|
||||||
|
+ char id[64] = { 0, };
|
||||||
|
GList *streams;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
@@ -234,6 +236,10 @@ gnome_screen_cast_session_add_stream_properties (GnomeScreenCastSession *gnome_s
|
||||||
|
|
||||||
|
g_variant_builder_init (&stream_properties_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
|
||||||
|
+ g_snprintf (id, G_N_ELEMENTS (id), "%u", stream->id);
|
||||||
|
+ g_variant_builder_add (&stream_properties_builder, "{sv}",
|
||||||
|
+ "id",
|
||||||
|
+ g_variant_new ("s", id));
|
||||||
|
g_variant_builder_add (&stream_properties_builder, "{sv}",
|
||||||
|
"source_type",
|
||||||
|
g_variant_new ("u", stream->source_type));
|
||||||
|
@@ -275,6 +281,7 @@ cursor_mode_to_gnome_cursor_mode (ScreenCastCursorMode cursor_mode)
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gnome_screen_cast_session_record_window (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
+ uint32_t id,
|
||||||
|
Window *window,
|
||||||
|
ScreenCastSelection *select,
|
||||||
|
GError **error)
|
||||||
|
@@ -327,6 +334,7 @@ gnome_screen_cast_session_record_window (GnomeScreenCastSession *gnome_screen_c
|
||||||
|
stream->session = gnome_screen_cast_session;
|
||||||
|
stream->path = g_strdup (stream_path);
|
||||||
|
stream->proxy = stream_proxy;
|
||||||
|
+ stream->id = id;
|
||||||
|
|
||||||
|
parameters = org_gnome_mutter_screen_cast_stream_get_parameters (stream->proxy);
|
||||||
|
if (parameters)
|
||||||
|
@@ -357,6 +365,7 @@ gnome_screen_cast_session_record_window (GnomeScreenCastSession *gnome_screen_c
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
+ uint32_t id,
|
||||||
|
Monitor *monitor,
|
||||||
|
ScreenCastSelection *select,
|
||||||
|
GError **error)
|
||||||
|
@@ -409,6 +418,7 @@ gnome_screen_cast_session_record_monitor (GnomeScreenCastSession *gnome_screen_
|
||||||
|
stream->session = gnome_screen_cast_session;
|
||||||
|
stream->path = g_strdup (stream_path);
|
||||||
|
stream->proxy = stream_proxy;
|
||||||
|
+ stream->id = id;
|
||||||
|
|
||||||
|
parameters = org_gnome_mutter_screen_cast_stream_get_parameters (stream->proxy);
|
||||||
|
if (parameters)
|
||||||
|
@@ -453,6 +463,7 @@ gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_scre
|
||||||
|
{
|
||||||
|
case SCREEN_CAST_SOURCE_TYPE_MONITOR:
|
||||||
|
if (!gnome_screen_cast_session_record_monitor (gnome_screen_cast_session,
|
||||||
|
+ info->id,
|
||||||
|
info->data.monitor,
|
||||||
|
select,
|
||||||
|
error))
|
||||||
|
@@ -460,6 +471,7 @@ gnome_screen_cast_session_record_selections (GnomeScreenCastSession *gnome_scre
|
||||||
|
break;
|
||||||
|
case SCREEN_CAST_SOURCE_TYPE_WINDOW:
|
||||||
|
if (!gnome_screen_cast_session_record_window (gnome_screen_cast_session,
|
||||||
|
+ info->id,
|
||||||
|
info->data.window,
|
||||||
|
select,
|
||||||
|
error))
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 55a3e5c..3be8337 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -162,7 +162,7 @@ serialize_streams_as_restore_data (ScreenCastSession *screen_cast_session,
|
||||||
|
|
||||||
|
g_variant_builder_add (&impl_builder,
|
||||||
|
"(uuv)",
|
||||||
|
- i,
|
||||||
|
+ info->id,
|
||||||
|
info->type,
|
||||||
|
stream_variant);
|
||||||
|
}
|
||||||
|
@@ -502,6 +502,7 @@ restore_stream_from_data (ScreenCastSession *screen_cast_session)
|
||||||
|
info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
info->type = SCREEN_CAST_SOURCE_TYPE_MONITOR;
|
||||||
|
info->data.monitor = monitor;
|
||||||
|
+ info->id = id;
|
||||||
|
g_ptr_array_add (streams, info);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
@@ -526,6 +527,7 @@ restore_stream_from_data (ScreenCastSession *screen_cast_session)
|
||||||
|
info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
info->type = SCREEN_CAST_SOURCE_TYPE_WINDOW;
|
||||||
|
info->data.window = window;
|
||||||
|
+ info->id = id;
|
||||||
|
g_ptr_array_add (streams, info);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
diff --git a/src/screencast.h b/src/screencast.h
|
||||||
|
index d78066e..3d64b4a 100644
|
||||||
|
--- a/src/screencast.h
|
||||||
|
+++ b/src/screencast.h
|
||||||
|
@@ -55,6 +55,7 @@ typedef struct _ScreenCastSelection
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ScreenCastSourceType type;
|
||||||
|
+ uint32_t id;
|
||||||
|
union {
|
||||||
|
Monitor *monitor;
|
||||||
|
Window *window;
|
||||||
|
diff --git a/src/screencastwidget.c b/src/screencastwidget.c
|
||||||
|
index c100ad9..20df194 100644
|
||||||
|
--- a/src/screencastwidget.c
|
||||||
|
+++ b/src/screencastwidget.c
|
||||||
|
@@ -597,6 +597,7 @@ screen_cast_widget_get_selected_streams (ScreenCastWidget *self)
|
||||||
|
g_autoptr(GPtrArray) streams = NULL;
|
||||||
|
g_autoptr(GList) selected_monitor_rows = NULL;
|
||||||
|
g_autoptr(GList) selected_window_rows = NULL;
|
||||||
|
+ uint32_t id = 0;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
streams = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
@@ -620,6 +621,7 @@ screen_cast_widget_get_selected_streams (ScreenCastWidget *self)
|
||||||
|
info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
info->type = SCREEN_CAST_SOURCE_TYPE_MONITOR;
|
||||||
|
info->data.monitor = monitor;
|
||||||
|
+ info->id = id++;
|
||||||
|
g_ptr_array_add (streams, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -634,6 +636,7 @@ screen_cast_widget_get_selected_streams (ScreenCastWidget *self)
|
||||||
|
info = g_new0 (ScreenCastStreamInfo, 1);
|
||||||
|
info->type = SCREEN_CAST_SOURCE_TYPE_WINDOW;
|
||||||
|
info->data.window = window;
|
||||||
|
+ info->id = id++;
|
||||||
|
g_ptr_array_add (streams, info);
|
||||||
|
}
|
||||||
|
|
24
0008-screencast-fix-variant-type-check.patch
Normal file
24
0008-screencast-fix-variant-type-check.patch
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
From df8ddc91a6ab1254b22de8f092f07ce9aca4ea3c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Thu, 25 Nov 2021 10:27:07 -0300
|
||||||
|
Subject: [PATCH] screencast: Fix variant type check
|
||||||
|
|
||||||
|
The restore data type is not the (suv) variant, but rather the
|
||||||
|
GNOME-specific variant format.
|
||||||
|
---
|
||||||
|
src/screencast.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 3be8337..c46a4a8 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -698,7 +698,7 @@ handle_select_sources (XdpImplScreenCast *object,
|
||||||
|
|
||||||
|
if (g_variant_lookup (arg_options, "restore_data", "(suv)", &provider, &version, &restore_data))
|
||||||
|
{
|
||||||
|
- if (!g_variant_check_format_string (restore_data, "(suv)", FALSE))
|
||||||
|
+ if (!g_variant_check_format_string (restore_data, RESTORE_VARIANT_TYPE, FALSE))
|
||||||
|
{
|
||||||
|
g_warning ("Cannot parse restore data, ignoring");
|
||||||
|
goto out;
|
@ -0,0 +1,30 @@
|
|||||||
|
From 4251d584b010c130f278ba22869d4c9a9d19ebdb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Fri, 18 Mar 2022 13:32:11 -0300
|
||||||
|
Subject: [PATCH] screencast: Don't restore windows with too different titles
|
||||||
|
|
||||||
|
If the title is too different, don't restore it. The "too
|
||||||
|
different" part is arbitrarily chosen to be half of the
|
||||||
|
title's length. If this is too strict, we can review it
|
||||||
|
later.
|
||||||
|
---
|
||||||
|
src/screencast.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index c46a4a8..5f9a738 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -455,6 +455,12 @@ find_best_window_by_app_id_and_title (const char *app_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* If even the best match's window title is too different, don't
|
||||||
|
+ * restore it.
|
||||||
|
+ */
|
||||||
|
+ if (best_match_distance > strlen (title) / 2)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
return best_match;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From 6d293e77e4470d0e5df57c29eeb6e1ed5cb619e8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
Date: Fri, 18 Mar 2022 13:36:37 -0300
|
||||||
|
Subject: [PATCH] screencast: Don't wrap restore data in another variant
|
||||||
|
|
||||||
|
We were sending a variant with the wrong type. This was a
|
||||||
|
fallout from the evolution of the xdg-desktop-portal work,
|
||||||
|
which originally started as a 'v' variant, but then changed
|
||||||
|
to '(suv)', and we didn't adapt properly
|
||||||
|
|
||||||
|
See https://github.com/flatpak/xdg-desktop-portal/pull/730
|
||||||
|
---
|
||||||
|
src/screencast.c | 3 +--
|
||||||
|
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 5f9a738..6b0014a 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -229,8 +229,7 @@ on_gnome_screen_cast_session_ready (GnomeScreenCastSession *gnome_screen_cast_se
|
||||||
|
{
|
||||||
|
g_variant_builder_add (&results_builder, "{sv}", "persist_mode",
|
||||||
|
g_variant_new_uint32 (screen_cast_session->persist_mode));
|
||||||
|
- g_variant_builder_add (&results_builder, "{sv}", "restore_data",
|
||||||
|
- g_variant_new_variant (restore_data));
|
||||||
|
+ g_variant_builder_add (&results_builder, "{sv}", "restore_data", restore_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
390
0011-fix-window-screencast-stream-restore.patch
Normal file
390
0011-fix-window-screencast-stream-restore.patch
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 6b0014a..15f6a80 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -427,16 +427,20 @@ find_best_window_by_app_id_and_title (const char *app_id,
|
||||||
|
const char *title)
|
||||||
|
{
|
||||||
|
ShellIntrospect *shell_introspect = shell_introspect_get ();
|
||||||
|
+ GPtrArray *windows;
|
||||||
|
Window *best_match;
|
||||||
|
glong best_match_distance;
|
||||||
|
- GList *l;
|
||||||
|
|
||||||
|
best_match = NULL;
|
||||||
|
best_match_distance = G_MAXLONG;
|
||||||
|
|
||||||
|
- for (l = shell_introspect_get_windows (shell_introspect); l; l = l->next)
|
||||||
|
+ shell_introspect_ref_listeners (shell_introspect);
|
||||||
|
+ shell_introspect_wait_for_windows (shell_introspect);
|
||||||
|
+
|
||||||
|
+ windows = shell_introspect_get_windows (shell_introspect);
|
||||||
|
+ for (size_t i = 0; windows && i < windows->len; i++)
|
||||||
|
{
|
||||||
|
- Window *window = l->data;
|
||||||
|
+ Window *window = g_ptr_array_index (windows, i);
|
||||||
|
glong distance;
|
||||||
|
|
||||||
|
if (g_strcmp0 (window_get_app_id (window), app_id) != 0)
|
||||||
|
@@ -454,6 +458,8 @@ find_best_window_by_app_id_and_title (const char *app_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ shell_introspect_unref_listeners (shell_introspect);
|
||||||
|
+
|
||||||
|
/* If even the best match's window title is too different, don't
|
||||||
|
* restore it.
|
||||||
|
*/
|
||||||
|
diff --git a/src/screencastwidget.c b/src/screencastwidget.c
|
||||||
|
index 9b30f2d..e95fee2 100644
|
||||||
|
--- a/src/screencastwidget.c
|
||||||
|
+++ b/src/screencastwidget.c
|
||||||
|
@@ -164,8 +164,7 @@ update_windows_list (ScreenCastWidget *widget)
|
||||||
|
GtkListBox *window_list = GTK_LIST_BOX (widget->window_list);
|
||||||
|
GtkWidget *toplevel;
|
||||||
|
GtkWidget *child;
|
||||||
|
- GList *windows;
|
||||||
|
- GList *l;
|
||||||
|
+ GPtrArray *windows;
|
||||||
|
|
||||||
|
child = gtk_widget_get_first_child (GTK_WIDGET (window_list));
|
||||||
|
while (child)
|
||||||
|
@@ -181,9 +180,9 @@ update_windows_list (ScreenCastWidget *widget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
windows = shell_introspect_get_windows (widget->shell_introspect);
|
||||||
|
- for (l = windows; l; l = l->next)
|
||||||
|
+ for (size_t i = 0; windows && i < windows->len; i++)
|
||||||
|
{
|
||||||
|
- Window *window = l->data;
|
||||||
|
+ Window *window = g_ptr_array_index (windows, i);
|
||||||
|
GtkWidget *window_widget;
|
||||||
|
|
||||||
|
if (should_skip_window (window, GTK_WINDOW (toplevel)))
|
||||||
|
diff --git a/src/shellintrospect.c b/src/shellintrospect.c
|
||||||
|
index 1fa8b93..c2b288d 100644
|
||||||
|
--- a/src/shellintrospect.c
|
||||||
|
+++ b/src/shellintrospect.c
|
||||||
|
@@ -22,16 +22,6 @@
|
||||||
|
#include "shell-dbus.h"
|
||||||
|
#include "shellintrospect.h"
|
||||||
|
|
||||||
|
-enum
|
||||||
|
-{
|
||||||
|
- WINDOWS_CHANGED,
|
||||||
|
- ANIMATIONS_ENABLED_CHANGED,
|
||||||
|
-
|
||||||
|
- N_SIGNALS
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static guint signals[N_SIGNALS];
|
||||||
|
-
|
||||||
|
struct _Window
|
||||||
|
{
|
||||||
|
uint64_t id;
|
||||||
|
@@ -50,7 +40,7 @@ struct _ShellIntrospect
|
||||||
|
|
||||||
|
unsigned int version;
|
||||||
|
|
||||||
|
- GList *windows;
|
||||||
|
+ GPtrArray *windows;
|
||||||
|
|
||||||
|
int num_listeners;
|
||||||
|
|
||||||
|
@@ -60,6 +50,16 @@ struct _ShellIntrospect
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ShellIntrospect, shell_introspect, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
+enum
|
||||||
|
+{
|
||||||
|
+ WINDOWS_CHANGED,
|
||||||
|
+ ANIMATIONS_ENABLED_CHANGED,
|
||||||
|
+
|
||||||
|
+ N_SIGNALS
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static guint signals[N_SIGNALS];
|
||||||
|
+
|
||||||
|
static ShellIntrospect *_shell_introspect;
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -70,50 +70,36 @@ window_free (Window *window)
|
||||||
|
g_free (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
-const char *
|
||||||
|
-window_get_title (Window *window)
|
||||||
|
-{
|
||||||
|
- return window->title;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-const char *
|
||||||
|
-window_get_app_id (Window *window)
|
||||||
|
-{
|
||||||
|
- return window->app_id;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-const uint64_t
|
||||||
|
-window_get_id (Window *window)
|
||||||
|
-{
|
||||||
|
- return window->id;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void
|
||||||
|
get_windows_cb (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ShellIntrospect *shell_introspect = user_data;
|
||||||
|
+ g_autoptr(GPtrArray) windows = NULL;
|
||||||
|
g_autoptr(GVariant) windows_variant = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
GVariantIter iter;
|
||||||
|
uint64_t id;
|
||||||
|
GVariant *params = NULL;
|
||||||
|
- GList *windows = NULL;
|
||||||
|
|
||||||
|
- g_list_free_full (shell_introspect->windows, (GDestroyNotify) window_free);
|
||||||
|
- shell_introspect->windows = NULL;
|
||||||
|
+ g_clear_object (&shell_introspect->cancellable);
|
||||||
|
|
||||||
|
if (!org_gnome_shell_introspect_call_get_windows_finish (shell_introspect->proxy,
|
||||||
|
&windows_variant,
|
||||||
|
res,
|
||||||
|
&error))
|
||||||
|
{
|
||||||
|
- g_warning ("Failed to get window list: %s", error->message);
|
||||||
|
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
+ g_warning ("Failed to get window list: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_variant_iter_init (&iter, windows_variant);
|
||||||
|
+
|
||||||
|
+ windows = g_ptr_array_new_full (g_variant_iter_n_children (&iter),
|
||||||
|
+ (GDestroyNotify) window_free);
|
||||||
|
+
|
||||||
|
while (g_variant_iter_loop (&iter, "{t@a{sv}}", &id, ¶ms))
|
||||||
|
{
|
||||||
|
char *app_id = NULL;
|
||||||
|
@@ -131,64 +117,30 @@ get_windows_cb (GObject *source_object,
|
||||||
|
.title = title,
|
||||||
|
.app_id = app_id
|
||||||
|
};
|
||||||
|
- windows = g_list_prepend (windows, window);
|
||||||
|
+ g_ptr_array_add (windows, window);
|
||||||
|
|
||||||
|
g_clear_pointer (¶ms, g_variant_unref);
|
||||||
|
}
|
||||||
|
|
||||||
|
- shell_introspect->windows = windows;
|
||||||
|
+ shell_introspect->windows = g_steal_pointer (&windows);
|
||||||
|
g_signal_emit (shell_introspect, signals[WINDOWS_CHANGED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sync_state (ShellIntrospect *shell_introspect)
|
||||||
|
{
|
||||||
|
+ g_clear_pointer (&shell_introspect->windows, g_ptr_array_unref);
|
||||||
|
+
|
||||||
|
+ g_cancellable_cancel (shell_introspect->cancellable);
|
||||||
|
+ g_clear_object (&shell_introspect->cancellable);
|
||||||
|
+ shell_introspect->cancellable = g_cancellable_new ();
|
||||||
|
+
|
||||||
|
org_gnome_shell_introspect_call_get_windows (shell_introspect->proxy,
|
||||||
|
shell_introspect->cancellable,
|
||||||
|
get_windows_cb,
|
||||||
|
shell_introspect);
|
||||||
|
}
|
||||||
|
|
||||||
|
-GList *
|
||||||
|
-shell_introspect_get_windows (ShellIntrospect *shell_introspect)
|
||||||
|
-{
|
||||||
|
- return shell_introspect->windows;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void
|
||||||
|
-shell_introspect_ref_listeners (ShellIntrospect *shell_introspect)
|
||||||
|
-{
|
||||||
|
- shell_introspect->num_listeners++;
|
||||||
|
-
|
||||||
|
- if (shell_introspect->proxy)
|
||||||
|
- sync_state (shell_introspect);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void
|
||||||
|
-shell_introspect_unref_listeners (ShellIntrospect *shell_introspect)
|
||||||
|
-{
|
||||||
|
- g_return_if_fail (shell_introspect->num_listeners > 0);
|
||||||
|
-
|
||||||
|
- shell_introspect->num_listeners--;
|
||||||
|
- if (shell_introspect->num_listeners == 0)
|
||||||
|
- {
|
||||||
|
- g_list_free_full (shell_introspect->windows,
|
||||||
|
- (GDestroyNotify) window_free);
|
||||||
|
- shell_introspect->windows = NULL;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-gboolean
|
||||||
|
-shell_introspect_are_animations_enabled (ShellIntrospect *shell_introspect,
|
||||||
|
- gboolean *out_animations_enabled)
|
||||||
|
-{
|
||||||
|
- if (!shell_introspect->animations_enabled_valid)
|
||||||
|
- return FALSE;
|
||||||
|
-
|
||||||
|
- *out_animations_enabled = shell_introspect->animations_enabled;
|
||||||
|
- return TRUE;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void
|
||||||
|
on_windows_changed_cb (GDBusProxy *proxy,
|
||||||
|
ShellIntrospect *shell_introspect)
|
||||||
|
@@ -291,6 +243,29 @@ on_shell_introspect_name_vanished (GDBusConnection *connection,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+shell_introspect_class_init (ShellIntrospectClass *klass)
|
||||||
|
+{
|
||||||
|
+ signals[WINDOWS_CHANGED] = g_signal_new ("windows-changed",
|
||||||
|
+ G_TYPE_FROM_CLASS (klass),
|
||||||
|
+ G_SIGNAL_RUN_LAST,
|
||||||
|
+ 0,
|
||||||
|
+ NULL, NULL, NULL,
|
||||||
|
+ G_TYPE_NONE, 0);
|
||||||
|
+ signals[ANIMATIONS_ENABLED_CHANGED] =
|
||||||
|
+ g_signal_new ("animations-enabled-changed",
|
||||||
|
+ G_TYPE_FROM_CLASS (klass),
|
||||||
|
+ G_SIGNAL_RUN_LAST,
|
||||||
|
+ 0,
|
||||||
|
+ NULL, NULL, NULL,
|
||||||
|
+ G_TYPE_NONE, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+shell_introspect_init (ShellIntrospect *shell_introspect)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
ShellIntrospect *
|
||||||
|
shell_introspect_get (void)
|
||||||
|
{
|
||||||
|
@@ -311,25 +286,67 @@ shell_introspect_get (void)
|
||||||
|
return shell_introspect;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-shell_introspect_init (ShellIntrospect *shell_introspect)
|
||||||
|
+GPtrArray *
|
||||||
|
+shell_introspect_get_windows (ShellIntrospect *shell_introspect)
|
||||||
|
{
|
||||||
|
+ return shell_introspect->windows;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
-shell_introspect_class_init (ShellIntrospectClass *klass)
|
||||||
|
+void
|
||||||
|
+shell_introspect_ref_listeners (ShellIntrospect *shell_introspect)
|
||||||
|
{
|
||||||
|
- signals[WINDOWS_CHANGED] = g_signal_new ("windows-changed",
|
||||||
|
- G_TYPE_FROM_CLASS (klass),
|
||||||
|
- G_SIGNAL_RUN_LAST,
|
||||||
|
- 0,
|
||||||
|
- NULL, NULL, NULL,
|
||||||
|
- G_TYPE_NONE, 0);
|
||||||
|
- signals[ANIMATIONS_ENABLED_CHANGED] =
|
||||||
|
- g_signal_new ("animations-enabled-changed",
|
||||||
|
- G_TYPE_FROM_CLASS (klass),
|
||||||
|
- G_SIGNAL_RUN_LAST,
|
||||||
|
- 0,
|
||||||
|
- NULL, NULL, NULL,
|
||||||
|
- G_TYPE_NONE, 0);
|
||||||
|
+ shell_introspect->num_listeners++;
|
||||||
|
+
|
||||||
|
+ if (shell_introspect->proxy)
|
||||||
|
+ sync_state (shell_introspect);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+shell_introspect_unref_listeners (ShellIntrospect *shell_introspect)
|
||||||
|
+{
|
||||||
|
+ g_return_if_fail (shell_introspect->num_listeners > 0);
|
||||||
|
+
|
||||||
|
+ shell_introspect->num_listeners--;
|
||||||
|
+ if (shell_introspect->num_listeners == 0)
|
||||||
|
+ g_clear_pointer (&shell_introspect->windows, g_ptr_array_unref);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const char *
|
||||||
|
+window_get_title (Window *window)
|
||||||
|
+{
|
||||||
|
+ return window->title;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const char *
|
||||||
|
+window_get_app_id (Window *window)
|
||||||
|
+{
|
||||||
|
+ return window->app_id;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const uint64_t
|
||||||
|
+window_get_id (Window *window)
|
||||||
|
+{
|
||||||
|
+ return window->id;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+gboolean
|
||||||
|
+shell_introspect_are_animations_enabled (ShellIntrospect *shell_introspect,
|
||||||
|
+ gboolean *out_animations_enabled)
|
||||||
|
+{
|
||||||
|
+ if (!shell_introspect->animations_enabled_valid)
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
+ *out_animations_enabled = shell_introspect->animations_enabled;
|
||||||
|
+ return TRUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+shell_introspect_wait_for_windows (ShellIntrospect *shell_introspect)
|
||||||
|
+{
|
||||||
|
+ g_assert (shell_introspect->num_listeners > 0);
|
||||||
|
+
|
||||||
|
+ sync_state (shell_introspect);
|
||||||
|
+
|
||||||
|
+ while (!shell_introspect->windows)
|
||||||
|
+ g_main_context_iteration (NULL, TRUE);
|
||||||
|
}
|
||||||
|
diff --git a/src/shellintrospect.h b/src/shellintrospect.h
|
||||||
|
index b187c4d..f63ecee 100644
|
||||||
|
--- a/src/shellintrospect.h
|
||||||
|
+++ b/src/shellintrospect.h
|
||||||
|
@@ -28,19 +28,21 @@ typedef struct _Window Window;
|
||||||
|
G_DECLARE_FINAL_TYPE (ShellIntrospect, shell_introspect,
|
||||||
|
SHELL, INTROSPECT, GObject)
|
||||||
|
|
||||||
|
+ShellIntrospect * shell_introspect_get (void);
|
||||||
|
+
|
||||||
|
+void shell_introspect_ref_listeners (ShellIntrospect *shell_introspect);
|
||||||
|
+
|
||||||
|
+void shell_introspect_unref_listeners (ShellIntrospect *shell_introspect);
|
||||||
|
+
|
||||||
|
const char * window_get_app_id (Window *window);
|
||||||
|
|
||||||
|
const char * window_get_title (Window *window);
|
||||||
|
|
||||||
|
const uint64_t window_get_id (Window *window);
|
||||||
|
|
||||||
|
-GList * shell_introspect_get_windows (ShellIntrospect *shell_introspect);
|
||||||
|
+GPtrArray * shell_introspect_get_windows (ShellIntrospect *shell_introspect);
|
||||||
|
|
||||||
|
-gboolean shell_introspect_are_animations_enabled (ShellIntrospect *introspect,
|
||||||
|
+gboolean shell_introspect_are_animations_enabled (ShellIntrospect *shell_introspect,
|
||||||
|
gboolean *enable_animations);
|
||||||
|
|
||||||
|
-void shell_introspect_ref_listeners (ShellIntrospect *shell_introspect);
|
||||||
|
-
|
||||||
|
-void shell_introspect_unref_listeners (ShellIntrospect *shell_introspect);
|
||||||
|
-
|
||||||
|
-ShellIntrospect * shell_introspect_get (void);
|
||||||
|
+void shell_introspect_wait_for_windows (ShellIntrospect *shell_introspect);
|
@ -0,0 +1,27 @@
|
|||||||
|
From 5450d65d61ea927752c001dff9f94cb9fd7baf7a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Grulich <jgrulich@redhat.com>
|
||||||
|
Date: Tue, 14 Jun 2022 15:39:26 +0200
|
||||||
|
Subject: [PATCH] ScreenCast: close screencast dialog when the session is
|
||||||
|
closed from the client side
|
||||||
|
|
||||||
|
When the session is closed, for example trying to share a screen in Chrome and closing
|
||||||
|
the web page while having the portal dialog still open, it will not take down the dialog
|
||||||
|
and instead it just gets hidden below Chrome's window.
|
||||||
|
---
|
||||||
|
src/screencast.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 15f6a80..729d668 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -852,6 +852,9 @@ screen_cast_session_close (Session *session)
|
||||||
|
error->message);
|
||||||
|
g_clear_object (&screen_cast_session->gnome_screen_cast_session);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ g_clear_pointer (&screen_cast_session->dialog_handle,
|
||||||
|
+ screen_cast_dialog_handle_close);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
@ -0,0 +1,87 @@
|
|||||||
|
From b33d02e04877bfeeaa43671d3b1b48e0680fc12d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||||
|
Date: Mon, 22 Aug 2022 18:45:46 +1000
|
||||||
|
Subject: [PATCH] session: emit the Closed signal when we're closing on our own
|
||||||
|
account
|
||||||
|
|
||||||
|
If a RemoteDesktop/ScreenCast session is closed by mutter, send out the
|
||||||
|
Closed signal on our impl.portal.Session to notify the
|
||||||
|
xdg-desktop-portal that we're done.
|
||||||
|
|
||||||
|
Related: https://github.com/flatpak/xdg-desktop-portal/issues/508
|
||||||
|
---
|
||||||
|
src/remotedesktop.c | 2 +-
|
||||||
|
src/screencast.c | 2 +-
|
||||||
|
src/session.c | 11 +++++++++--
|
||||||
|
src/session.h | 2 +-
|
||||||
|
4 files changed, 12 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/remotedesktop.c b/src/remotedesktop.c
|
||||||
|
index 46d1dcc..0298f68 100644
|
||||||
|
--- a/src/remotedesktop.c
|
||||||
|
+++ b/src/remotedesktop.c
|
||||||
|
@@ -266,7 +266,7 @@ static void
|
||||||
|
on_mutter_session_closed (OrgGnomeMutterRemoteDesktopSession *mutter_session_proxy,
|
||||||
|
RemoteDesktopSession *remote_desktop_session)
|
||||||
|
{
|
||||||
|
- session_close ((Session *)remote_desktop_session);
|
||||||
|
+ session_close ((Session *)remote_desktop_session, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RemoteDesktopSession *
|
||||||
|
diff --git a/src/screencast.c b/src/screencast.c
|
||||||
|
index 15f6a80..0a15033 100644
|
||||||
|
--- a/src/screencast.c
|
||||||
|
+++ b/src/screencast.c
|
||||||
|
@@ -243,7 +243,7 @@ static void
|
||||||
|
on_gnome_screen_cast_session_closed (GnomeScreenCastSession *gnome_screen_cast_session,
|
||||||
|
ScreenCastSession *screen_cast_session)
|
||||||
|
{
|
||||||
|
- session_close ((Session *)screen_cast_session);
|
||||||
|
+ session_close ((Session *)screen_cast_session, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
diff --git a/src/session.c b/src/session.c
|
||||||
|
index 5ebe13f..b428ef8 100644
|
||||||
|
--- a/src/session.c
|
||||||
|
+++ b/src/session.c
|
||||||
|
@@ -73,8 +73,15 @@ session_unexport (Session *session)
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
-session_close (Session *session)
|
||||||
|
+session_close (Session *session, gboolean notify)
|
||||||
|
{
|
||||||
|
+ if (notify)
|
||||||
|
+ {
|
||||||
|
+ GVariantBuilder details_builder;
|
||||||
|
+ g_variant_builder_init (&details_builder, G_VARIANT_TYPE_VARDICT);
|
||||||
|
+ g_signal_emit_by_name (session, "closed", g_variant_builder_end (&details_builder));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (session->exported)
|
||||||
|
session_unexport (session);
|
||||||
|
|
||||||
|
@@ -92,7 +99,7 @@ handle_close (XdpImplSession *object,
|
||||||
|
Session *session = (Session *)object;
|
||||||
|
|
||||||
|
if (!session->closed)
|
||||||
|
- session_close (session);
|
||||||
|
+ session_close (session, FALSE);
|
||||||
|
|
||||||
|
xdp_impl_session_complete_close (object, invocation);
|
||||||
|
|
||||||
|
diff --git a/src/session.h b/src/session.h
|
||||||
|
index 4a1173a..7594bd8 100644
|
||||||
|
--- a/src/session.h
|
||||||
|
+++ b/src/session.h
|
||||||
|
@@ -47,7 +47,7 @@ Session *lookup_session (const char *id);
|
||||||
|
|
||||||
|
Session *session_new (const char *id);
|
||||||
|
|
||||||
|
-void session_close (Session *session);
|
||||||
|
+void session_close (Session *session, gboolean notify);
|
||||||
|
|
||||||
|
gboolean session_export (Session *session,
|
||||||
|
GDBusConnection *connection,
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
Name: xdg-desktop-portal-gnome
|
Name: xdg-desktop-portal-gnome
|
||||||
Version: 41.2
|
Version: 41.2
|
||||||
Release: 2%{?dist}
|
Release: 3%{?dist}
|
||||||
Summary: Backend implementation for xdg-desktop-portal using GNOME
|
Summary: Backend implementation for xdg-desktop-portal using GNOME
|
||||||
|
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
@ -14,6 +14,33 @@ Source0: https://download.gnome.org/sources/%{name}/41/%{name}-%{tarball_
|
|||||||
|
|
||||||
Patch0: windows-changed-signal.patch
|
Patch0: windows-changed-signal.patch
|
||||||
|
|
||||||
|
## Screencast: stream restoration support
|
||||||
|
# Code cleanups/shuffling
|
||||||
|
# https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/merge_requests/18
|
||||||
|
Patch11: 0001-screencast-trivial-style-cleanups.patch
|
||||||
|
Patch12: 0002-screencast-cleanup-unnecessary-forward-declaration.patch
|
||||||
|
Patch13: 0003-screencast-more-code-shuffling-and-cleanups.patch
|
||||||
|
Patch14: 0004-screencastwidget-rework-selection-api.patch
|
||||||
|
# Stream restoration support
|
||||||
|
# https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/merge_requests/14
|
||||||
|
Patch15: 0005-displaystatetracker-add-match-string.patch
|
||||||
|
Patch16: 0006-implement-screencast-stream-restoration.patch
|
||||||
|
Patch17: 0007-screencast-pass-stream-ids.patch
|
||||||
|
# Followup fixes
|
||||||
|
Patch18: 0008-screencast-fix-variant-type-check.patch
|
||||||
|
Patch19: 0009-screencast-dont-restore-windows-with-too-different-titles.patch
|
||||||
|
Patch20: 0010-screencast-dont-wrap-restore-data-in-another-variant.patch
|
||||||
|
# https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/merge_requests/49
|
||||||
|
Patch21: 0011-fix-window-screencast-stream-restore.patch
|
||||||
|
# Closely related screencast fixes
|
||||||
|
# https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/merge_requests/40
|
||||||
|
# https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/merge_requests/41
|
||||||
|
Patch22: 0012-screencast-close-screencast-dialog-when-the-session-is-closed-from-client-side.patch
|
||||||
|
# https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/merge_requests/52
|
||||||
|
Patch23: 0013-session-emit-closed-signal-when-we-are-closing-our-own-account.patch
|
||||||
|
# https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/merge_requests/86
|
||||||
|
Patch24: 00014-screencasts-duplicate-monitor-and-window-stream-info.patch
|
||||||
|
|
||||||
BuildRequires: desktop-file-utils
|
BuildRequires: desktop-file-utils
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
BuildRequires: gettext
|
BuildRequires: gettext
|
||||||
@ -68,6 +95,10 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jan 09 2024 Jan Grulich <jgrulich@redhat.com> - 41.2-3
|
||||||
|
- Add screencast stream restoration support
|
||||||
|
Resolves: RHEL-4526
|
||||||
|
|
||||||
* Tue Dec 13 2022 Jonas Ådahl <jadahl@redhat.com> - 41.2-2
|
* Tue Dec 13 2022 Jonas Ådahl <jadahl@redhat.com> - 41.2-2
|
||||||
- Keep screen share window list up to date
|
- Keep screen share window list up to date
|
||||||
Resolves: #2148362
|
Resolves: #2148362
|
||||||
|
Loading…
Reference in New Issue
Block a user