From 0df5f89c45f3aba8517a00a919b825d761803d06 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jan 13 2021 16:09:03 +0000 Subject: import gnome-shell-3.32.2-25.el8 --- diff --git a/SOURCES/0001-screencast-Stop-recording-when-screen-size-or-resour.patch b/SOURCES/0001-screencast-Stop-recording-when-screen-size-or-resour.patch new file mode 100644 index 0000000..582ff4e --- /dev/null +++ b/SOURCES/0001-screencast-Stop-recording-when-screen-size-or-resour.patch @@ -0,0 +1,253 @@ +From 67a4506d4d8a0cbbaca5df4adfc309e54e557aee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Tue, 5 Jan 2021 12:04:23 +0100 +Subject: [PATCH] screencast: Stop recording when screen size or resource scale + change + +Video encoders don't really handle changing the size of the video, and if +we'd e.g. change resolution while recording, we would end up with a corrupt +video file. Handle this more gracefully by stopping the recording if the +conditions change. +--- + js/ui/screencast.js | 92 +++++++++++++++++++++++++++++++++++++++++--- + src/shell-recorder.c | 50 ++++++++++++------------ + src/shell-recorder.h | 1 + + 3 files changed, 114 insertions(+), 29 deletions(-) + +diff --git a/js/ui/screencast.js b/js/ui/screencast.js +index 0b0b14a8e..54f8fb5ae 100644 +--- a/js/ui/screencast.js ++++ b/js/ui/screencast.js +@@ -1,6 +1,6 @@ + // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + +-const { Gio, GLib, Shell } = imports.gi; ++const { Gio, GLib, Meta, Shell } = imports.gi; + const Signals = imports.signals; + + const Main = imports.ui.main; +@@ -53,16 +53,27 @@ var ScreencastService = class { + this._stopRecordingForSender(name); + } + +- _stopRecordingForSender(sender) { ++ _stopRecordingForSender(sender, closeNow=false) { + let recorder = this._recorders.get(sender); + if (!recorder) + return false; + + Gio.bus_unwatch_name(recorder._watchNameId); +- recorder.close(); ++ if (closeNow) ++ recorder.close_now(); ++ else ++ recorder.close(); + this._recorders.delete(sender); + this.emit('updated'); + ++ let connection = this._dbusImpl.get_connection(); ++ let info = this._dbusImpl.get_info(); ++ connection.emit_signal(sender, ++ this._dbusImpl.get_object_path(), ++ info ? info.name : null, ++ 'Stopped', ++ null); ++ + return true; + } + +@@ -78,6 +89,53 @@ var ScreencastService = class { + recorder.set_draw_cursor(options['draw-cursor']); + } + ++ _ensureResourceScaleChangedHandler() { ++ if (this._resourceScaleChangedHandlerId) ++ return; ++ ++ this._resourceScaleChangedHandlerId = ++ global.stage.connect('notify::resource-scale', ++ () => { ++ for (let sender of this._recorders.keys()) { ++ let recorder = this._recorders.get(sender); ++ ++ if (!recorder.is_recording()) ++ continue; ++ ++ this._stopRecordingForSender(sender, true); ++ } ++ }); ++ } ++ ++ _ensureMonitorsChangedHandler() { ++ if (this._monitorsChangedHandlerId) ++ return; ++ ++ this._monitorsChangedHandlerId = Main.layoutManager.connect('monitors-changed', ++ () => { ++ for (let sender of this._recorders.keys()) { ++ let recorder = this._recorders.get(sender); ++ ++ if (!recorder.is_recording()) ++ continue; ++ ++ let geometry = recorder._geometry; ++ let screenWidth = global.screen_width; ++ let screenHeight = global.screen_height; ++ ++ if (recorder._isAreaScreecast) { ++ if (geometry.x + geometry.width > screenWidth || ++ geometry.y + geometry.height > screenHeight) ++ this._stopRecordingForSender(sender, true); ++ } else { ++ if (geometry.width != screenWidth || ++ geometry.height != screenHeight) ++ this._stopRecordingForSender(sender, true); ++ } ++ } ++ }); ++ } ++ + ScreencastAsync(params, invocation) { + let returnValue = [false, '']; + if (!Main.sessionMode.allowScreencast || +@@ -95,8 +153,20 @@ var ScreencastService = class { + this._applyOptionalParameters(recorder, options); + let [success, fileName] = recorder.record(); + returnValue = [success, fileName ? fileName : '']; +- if (!success) ++ if (success) { ++ recorder._isAreaScreecast = false; ++ recorder._geometry = ++ new Meta.Rectangle({ ++ x: 0, ++ y: 0, ++ width: global.screen_width, ++ height: global.screen_height ++ }); ++ this._ensureResourceScaleChangedHandler(); ++ this._ensureMonitorsChangedHandler(); ++ } else { + this._stopRecordingForSender(sender); ++ } + } + + invocation.return_value(GLib.Variant.new('(bs)', returnValue)); +@@ -131,8 +201,20 @@ var ScreencastService = class { + this._applyOptionalParameters(recorder, options); + let [success, fileName] = recorder.record(); + returnValue = [success, fileName ? fileName : '']; +- if (!success) ++ if (success) { ++ recorder._isAreaScreecast = true; ++ recorder._geometry = ++ new Meta.Rectangle({ ++ x: x, ++ y: y, ++ width: width, ++ height: height ++ }); ++ this._ensureResourceScaleChangedHandler(); ++ this._ensureMonitorsChangedHandler(); ++ } else { + this._stopRecordingForSender(sender); ++ } + } + + invocation.return_value(GLib.Variant.new('(bs)', returnValue)); +diff --git a/src/shell-recorder.c b/src/shell-recorder.c +index 0203ecf1c..e561a0152 100644 +--- a/src/shell-recorder.c ++++ b/src/shell-recorder.c +@@ -511,21 +511,6 @@ recorder_update_size (ShellRecorder *recorder) + } + } + +-static void +-recorder_on_stage_notify_size (GObject *object, +- GParamSpec *pspec, +- ShellRecorder *recorder) +-{ +- recorder_update_size (recorder); +- +- /* This breaks the recording but tweaking the GStreamer pipeline a bit +- * might make it work, at least if the codec can handle a stream where +- * the frame size changes in the middle. +- */ +- if (recorder->current_pipeline) +- recorder_pipeline_set_caps (recorder->current_pipeline); +-} +- + static gboolean + recorder_idle_redraw (gpointer data) + { +@@ -622,12 +607,6 @@ recorder_connect_stage_callbacks (ShellRecorder *recorder) + G_CALLBACK (recorder_on_stage_destroy), recorder); + g_signal_connect_after (recorder->stage, "paint", + G_CALLBACK (recorder_on_stage_paint), recorder); +- g_signal_connect (recorder->stage, "notify::width", +- G_CALLBACK (recorder_on_stage_notify_size), recorder); +- g_signal_connect (recorder->stage, "notify::height", +- G_CALLBACK (recorder_on_stage_notify_size), recorder); +- g_signal_connect (recorder->stage, "notify::resource-scale", +- G_CALLBACK (recorder_on_stage_notify_size), recorder); + } + + static void +@@ -639,9 +618,6 @@ recorder_disconnect_stage_callbacks (ShellRecorder *recorder) + g_signal_handlers_disconnect_by_func (recorder->stage, + (void *)recorder_on_stage_paint, + recorder); +- g_signal_handlers_disconnect_by_func (recorder->stage, +- (void *)recorder_on_stage_notify_size, +- recorder); + + /* We don't don't deselect for cursor changes in case someone else just + * happened to be selecting for cursor events on the same window; sending +@@ -1578,6 +1554,32 @@ shell_recorder_record (ShellRecorder *recorder, + return TRUE; + } + ++/** ++ * shell_recorder_close_now: ++ * @recorder: the #ShellRecorder ++ * ++ * Stops recording immediately. It's possible to call shell_recorder_record() ++ * again to reopen a new recording stream, but unless change the recording ++ * filename, this may result in the old recording being overwritten. ++ */ ++void ++shell_recorder_close_now (ShellRecorder *recorder) ++{ ++ g_return_if_fail (SHELL_IS_RECORDER (recorder)); ++ g_return_if_fail (recorder->state != RECORDER_STATE_CLOSED); ++ ++ recorder_remove_update_pointer_timeout (recorder); ++ recorder_close_pipeline (recorder); ++ ++ recorder->state = RECORDER_STATE_CLOSED; ++ ++ /* Reenable after the recording */ ++ meta_enable_unredirect_for_display (shell_global_get_display (shell_global_get ())); ++ ++ /* Release the refcount we took when we started recording */ ++ g_object_unref (recorder); ++} ++ + /** + * shell_recorder_close: + * @recorder: the #ShellRecorder +diff --git a/src/shell-recorder.h b/src/shell-recorder.h +index c1e0e6368..1c3e6aab4 100644 +--- a/src/shell-recorder.h ++++ b/src/shell-recorder.h +@@ -37,6 +37,7 @@ void shell_recorder_set_area (ShellRecorder *recorder, + gboolean shell_recorder_record (ShellRecorder *recorder, + char **filename_used); + void shell_recorder_close (ShellRecorder *recorder); ++void shell_recorder_close_now (ShellRecorder *recorder); + void shell_recorder_pause (ShellRecorder *recorder); + gboolean shell_recorder_is_recording (ShellRecorder *recorder); + +-- +2.27.0 + diff --git a/SPECS/gnome-shell.spec b/SPECS/gnome-shell.spec index 73ac400..12893f7 100644 --- a/SPECS/gnome-shell.spec +++ b/SPECS/gnome-shell.spec @@ -1,6 +1,6 @@ Name: gnome-shell Version: 3.32.2 -Release: 24%{?dist} +Release: 25%{?dist} Summary: Window management and application launching for GNOME Group: User Interface/Desktops @@ -64,6 +64,9 @@ Patch63: 0004-global-force-fsync-to-worker-thread-when-saving-stat.patch Patch64: 0005-app-cache-add-ShellAppCache-for-GAppInfo-caching.patch Patch65: 0006-js-Always-use-AppSystem-to-lookup-apps.patch +# Stop screen recording on monitor changes (#1705392) +Patch70: 0001-screencast-Stop-recording-when-screen-size-or-resour.patch + # suspend/resume fix on nvidia (#1663440) Patch10001: 0001-background-refresh-after-suspend-on-wayland.patch Patch10002: 0002-background-rebuild-background-not-just-animation-on-.patch @@ -243,7 +246,11 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/evolution-calendar.de %{_mandir}/man1/%{name}.1.gz %changelog -* Tue Jan 07 2021 Florian Müllner - 3.32.2-24 +* Tue Jan 12 2021 Jonas Ådahl - 3.32.2-25 +- Stop screen recording on monitor changes + Resolves: #1705392 + +* Thu Jan 07 2021 Florian Müllner - 3.32.2-24 - Handle workspace from startup notification Resolves: #1671761