From ebb234de1901c8988b083123fdd724a5ef36c603 Mon Sep 17 00:00:00 2001 From: "Ward Nakchbandi (Cosmic Fusion)" Date: Tue, 27 Jun 2023 00:18:37 +0300 Subject: [PATCH] initial push --- ...oreground-color-to-text-as-a-PangoAt.patch | 95 +++++ .../debian/Revert-build-Port-to-gcr4.patch | 107 ++++++ .../Revert-tests-Fail-on-warnings-too.patch | 22 ++ ...on-prefs-Give-Debian-specific-advice.patch | 32 ++ ...ingerprint-service-synchronously-whe.patch | 248 +++++++++++++ ...sible-to-set-debug-flags-dynamically.patch | 237 ++++++++++++ ...-when-magnifier-is-enabled-and-scale.patch | 172 +++++++++ ...ktrace-crashes-all-and-backtrace-all.patch | 47 +++ ...nularity-of-backtraces-in-SHELL_DEBU.patch | 169 +++++++++ ...n-error-message-on-gnome-shell-crash.patch | 30 ++ debian/patches/series | 27 ++ ...add-support-for-debugFlags-parameter.patch | 46 +++ ...rt-dash-Use-pin-instead-of-favorites.patch | 90 +++++ debian/patches/ubuntu/background_login.patch | 39 ++ .../ubuntu/configure_login_screen.patch | 199 ++++++++++ ...support-to-Yaru-theme-color-variants.patch | 81 ++++ debian/patches/ubuntu/desktop_detect.patch | 66 ++++ debian/patches/ubuntu/gdm_alternatives.patch | 42 +++ ...keep-ubuntu-logo-bright-lp1867133-v1.patch | 36 ++ ...locate-before-getting-size-of-tracke.patch | 34 ++ .../ubuntu/lightdm-user-switching.patch | 93 +++++ debian/patches/ubuntu/lock_on_suspend.patch | 48 +++ ...loading-multiple-Yaru-theme-variants.patch | 345 ++++++++++++++++++ .../ubuntu/resolve_alternate_theme_path.patch | 50 +++ ...ncel-method-on-providers-when-no-dat.patch | 163 +++++++++ .../ubuntu/secure_mode_extension.patch | 89 +++++ ...rt-for-configuring-an-icons-resource.patch | 38 ++ ...not-move-snap-apps-to-gnome-apps-sco.patch | 75 ++++ debian/shlibs.local | 1 + 29 files changed, 2721 insertions(+) create mode 100644 debian/patches/Revert-st-Apply-css-foreground-color-to-text-as-a-PangoAt.patch create mode 100644 debian/patches/debian/Revert-build-Port-to-gcr4.patch create mode 100644 debian/patches/debian/Revert-tests-Fail-on-warnings-too.patch create mode 100644 debian/patches/debian/gnome-shell-extension-prefs-Give-Debian-specific-advice.patch create mode 100644 debian/patches/gdm-util-Only-start-fingerprint-service-synchronously-whe.patch create mode 100644 debian/patches/global-make-possible-to-set-debug-flags-dynamically.patch create mode 100644 debian/patches/magnifier-Show-cursor-when-magnifier-is-enabled-and-scale.patch create mode 100644 debian/patches/main-add-backtrace-crashes-all-and-backtrace-all.patch create mode 100644 debian/patches/main-increase-the-granularity-of-backtraces-in-SHELL_DEBU.patch create mode 100644 debian/patches/main-show-an-error-message-on-gnome-shell-crash.patch create mode 100644 debian/patches/series create mode 100644 debian/patches/sessionMode-add-support-for-debugFlags-parameter.patch create mode 100644 debian/patches/ubuntu/Revert-dash-Use-pin-instead-of-favorites.patch create mode 100644 debian/patches/ubuntu/background_login.patch create mode 100644 debian/patches/ubuntu/configure_login_screen.patch create mode 100644 debian/patches/ubuntu/darkMode-Add-support-to-Yaru-theme-color-variants.patch create mode 100644 debian/patches/ubuntu/desktop_detect.patch create mode 100644 debian/patches/ubuntu/gdm_alternatives.patch create mode 100644 debian/patches/ubuntu/keep-ubuntu-logo-bright-lp1867133-v1.patch create mode 100644 debian/patches/ubuntu/layout-Try-to-allocate-before-getting-size-of-tracke.patch create mode 100644 debian/patches/ubuntu/lightdm-user-switching.patch create mode 100644 debian/patches/ubuntu/lock_on_suspend.patch create mode 100644 debian/patches/ubuntu/main-Support-loading-multiple-Yaru-theme-variants.patch create mode 100644 debian/patches/ubuntu/resolve_alternate_theme_path.patch create mode 100644 debian/patches/ubuntu/search-call-XUbuntuCancel-method-on-providers-when-no-dat.patch create mode 100644 debian/patches/ubuntu/secure_mode_extension.patch create mode 100644 debian/patches/ubuntu/sessionMode-Add-support-for-configuring-an-icons-resource.patch create mode 100644 debian/patches/ubuntu/shell-global-util-Do-not-move-snap-apps-to-gnome-apps-sco.patch create mode 100644 debian/shlibs.local diff --git a/debian/patches/Revert-st-Apply-css-foreground-color-to-text-as-a-PangoAt.patch b/debian/patches/Revert-st-Apply-css-foreground-color-to-text-as-a-PangoAt.patch new file mode 100644 index 0000000..d801d77 --- /dev/null +++ b/debian/patches/Revert-st-Apply-css-foreground-color-to-text-as-a-PangoAt.patch @@ -0,0 +1,95 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Fri, 1 Apr 2022 02:41:07 +0200 +Subject: Revert "st: Apply css foreground color to text as a PangoAttribute" + +Using the pango foreground color implies that such part will have a +color set at pango level and so that cogl will use this value as a +color override (as per cogl_pango_renderer_set_color_for_part()). + +This is fine for most labels, but in case the clutter-text has the +selected text color set, it is simply ignored, because the overridden +color is always preferred. + +Also the reason for this commit, was not to apply colors on top of +colored fonts, but this won't happen anymore now because mutter's commit +aa136f45 ensures that no color will be applied to glyphs that are +already colored. + +So to me it looks that's just safer to revert it, instead of adding +different logic to handle the selected-text-color case. + +This reverts commit 66c4b1a8b607600f193b34e6a9f8c85f76c2ac2c. + +Origin: https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2260 +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1878998 +--- + src/st/st-entry.c | 2 ++ + src/st/st-private.c | 32 ++++++++++++++++++++++++++------ + 2 files changed, 28 insertions(+), 6 deletions(-) + +diff --git a/src/st/st-entry.c b/src/st/st-entry.c +index 64f85fd..d45ce95 100644 +--- a/src/st/st-entry.c ++++ b/src/st/st-entry.c +@@ -1095,6 +1095,8 @@ st_entry_init (StEntry *entry) + g_signal_connect (priv->entry, "notify::line-alignment", + G_CALLBACK (invalidate_shadow_pipeline), entry); + ++ g_signal_connect_swapped (priv->entry, "notify::editable", ++ G_CALLBACK (st_widget_style_changed), entry); + + priv->spacing = 6.0f; + +diff --git a/src/st/st-private.c b/src/st/st-private.c +index bb98151..1b70c5e 100644 +--- a/src/st/st-private.c ++++ b/src/st/st-private.c +@@ -115,22 +115,42 @@ _st_set_text_from_style (ClutterText *text, + StTextDecoration decoration; + PangoAttrList *attribs = NULL; + const PangoFontDescription *font; +- PangoAttribute *foreground; + StTextAlign align; + gdouble spacing; + gchar *font_features; ++ gboolean foreground_color_set; + + font = st_theme_node_get_font (theme_node); + clutter_text_set_font_description (text, (PangoFontDescription *) font); + + attribs = pango_attr_list_new (); + ++ foreground_color_set = FALSE; + st_theme_node_get_foreground_color (theme_node, &color); +- clutter_text_set_cursor_color (text, &color); +- foreground = pango_attr_foreground_new (color.red * 255, +- color.green * 255, +- color.blue * 255); +- pango_attr_list_insert (attribs, foreground); ++ ++ if (clutter_text_get_editable (text)) ++ { ++ ClutterColor selected_color; ++ ++ if (st_theme_node_lookup_color (theme_node, "selected-color", ++ TRUE, &selected_color) && ++ !clutter_color_equal (&selected_color, &color)) ++ { ++ clutter_text_set_color (text, &color); ++ clutter_text_set_cursor_color (text, &color); ++ foreground_color_set = TRUE; ++ } ++ } ++ ++ if (!foreground_color_set) ++ { ++ PangoAttribute *foreground; ++ clutter_text_set_cursor_color (text, &color); ++ foreground = pango_attr_foreground_new (color.red * 255, ++ color.green * 255, ++ color.blue * 255); ++ pango_attr_list_insert (attribs, foreground); ++ } + + if (color.alpha != 255) + { diff --git a/debian/patches/debian/Revert-build-Port-to-gcr4.patch b/debian/patches/debian/Revert-build-Port-to-gcr4.patch new file mode 100644 index 0000000..2f660df --- /dev/null +++ b/debian/patches/debian/Revert-build-Port-to-gcr4.patch @@ -0,0 +1,107 @@ +From: Jeremy Bicha +Date: Sun, 21 Aug 2022 10:30:55 -0400 +Subject: Revert "build: Port to gcr4" + +This reverts commit 5c935af7d3b3a3c9feb4e0d9ea214b6d25a7a2e7. + +Forwarded: not-needed +--- + js/ui/environment.js | 2 +- + meson.build | 4 ++-- + src/meson.build | 2 +- + src/shell-keyring-prompt.c | 6 +++--- + src/shell-secure-text-buffer.c | 2 +- + 5 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/js/ui/environment.js b/js/ui/environment.js +index 224456d..d4292ca 100644 +--- a/js/ui/environment.js ++++ b/js/ui/environment.js +@@ -8,7 +8,7 @@ imports.gi.versions.Atk = '1.0'; + imports.gi.versions.Atspi = '2.0'; + imports.gi.versions.Clutter = Config.LIBMUTTER_API_VERSION; + imports.gi.versions.Cogl = Config.LIBMUTTER_API_VERSION; +-imports.gi.versions.Gcr = '4'; ++imports.gi.versions.Gcr = '3'; + imports.gi.versions.Gdk = '4.0'; + imports.gi.versions.Gdm = '1.0'; + imports.gi.versions.Geoclue = '2.0'; +diff --git a/meson.build b/meson.build +index 7b08fe5..0100552 100644 +--- a/meson.build ++++ b/meson.build +@@ -20,7 +20,7 @@ libmutter_test_pc = 'libmutter-test-' + mutter_api_version + + ecal_req = '>= 3.33.1' + eds_req = '>= 3.33.1' +-gcr_req = '>= 3.90.0' ++gcr_req = '>= 3.7.5' + gio_req = '>= 2.56.0' + gi_req = '>= 1.49.1' + gjs_req = '>= 1.73.1' +@@ -71,7 +71,7 @@ endif + atk_bridge_dep = dependency('atk-bridge-2.0') + ecal_dep = dependency('libecal-2.0', version: ecal_req) + eds_dep = dependency('libedataserver-1.2', version: eds_req) +-gcr_dep = dependency('gcr-4', version: gcr_req) ++gcr_dep = dependency('gcr-base-3', version: gcr_req) + gdk_x11_dep = dependency('gdk-x11-3.0') + gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0') + gi_dep = dependency('gobject-introspection-1.0', version: gi_req) +diff --git a/src/meson.build b/src/meson.build +index 4f88207..512c213 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -213,7 +213,7 @@ libshell_dep = declare_dependency(link_with: libshell) + libshell_gir_includes = [ + 'Clutter-@0@'.format(mutter_api_version), + 'Meta-@0@'.format(mutter_api_version), +- 'Gcr-4', ++ 'Gcr-3', + 'PolkitAgent-1.0', + 'GdkPixbuf-2.0' + ] +diff --git a/src/shell-keyring-prompt.c b/src/shell-keyring-prompt.c +index bb03279..83c6746 100644 +--- a/src/shell-keyring-prompt.c ++++ b/src/shell-keyring-prompt.c +@@ -26,7 +26,7 @@ + #include "shell-secure-text-buffer.h" + + #define GCR_API_SUBJECT_TO_CHANGE +-#include ++#include + + #include + +@@ -91,7 +91,7 @@ enum { + + static GParamSpec *props[N_PROPS] = { NULL, }; + +-static void shell_keyring_prompt_iface (GcrPromptInterface *iface); ++static void shell_keyring_prompt_iface (GcrPromptIface *iface); + + G_DEFINE_TYPE_WITH_CODE (ShellKeyringPrompt, shell_keyring_prompt, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GCR_TYPE_PROMPT, shell_keyring_prompt_iface); +@@ -531,7 +531,7 @@ shell_keyring_prompt_close (GcrPrompt *prompt) + } + + static void +-shell_keyring_prompt_iface (GcrPromptInterface *iface) ++shell_keyring_prompt_iface (GcrPromptIface *iface) + { + iface->prompt_password_async = shell_keyring_prompt_password_async; + iface->prompt_password_finish = shell_keyring_prompt_password_finish; +diff --git a/src/shell-secure-text-buffer.c b/src/shell-secure-text-buffer.c +index 8271410..03af451 100644 +--- a/src/shell-secure-text-buffer.c ++++ b/src/shell-secure-text-buffer.c +@@ -26,7 +26,7 @@ + #include "shell-secure-text-buffer.h" + + #define GCR_API_SUBJECT_TO_CHANGE +-#include ++#include + + #include + diff --git a/debian/patches/debian/Revert-tests-Fail-on-warnings-too.patch b/debian/patches/debian/Revert-tests-Fail-on-warnings-too.patch new file mode 100644 index 0000000..14008c4 --- /dev/null +++ b/debian/patches/debian/Revert-tests-Fail-on-warnings-too.patch @@ -0,0 +1,22 @@ +From: Jeremy Bicha +Date: Fri, 17 Feb 2023 15:35:20 -0500 +Subject: Revert "tests: Fail on warnings too" + +This reverts commit 207b9bb3c0a582b830218fd1b6e8760684adbc48. +--- + tests/meson.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/meson.build b/tests/meson.build +index 85339dd..345eedc 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -54,7 +54,7 @@ libgvc_path = fs.parent(libgvc.get_variable('libgvc').full_path()) + background_file = files(join_paths('data', 'background.png')) + + perf_testenv = environment() +-perf_testenv.set('G_DEBUG', 'fatal-warnings') ++perf_testenv.set('G_DEBUG', 'fatal-criticals') + perf_testenv.set('G_MESSAGES_DEBUG', 'GNOME Shell') + perf_testenv.set('GNOME_SHELL_DATADIR', data_builddir) + perf_testenv.set('GNOME_SHELL_BUILDDIR', src_builddir) diff --git a/debian/patches/debian/gnome-shell-extension-prefs-Give-Debian-specific-advice.patch b/debian/patches/debian/gnome-shell-extension-prefs-Give-Debian-specific-advice.patch new file mode 100644 index 0000000..9759e4b --- /dev/null +++ b/debian/patches/debian/gnome-shell-extension-prefs-Give-Debian-specific-advice.patch @@ -0,0 +1,32 @@ +From: Simon McVittie +Date: Sun, 12 Sep 2021 10:41:54 +0100 +Subject: gnome-shell-extension-prefs: Give Debian-specific advice + +We package gnome-extensions-app in the same binary package as +gnome-shell-extension-prefs, so there's never a need to download it from +Flathub. + +Forwarded: not-needed, Debian-specific +Signed-off-by: Simon McVittie +--- + src/gnome-shell-extension-prefs | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/gnome-shell-extension-prefs b/src/gnome-shell-extension-prefs +index 303b196..a59ffed 100755 +--- a/src/gnome-shell-extension-prefs ++++ b/src/gnome-shell-extension-prefs +@@ -13,10 +13,10 @@ openPrefs() { + } + + cat >&2 < +Date: Tue, 1 Mar 2022 11:57:20 +0100 +Subject: gmd/util: Only start fingerprint service synchronously when it's + default + +On ShellUserVerifier construction we used to start fprintd in a sync +fashion all the times, however in case the daemon had startup failures +or was hanging for whatever reason (like due to devices probing, given +that fprintd synchronously wait for them all to be initialized) we used +to just fail, leaving gdm or the lockscreen inusable. + +While this could be prevented with a try/catch statement, there's no +much point to wait for fprintd if that's not the default authentication +service, and so: + - If we use gdm-fingerprint as default auth method, use a sync call to + initialize it and in case of failures, just continue with fallback + authentication mechanism (password) + + - Otherwise, asynchronously initialize fprintd and continue with the + ShellUserVerifier without fingerprint support until we got a reply. + In case the service fails to deliver us a result, we don't give up + but we will try doing that at each authentication via + _checkForFingerprintReader(). + In case all works properly, as per the previous commit, once the + initialization is done, we'll start the fingerprint PAM gdm service. + +Fixes #5168 + +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1962566 +Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5168 +Origin: https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2267 +--- + js/gdm/util.js | 128 +++++++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 101 insertions(+), 27 deletions(-) + +diff --git a/js/gdm/util.js b/js/gdm/util.js +index 78c45cb..e4902f8 100644 +--- a/js/gdm/util.js ++++ b/js/gdm/util.js +@@ -44,6 +44,7 @@ var DISABLE_USER_LIST_KEY = 'disable-user-list'; + + // Give user 48ms to read each character of a PAM message + var USER_READ_TIME = 48; ++const FINGERPRINT_SERVICE_PROXY_TIMEOUT = 5000; + const FINGERPRINT_ERROR_TIMEOUT_WAIT = 15; + + var MessageType = { +@@ -148,16 +149,49 @@ var ShellUserVerifier = class extends Signals.EventEmitter { + this._preemptingService = null; + + this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA }); +- this._settings.connect('changed', +- this._updateDefaultService.bind(this)); +- this._updateDefaultService(); ++ this._settings.connect('changed', () => this._updateDefaultServiceWithFallback()); ++ ++ this._fingerprintReaderType = FingerprintReaderType.NONE; ++ if (this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY)) { ++ const fprintManager = new FprintManagerProxy(Gio.DBus.system, ++ 'net.reactivated.Fprint', ++ '/net/reactivated/Fprint/Manager', ++ null, ++ null, ++ Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES | ++ Gio.DBusProxyFlags.DO_NOT_AUTO_START_AT_CONSTRUCTION | ++ Gio.DBusProxyFlags.DO_NOT_CONNECT_SIGNALS); ++ ++ // Do not wait too much for fprintd to reply, as in case it hangs ++ // we should fail early without having the shell to misbehave because ++ fprintManager.set_default_timeout(FINGERPRINT_SERVICE_PROXY_TIMEOUT); + +- this._fprintManager = new FprintManagerProxy(Gio.DBus.system, +- 'net.reactivated.Fprint', +- '/net/reactivated/Fprint/Manager', +- null, +- null, +- Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES); ++ this._updateDefaultService(); ++ ++ if (!this._defaultService) { ++ // Fingerprint is the default one, we must wait for it! ++ try { ++ const [devicePath] = fprintManager.GetDefaultDeviceSync(); ++ this._fprintManager = fprintManager; ++ ++ const fprintDeviceProxy = new FprintDeviceProxy(Gio.DBus.system, ++ 'net.reactivated.Fprint', devicePath, null, null, ++ Gio.DBusProxyFlags.NOT_CONNECT_SIGNALS); ++ this._setFingerprintReaderType(fprintDeviceProxy['scan-type']); ++ } catch (e) { ++ logError(e, 'Failed to initialize fprintd service'); ++ } finally { ++ this._updateDefaultServiceWithFallback(); ++ } ++ } else { ++ // Ensure fingerprint service starts, but do not wait for it ++ this._updateFingerprintReaderType(fprintManager, null).then( ++ () => (this._fprintManager = fprintManager)).catch( ++ e => logError(e, 'Failed to initialize fprintd service')); ++ } ++ } else { ++ this._updateDefaultServiceWithFallback(); ++ } + this._smartcardManager = SmartcardManager.getSmartcardManager(); + + // We check for smartcards right away, since an inserted smartcard +@@ -176,6 +210,7 @@ var ShellUserVerifier = class extends Signals.EventEmitter { + this.reauthenticating = false; + + this._failCounter = 0; ++ this._startedServices = new Set(); + this._unavailableServices = new Set(); + + this._credentialManagers = {}; +@@ -265,6 +300,7 @@ var ShellUserVerifier = class extends Signals.EventEmitter { + + this._clearUserVerifier(); + this._clearMessageQueue(); ++ this._startedServices.clear(); + } + + destroy() { +@@ -385,27 +421,52 @@ var ShellUserVerifier = class extends Signals.EventEmitter { + } + + async _checkForFingerprintReader() { +- this._fingerprintReaderType = FingerprintReaderType.NONE; +- +- if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY) || +- this._fprintManager == null) { +- this._updateDefaultService(); ++ if (!this._fprintManager) { ++ this._updateDefaultServiceWithFallback(); + return; + } + ++ if (this._fingerprintReaderType !== FingerprintReaderType.NONE) ++ return; ++ ++ await this._updateFingerprintReaderType(this._fprintManager, this._cancellable); ++ } ++ ++ async _updateFingerprintReaderType(fprintManager, cancellable) { + try { +- const [device] = await this._fprintManager.GetDefaultDeviceAsync( +- Gio.DBusCallFlags.NONE, this._cancellable); +- const fprintDeviceProxy = new FprintDeviceProxy(Gio.DBus.system, +- 'net.reactivated.Fprint', +- device); +- const fprintDeviceType = fprintDeviceProxy['scan-type']; ++ // Wrappers don't support null cancellable, so let's cheat about it ++ const [devicePath] = await fprintManager.GetDefaultDeviceAsync( ++ cancellable ? cancellable : Gio.DBusCallFlags.NONE); ++ const fprintDeviceProxy = await new Promise((resolve, reject) => { ++ const proxy = new FprintDeviceProxy(Gio.DBus.system, ++ 'net.reactivated.Fprint', devicePath, (_, error) => { ++ if (error) ++ reject(error); ++ else ++ resolve(proxy); ++ }, cancellable, Gio.DBusProxyFlags.NOT_CONNECT_SIGNALS); ++ }); ++ this._setFingerprintReaderType(fprintDeviceProxy['scan-type']); ++ this._updateDefaultServiceWithFallback(); ++ ++ if (this._userVerifier && ++ !this._startedServices.has(FINGERPRINT_SERVICE_NAME)) { ++ if (!this._hold?.isAcquired()) ++ this._hold = new Batch.Hold(); ++ await this._maybeStartFingerprintVerification(); ++ } ++ } catch (e) { ++ if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) ++ logError(e); ++ } ++ } + +- this._fingerprintReaderType = fprintDeviceType === 'swipe' +- ? FingerprintReaderType.SWIPE +- : FingerprintReaderType.PRESS; +- this._updateDefaultService(); +- } catch (e) {} ++ _setFingerprintReaderType(fprintDeviceType) { ++ this._fingerprintReaderType = ++ FingerprintReaderType[fprintDeviceType.toUpperCase()]; ++ ++ if (this._fingerprintReaderType === undefined) ++ throw new Error(`Unexpected fingerprint device type '${fprintDeviceType}'`); + } + + _onCredentialManagerAuthenticated(credentialManager, _token) { +@@ -506,6 +567,7 @@ var ShellUserVerifier = class extends Signals.EventEmitter { + 'problem', this._onProblem.bind(this), + 'info-query', this._onInfoQuery.bind(this), + 'secret-info-query', this._onSecretInfoQuery.bind(this), ++ 'conversation-started', this._onConversationStarted.bind(this), + 'conversation-stopped', this._onConversationStopped.bind(this), + 'service-unavailable', this._onServiceUnavailable.bind(this), + 'reset', this._onReset.bind(this), +@@ -559,6 +621,10 @@ var ShellUserVerifier = class extends Signals.EventEmitter { + this._defaultService = SMARTCARD_SERVICE_NAME; + else if (this._fingerprintReaderType !== FingerprintReaderType.NONE) + this._defaultService = FINGERPRINT_SERVICE_NAME; ++ } ++ ++ _updateDefaultServiceWithFallback() { ++ this._updateDefaultService(); + + if (!this._defaultService) { + log("no authentication service is enabled, using password authentication"); +@@ -597,11 +663,14 @@ var ShellUserVerifier = class extends Signals.EventEmitter { + + _beginVerification() { + this._startService(this._getForegroundService()); ++ this._maybeStartFingerprintVerification(); ++ } + ++ async _maybeStartFingerprintVerification() { + if (this._userName && + this._fingerprintReaderType !== FingerprintReaderType.NONE && + !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME)) +- this._startService(FINGERPRINT_SERVICE_NAME); ++ await this._startService(FINGERPRINT_SERVICE_NAME); + } + + _onChoiceListQuery(client, serviceName, promptMessage, list) { +@@ -694,8 +763,9 @@ var ShellUserVerifier = class extends Signals.EventEmitter { + _onReset() { + // Clear previous attempts to authenticate + this._failCounter = 0; ++ this._startedServices.clear(); + this._unavailableServices.clear(); +- this._updateDefaultService(); ++ this._updateDefaultServiceWithFallback(); + + this.emit('reset'); + } +@@ -776,6 +846,10 @@ var ShellUserVerifier = class extends Signals.EventEmitter { + this._queueMessage(serviceName, errorMessage, MessageType.ERROR); + } + ++ _onConversationStarted(client, serviceName) { ++ this._startedServices.add(serviceName); ++ } ++ + _onConversationStopped(client, serviceName) { + // If the login failed with the preauthenticated oVirt credentials + // then discard the credentials and revert to default authentication diff --git a/debian/patches/global-make-possible-to-set-debug-flags-dynamically.patch b/debian/patches/global-make-possible-to-set-debug-flags-dynamically.patch new file mode 100644 index 0000000..e7746e9 --- /dev/null +++ b/debian/patches/global-make-possible-to-set-debug-flags-dynamically.patch @@ -0,0 +1,237 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Tue, 24 Oct 2017 02:15:13 +0200 +Subject: global: make possible to set debug-flags dynamically + +Adding {set,get}_debug_flags functions to the shell global object to +make possible to set this easily from looking class, making it easier +for developers and users to debug without having to restart the shell +with environment variables. + +Debug flags in main are updated when the "debug-flags" property is +changed. I'm keeping this as a string-list so that it's easier to update. + +https://bugzilla.gnome.org/show_bug.cgi?id=789377 + +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=789377 +Forwarded: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/6 +--- + src/main.c | 57 ++++++++++++++++++++++++++++++++++++++++++------------ + src/shell-global.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ + src/shell-global.h | 4 ++++ + 3 files changed, 101 insertions(+), 12 deletions(-) + +diff --git a/src/main.c b/src/main.c +index d4988e9..a9ea4e9 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -353,14 +353,14 @@ shell_a11y_init (void) + } + + static void +-shell_init_debug (const char *debug_env) ++shell_update_debug (const char *debug_string) + { + static const GDebugKey keys[] = { + { "backtrace-warnings", SHELL_DEBUG_BACKTRACE_WARNINGS }, + { "backtrace-segfaults", SHELL_DEBUG_BACKTRACE_SEGFAULTS }, + }; + +- _shell_debug = g_parse_debug_string (debug_env, keys, ++ _shell_debug = g_parse_debug_string (debug_string, keys, + G_N_ELEMENTS (keys)); + } + +@@ -462,6 +462,42 @@ dump_gjs_stack_on_signal (int signo) + _tracked_signals[signo] = TRUE; + } + ++static void ++reset_signal_handler_to_default (int signo) ++{ ++ signal (signo, SIG_DFL); ++ _tracked_signals[signo] = FALSE; ++} ++ ++static void ++setup_debug_signal_listners (void) ++{ ++ dump_gjs_stack_on_signal (SIGABRT); ++ dump_gjs_stack_on_signal (SIGFPE); ++ dump_gjs_stack_on_signal (SIGIOT); ++ dump_gjs_stack_on_signal (SIGTRAP); ++ ++ if ((_shell_debug & SHELL_DEBUG_BACKTRACE_SEGFAULTS)) ++ { ++ dump_gjs_stack_on_signal (SIGBUS); ++ dump_gjs_stack_on_signal (SIGSEGV); ++ } ++ else ++ { ++ reset_signal_handler_to_default (SIGBUS); ++ reset_signal_handler_to_default (SIGSEGV); ++ } ++} ++ ++static void ++global_notify_debug_flags (GObject *gobject, ++ GParamSpec *pspec, ++ gpointer data) ++{ ++ shell_update_debug (shell_global_get_debug_flags (shell_global_get ())); ++ setup_debug_signal_listners (); ++} ++ + static gboolean + list_modes (const char *option_name, + const char *value, +@@ -585,6 +621,7 @@ main (int argc, char **argv) + { + g_autoptr (MetaContext) context = NULL; + GError *error = NULL; ++ const char *debug_flags; + int ecode = EXIT_SUCCESS; + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); +@@ -622,7 +659,8 @@ main (int argc, char **argv) + g_setenv ("GJS_DEBUG_OUTPUT", "stderr", TRUE); + g_setenv ("GJS_DEBUG_TOPICS", "JS ERROR;JS LOG", TRUE); + +- shell_init_debug (g_getenv ("SHELL_DEBUG")); ++ debug_flags = g_getenv ("SHELL_DEBUG"); ++ shell_update_debug (debug_flags); + + shell_dbus_init (meta_context_is_replacing (context)); + shell_a11y_init (); +@@ -638,18 +676,13 @@ main (int argc, char **argv) + + _shell_global_init ("session-mode", session_mode, + "force-animations", force_animations, ++ "debug-flags", debug_flags, + NULL); + +- dump_gjs_stack_on_signal (SIGABRT); +- dump_gjs_stack_on_signal (SIGFPE); +- dump_gjs_stack_on_signal (SIGIOT); +- dump_gjs_stack_on_signal (SIGTRAP); ++ g_signal_connect (shell_global_get (), "notify::debug-flags", ++ G_CALLBACK (global_notify_debug_flags), NULL); + +- if ((_shell_debug & SHELL_DEBUG_BACKTRACE_SEGFAULTS)) +- { +- dump_gjs_stack_on_signal (SIGBUS); +- dump_gjs_stack_on_signal (SIGSEGV); +- } ++ setup_debug_signal_listners (); + + shell_profiler_init (); + +diff --git a/src/shell-global.c b/src/shell-global.c +index aae9469..e4565b3 100644 +--- a/src/shell-global.c ++++ b/src/shell-global.c +@@ -61,6 +61,7 @@ struct _ShellGlobal { + Display *xdisplay; + + char *session_mode; ++ char *debug_flags; + + XserverRegion input_region; + +@@ -120,6 +121,7 @@ enum { + PROP_FRAME_FINISH_TIMESTAMP, + PROP_SWITCHEROO_CONTROL, + PROP_FORCE_ANIMATIONS, ++ PROP_DEBUG_FLAGS, + + N_PROPS + }; +@@ -249,6 +251,9 @@ shell_global_set_property(GObject *object, + case PROP_FORCE_ANIMATIONS: + global->force_animations = g_value_get_boolean (value); + break; ++ case PROP_DEBUG_FLAGS: ++ shell_global_set_debug_flags (global, g_value_get_string (value)); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -338,6 +343,9 @@ shell_global_get_property(GObject *object, + case PROP_FORCE_ANIMATIONS: + g_value_set_boolean (value, global->force_animations); + break; ++ case PROP_DEBUG_FLAGS: ++ g_value_set_string (value, global->debug_flags); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -688,6 +696,13 @@ shell_global_class_init (ShellGlobalClass *klass) + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT| G_PARAM_STATIC_STRINGS); + ++ props[PROP_DEBUG_FLAGS] = ++ g_param_spec_string ("debug-flags", ++ "Debug Flags", ++ "The debugging flags", ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); ++ + g_object_class_install_properties (gobject_class, N_PROPS, props); + } + +@@ -1988,3 +2003,40 @@ shell_global_get_app_usage (ShellGlobal *global) + global->app_usage = g_object_new (SHELL_TYPE_APP_USAGE, NULL); + return global->app_usage; + } ++ ++/** ++ * shell_global_get_debug_flags: ++ * @global: a #ShellGlobal ++ * ++ * Returns: (transfer none): The current debug flags ++ */ ++const gchar * ++shell_global_get_debug_flags (ShellGlobal *global) ++{ ++ g_return_val_if_fail (SHELL_IS_GLOBAL (global), NULL); ++ ++ return global->debug_flags; ++} ++ ++/** ++ * shell_global_set_debug_flags: ++ * @global: a #ShellGlobal ++ * @debug_flags: (nullable): A string for debugging flags ++ * ++ * Updates the debugging flags at runtime as the one set using the SHELL_DEBUG ++ * environment variables. Currently we support 'backtrace-warnings' and ++ * 'backtrace-segfaults' keys. ++ */ ++void ++shell_global_set_debug_flags (ShellGlobal *global, ++ const char *debug_flags) ++{ ++ g_return_if_fail (SHELL_IS_GLOBAL (global)); ++ ++ if (g_strcmp0 (global->debug_flags, debug_flags) != 0) ++ { ++ g_free (global->debug_flags); ++ global->debug_flags = g_strdup (debug_flags); ++ g_object_notify (G_OBJECT (global), "debug-flags"); ++ } ++} +diff --git a/src/shell-global.h b/src/shell-global.h +index 8399330..683f75a 100644 +--- a/src/shell-global.h ++++ b/src/shell-global.h +@@ -99,6 +99,10 @@ ShellAppSystem * shell_global_get_app_system (ShellGlobal *global); + + ShellAppUsage * shell_global_get_app_usage (ShellGlobal *global); + ++const char * shell_global_get_debug_flags (ShellGlobal *global); ++void shell_global_set_debug_flags (ShellGlobal *global, ++ const char *debug_flags); ++ + G_END_DECLS + + #endif /* __SHELL_GLOBAL_H__ */ diff --git a/debian/patches/magnifier-Show-cursor-when-magnifier-is-enabled-and-scale.patch b/debian/patches/magnifier-Show-cursor-when-magnifier-is-enabled-and-scale.patch new file mode 100644 index 0000000..383500b --- /dev/null +++ b/debian/patches/magnifier-Show-cursor-when-magnifier-is-enabled-and-scale.patch @@ -0,0 +1,172 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Wed, 27 Mar 2019 16:14:39 +0100 +Subject: magnifier: Scale the sprite to match the current monitor scaling + +Compute the sprite texture scale (unfortunately using a workaround, based on +mutter cursor size preferences, tying to figure out the closest texture integer +scaling), and use this value to compute the scaling that should be applied to +the sprite in order to match the current monitor scaling. + +Origin: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/475 +Applied-Upstream: no +Forwarded: yes +--- + js/ui/layout.js | 24 ++++++++++++++++++++---- + js/ui/magnifier.js | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 73 insertions(+), 6 deletions(-) + +diff --git a/js/ui/layout.js b/js/ui/layout.js +index d7f73dc..e53ff9d 100644 +--- a/js/ui/layout.js ++++ b/js/ui/layout.js +@@ -974,22 +974,38 @@ var LayoutManager = GObject.registerClass({ + return ws.get_work_area_for_monitor(monitorIndex); + } + ++ _findIndexForRect(x, y, width, height) { ++ let rect = new Meta.Rectangle({ ++ x: Math.floor(x), ++ y: Math.floor(y), ++ width: Math.ceil(x + width) - Math.floor(x), ++ height: Math.ceil(y + height) - Math.floor(y) ++ }); ++ return global.display.get_monitor_index_for_rect(rect); ++ } ++ + // This call guarantees that we return some monitor to simplify usage of it + // In practice all tracked actors should be visible on some monitor anyway + findIndexForActor(actor) { + let [x, y] = actor.get_transformed_position(); + let [w, h] = actor.get_transformed_size(); +- let rect = new Meta.Rectangle({ x, y, width: w, height: h }); +- return global.display.get_monitor_index_for_rect(rect); ++ return this._findIndexForRect(x, y, w, h); + } + +- findMonitorForActor(actor) { +- let index = this.findIndexForActor(actor); ++ _findMonitorForIndex(index) { + if (index >= 0 && index < this.monitors.length) + return this.monitors[index]; + return null; + } + ++ findMonitorForActor(actor) { ++ return this._findMonitorForIndex(this.findIndexForActor(actor)); ++ } ++ ++ findMonitorForPoint(x, y) { ++ return this._findMonitorForIndex(this._findIndexForRect(x, y, 1, 1)); ++ } ++ + _queueUpdateRegions() { + if (!this._updateRegionIdle) { + const laters = global.compositor.get_laters(); +diff --git a/js/ui/magnifier.js b/js/ui/magnifier.js +index f4012de..f8d235f 100644 +--- a/js/ui/magnifier.js ++++ b/js/ui/magnifier.js +@@ -46,6 +46,8 @@ var MouseSpriteContent = GObject.registerClass({ + }, class MouseSpriteContent extends GObject.Object { + _init() { + super._init(); ++ this._scale = 1.0; ++ this._monitorScale = 1.0; + this._texture = null; + } + +@@ -53,7 +55,10 @@ var MouseSpriteContent = GObject.registerClass({ + if (!this._texture) + return [false, 0, 0]; + +- return [true, this._texture.get_width(), this._texture.get_height()]; ++ let width = this._texture.get_width() / this._scale; ++ let height = this._texture.get_height() / this._scale; ++ ++ return [true, width, height]; + } + + vfunc_paint_content(actor, node, _paintContext) { +@@ -70,6 +75,29 @@ var MouseSpriteContent = GObject.registerClass({ + textureNode.add_rectangle(actor.get_content_box()); + } + ++ _textureScale() { ++ if (!this._texture) ++ return 1; ++ ++ /* This is a workaround to guess the sprite scale; while it works file ++ * in normal scenarios, it's not guaranteed to work in all the cases, ++ * and so we should actually add an API to mutter that will allow us ++ * to know the real spirte texture scaling in order to adapt it to the ++ * wanted one. */ ++ let avgSize = (this._texture.get_width() + this._texture.get_height()) / 2; ++ return Math.max (1, Math.floor (avgSize / Meta.prefs_get_cursor_size() + .1)); ++ } ++ ++ _recomputeScale() { ++ let scale = this._textureScale() / this._monitorScale; ++ ++ if (this._scale != scale) { ++ this._scale = scale; ++ return true; ++ } ++ return false; ++ } ++ + get texture() { + return this._texture; + } +@@ -84,7 +112,19 @@ var MouseSpriteContent = GObject.registerClass({ + + if (!oldTexture || !coglTexture || + oldTexture.get_width() != coglTexture.get_width() || +- oldTexture.get_height() != coglTexture.get_height()) ++ oldTexture.get_height() != coglTexture.get_height()) { ++ this._recomputeScale(); ++ this.invalidate_size(); ++ } ++ } ++ ++ get scale() { ++ return this._scale; ++ } ++ ++ set monitorScale(monitorScale) { ++ this._monitorScale = monitorScale; ++ if (this._recomputeScale()) + this.invalidate_size(); + } + }); +@@ -113,6 +153,8 @@ var Magnifier = class Magnifier extends Signals.EventEmitter { + this._settingsInit(aZoomRegion); + aZoomRegion.scrollContentsTo(this.xMouse, this.yMouse); + ++ this._updateContentScale(); ++ + St.Settings.get().connect('notify::magnifier-active', () => { + this.setActive(St.Settings.get().magnifier_active); + }); +@@ -120,6 +162,13 @@ var Magnifier = class Magnifier extends Signals.EventEmitter { + this.setActive(St.Settings.get().magnifier_active); + } + ++ _updateContentScale() { ++ let monitor = Main.layoutManager.findMonitorForPoint(this.xMouse, ++ this.yMouse); ++ this._mouseSprite.content.monitorScale = monitor ? ++ monitor.geometry_scale : 1; ++ } ++ + /** + * showSystemCursor: + * Show the system mouse pointer. +@@ -256,6 +305,8 @@ var Magnifier = class Magnifier extends Signals.EventEmitter { + this.xMouse = xMouse; + this.yMouse = yMouse; + ++ this._updateContentScale(); ++ + let sysMouseOverAny = false; + this._zoomRegions.forEach(zoomRegion => { + if (zoomRegion.scrollToMousePos()) diff --git a/debian/patches/main-add-backtrace-crashes-all-and-backtrace-all.patch b/debian/patches/main-add-backtrace-crashes-all-and-backtrace-all.patch new file mode 100644 index 0000000..02fd8f2 --- /dev/null +++ b/debian/patches/main-add-backtrace-crashes-all-and-backtrace-all.patch @@ -0,0 +1,47 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Thu, 2 Aug 2018 16:17:39 +0200 +Subject: main: add `backtrace-crashes-all` and `backtrace-all` + +These are just convenient aliases to not to have to list all the types, +as having more granularity is cool, but it might also cause some annoyance. + +https://bugzilla.gnome.org/show_bug.cgi?id=789377 + +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=789377 +Forwarded: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/6 +--- + src/main.c | 7 +++++++ + src/shell-global.c | 2 ++ + 2 files changed, 9 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 0d56b23..88d0513 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -55,6 +55,13 @@ static const GDebugKey SHELL_DEBUG_KEYS[] = { + { "backtrace-segfaults", SHELL_DEBUG_BACKTRACE_SEGFAULTS }, + { "backtrace-aborts", SHELL_DEBUG_BACKTRACE_ABORTS }, + { "backtrace-math-errors", SHELL_DEBUG_BACKTRACE_FPE }, ++ { "backtrace-crashes-all", SHELL_DEBUG_BACKTRACE_SEGFAULTS | ++ SHELL_DEBUG_BACKTRACE_ABORTS | ++ SHELL_DEBUG_BACKTRACE_FPE }, ++ { "backtrace-all", SHELL_DEBUG_BACKTRACE_WARNINGS | ++ SHELL_DEBUG_BACKTRACE_SEGFAULTS | ++ SHELL_DEBUG_BACKTRACE_ABORTS | ++ SHELL_DEBUG_BACKTRACE_FPE }, + }; + static int _default_debug_flags = SHELL_DEBUG_BACKTRACE_ABORTS | + SHELL_DEBUG_BACKTRACE_FPE; +diff --git a/src/shell-global.c b/src/shell-global.c +index b6e9ef9..f34dc3b 100644 +--- a/src/shell-global.c ++++ b/src/shell-global.c +@@ -2029,6 +2029,8 @@ shell_global_get_debug_flags (ShellGlobal *global) + * - 'backtrace-segfaults' + * - 'backtrace-aborts' + * - 'backtrace-math-errors' ++ * - 'backtrace-crashes-all' ++ * - 'backtrace-all' + * - 'all' + */ + void diff --git a/debian/patches/main-increase-the-granularity-of-backtraces-in-SHELL_DEBU.patch b/debian/patches/main-increase-the-granularity-of-backtraces-in-SHELL_DEBU.patch new file mode 100644 index 0000000..cd1030e --- /dev/null +++ b/debian/patches/main-increase-the-granularity-of-backtraces-in-SHELL_DEBU.patch @@ -0,0 +1,169 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Tue, 24 Oct 2017 03:20:34 +0200 +Subject: main: increase the granularity of backtraces in SHELL_DEBUG + +Add support for multiple debug-keys for getting the backtraces, +allowing more control using both SHELL_DEBUG and/or set_debug_flags + +https://bugzilla.gnome.org/show_bug.cgi?id=789377 + +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=789377 +Forwarded: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/6 +--- + src/main.c | 76 +++++++++++++++++++++++++++++++++++++++++------------- + src/shell-global.c | 10 ++++--- + 2 files changed, 65 insertions(+), 21 deletions(-) + +diff --git a/src/main.c b/src/main.c +index a9ea4e9..0d56b23 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -39,16 +39,26 @@ static gboolean is_gdm_mode = FALSE; + static char *session_mode = NULL; + static int caught_signal = 0; + static gboolean force_animations = FALSE; ++static gboolean _tracked_signals[NSIG] = { 0 }; + + #define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 + #define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 + + enum { +- SHELL_DEBUG_BACKTRACE_WARNINGS = 1, +- SHELL_DEBUG_BACKTRACE_SEGFAULTS = 2, ++ SHELL_DEBUG_BACKTRACE_WARNINGS = (1 << 0), ++ SHELL_DEBUG_BACKTRACE_SEGFAULTS = (1 << 1), ++ SHELL_DEBUG_BACKTRACE_ABORTS = (1 << 2), ++ SHELL_DEBUG_BACKTRACE_FPE = (1 << 3), + }; +-static int _shell_debug; +-static gboolean _tracked_signals[NSIG] = { 0 }; ++static const GDebugKey SHELL_DEBUG_KEYS[] = { ++ { "backtrace-warnings", SHELL_DEBUG_BACKTRACE_WARNINGS }, ++ { "backtrace-segfaults", SHELL_DEBUG_BACKTRACE_SEGFAULTS }, ++ { "backtrace-aborts", SHELL_DEBUG_BACKTRACE_ABORTS }, ++ { "backtrace-math-errors", SHELL_DEBUG_BACKTRACE_FPE }, ++}; ++static int _default_debug_flags = SHELL_DEBUG_BACKTRACE_ABORTS | ++ SHELL_DEBUG_BACKTRACE_FPE; ++static int _shell_debug = 0; + + static void + shell_dbus_acquire_name (GDBusProxy *bus, +@@ -355,13 +365,23 @@ shell_a11y_init (void) + static void + shell_update_debug (const char *debug_string) + { +- static const GDebugKey keys[] = { +- { "backtrace-warnings", SHELL_DEBUG_BACKTRACE_WARNINGS }, +- { "backtrace-segfaults", SHELL_DEBUG_BACKTRACE_SEGFAULTS }, +- }; ++ _shell_debug = g_parse_debug_string (debug_string, SHELL_DEBUG_KEYS, ++ G_N_ELEMENTS (SHELL_DEBUG_KEYS)); ++} ++ ++static char * ++debug_flags_to_string (void) ++{ ++ gsize i, j; ++ const char *enabled_flags[G_N_ELEMENTS (SHELL_DEBUG_KEYS) + 1] = { 0 }; ++ ++ for (i = 0, j = 0; i < G_N_ELEMENTS (SHELL_DEBUG_KEYS); ++i) ++ { ++ if ((_shell_debug & SHELL_DEBUG_KEYS[i].value)) ++ enabled_flags[j++] = SHELL_DEBUG_KEYS[i].key; ++ } + +- _shell_debug = g_parse_debug_string (debug_string, keys, +- G_N_ELEMENTS (keys)); ++ return g_strjoinv (":", (char**) enabled_flags); + } + + static GLogWriterOutput +@@ -472,10 +492,23 @@ reset_signal_handler_to_default (int signo) + static void + setup_debug_signal_listners (void) + { +- dump_gjs_stack_on_signal (SIGABRT); +- dump_gjs_stack_on_signal (SIGFPE); +- dump_gjs_stack_on_signal (SIGIOT); +- dump_gjs_stack_on_signal (SIGTRAP); ++ if ((_shell_debug & SHELL_DEBUG_BACKTRACE_ABORTS)) ++ { ++ dump_gjs_stack_on_signal (SIGABRT); ++ dump_gjs_stack_on_signal (SIGIOT); ++ dump_gjs_stack_on_signal (SIGTRAP); ++ } ++ else ++ { ++ reset_signal_handler_to_default (SIGABRT); ++ reset_signal_handler_to_default (SIGIOT); ++ reset_signal_handler_to_default (SIGTRAP); ++ } ++ ++ if ((_shell_debug & SHELL_DEBUG_BACKTRACE_FPE)) ++ dump_gjs_stack_on_signal (SIGFPE); ++ else ++ reset_signal_handler_to_default (SIGFPE); + + if ((_shell_debug & SHELL_DEBUG_BACKTRACE_SEGFAULTS)) + { +@@ -620,8 +653,9 @@ int + main (int argc, char **argv) + { + g_autoptr (MetaContext) context = NULL; ++ g_autofree char *debug_flags_string = NULL; + GError *error = NULL; +- const char *debug_flags; ++ const char *shell_debug; + int ecode = EXIT_SUCCESS; + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); +@@ -659,8 +693,14 @@ main (int argc, char **argv) + g_setenv ("GJS_DEBUG_OUTPUT", "stderr", TRUE); + g_setenv ("GJS_DEBUG_TOPICS", "JS ERROR;JS LOG", TRUE); + +- debug_flags = g_getenv ("SHELL_DEBUG"); +- shell_update_debug (debug_flags); ++ shell_debug = g_getenv ("SHELL_DEBUG"); ++ ++ if (shell_debug) ++ shell_update_debug (shell_debug); ++ else ++ _shell_debug = _default_debug_flags; ++ ++ debug_flags_string = debug_flags_to_string (); + + shell_dbus_init (meta_context_is_replacing (context)); + shell_a11y_init (); +@@ -676,7 +716,7 @@ main (int argc, char **argv) + + _shell_global_init ("session-mode", session_mode, + "force-animations", force_animations, +- "debug-flags", debug_flags, ++ "debug-flags", debug_flags_string, + NULL); + + g_signal_connect (shell_global_get (), "notify::debug-flags", +diff --git a/src/shell-global.c b/src/shell-global.c +index e4565b3..b6e9ef9 100644 +--- a/src/shell-global.c ++++ b/src/shell-global.c +@@ -2021,11 +2021,15 @@ shell_global_get_debug_flags (ShellGlobal *global) + /** + * shell_global_set_debug_flags: + * @global: a #ShellGlobal +- * @debug_flags: (nullable): A string for debugging flags ++ * @debug_flags: (nullable): A comma-separated string of debugging flags + * + * Updates the debugging flags at runtime as the one set using the SHELL_DEBUG +- * environment variables. Currently we support 'backtrace-warnings' and +- * 'backtrace-segfaults' keys. ++ * environment variables. Currently we support these keys: ++ * - 'backtrace-warnings' ++ * - 'backtrace-segfaults' ++ * - 'backtrace-aborts' ++ * - 'backtrace-math-errors' ++ * - 'all' + */ + void + shell_global_set_debug_flags (ShellGlobal *global, diff --git a/debian/patches/main-show-an-error-message-on-gnome-shell-crash.patch b/debian/patches/main-show-an-error-message-on-gnome-shell-crash.patch new file mode 100644 index 0000000..c8d2a11 --- /dev/null +++ b/debian/patches/main-show-an-error-message-on-gnome-shell-crash.patch @@ -0,0 +1,30 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Thu, 2 Aug 2018 15:59:20 +0200 +Subject: main: show an error message on gnome-shell crash + +When we call the crash signal handler, write on log the reason of the +crash, also to make easier to parse the logs later on, and being able +to understand if a stacktrace is coming from a crash or a different +gjs error. + +https://bugzilla.gnome.org/show_bug.cgi?id=789377 + +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=789377 +Forwarded: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/6 +--- + src/main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/main.c b/src/main.c +index e81f92c..d4988e9 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -423,6 +423,8 @@ dump_gjs_stack_on_signal_handler (int signo) + struct sigaction sa = { .sa_handler = dump_gjs_stack_alarm_sigaction }; + gsize i; + ++ g_printerr ("GNOME Shell crashed with signal %d\n", signo); ++ + /* Ignore all the signals starting this point, a part the one we'll raise + * (which is implicitly ignored here through SA_RESETHAND), this is needed + * not to get this handler being called by other signals that we were diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..ad4e89d --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,27 @@ +debian/gnome-shell-extension-prefs-Give-Debian-specific-advice.patch +debian/Revert-build-Port-to-gcr4.patch +debian/Revert-tests-Fail-on-warnings-too.patch +gdm-util-Only-start-fingerprint-service-synchronously-whe.patch +ubuntu/desktop_detect.patch +ubuntu/lightdm-user-switching.patch +ubuntu/lock_on_suspend.patch +ubuntu/background_login.patch +ubuntu/gdm_alternatives.patch +main-show-an-error-message-on-gnome-shell-crash.patch +global-make-possible-to-set-debug-flags-dynamically.patch +main-increase-the-granularity-of-backtraces-in-SHELL_DEBU.patch +main-add-backtrace-crashes-all-and-backtrace-all.patch +sessionMode-add-support-for-debugFlags-parameter.patch +magnifier-Show-cursor-when-magnifier-is-enabled-and-scale.patch +ubuntu/search-call-XUbuntuCancel-method-on-providers-when-no-dat.patch +ubuntu/resolve_alternate_theme_path.patch +ubuntu/secure_mode_extension.patch +ubuntu/keep-ubuntu-logo-bright-lp1867133-v1.patch +ubuntu/configure_login_screen.patch +ubuntu/layout-Try-to-allocate-before-getting-size-of-tracke.patch +Revert-st-Apply-css-foreground-color-to-text-as-a-PangoAt.patch +ubuntu/sessionMode-Add-support-for-configuring-an-icons-resource.patch +ubuntu/Revert-dash-Use-pin-instead-of-favorites.patch +ubuntu/main-Support-loading-multiple-Yaru-theme-variants.patch +ubuntu/darkMode-Add-support-to-Yaru-theme-color-variants.patch +ubuntu/shell-global-util-Do-not-move-snap-apps-to-gnome-apps-sco.patch diff --git a/debian/patches/sessionMode-add-support-for-debugFlags-parameter.patch b/debian/patches/sessionMode-add-support-for-debugFlags-parameter.patch new file mode 100644 index 0000000..3649b26 --- /dev/null +++ b/debian/patches/sessionMode-add-support-for-debugFlags-parameter.patch @@ -0,0 +1,46 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Thu, 2 Aug 2018 16:05:13 +0200 +Subject: sessionMode: add support for `debugFlags` parameter + +A session can now define `debugFlags` from a json file, still leaving priority +to the environment variable. + +https://bugzilla.gnome.org/show_bug.cgi?id=789377 + +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=789377 +Forwarded: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/6 +--- + js/ui/main.js | 7 +++++++ + js/ui/sessionMode.js | 1 + + 2 files changed, 8 insertions(+) + +diff --git a/js/ui/main.js b/js/ui/main.js +index 6ecb1a0..5c3cb8e 100644 +--- a/js/ui/main.js ++++ b/js/ui/main.js +@@ -139,6 +139,13 @@ function _sessionUpdated() { + _remoteAccessInhibited = true; + } + } ++ ++ if (!GLib.getenv('SHELL_DEBUG')) { ++ if (typeof sessionMode.debugFlags === 'string') ++ global.set_debug_flags(sessionMode.debugFlags); ++ else if (Array.isArray(sessionMode.debugFlags)) ++ global.set_debug_flags(sessionMode.debugFlags.join(':')) ++ } + } + + /** +diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js +index 7831646..5478b2a 100644 +--- a/js/ui/sessionMode.js ++++ b/js/ui/sessionMode.js +@@ -29,6 +29,7 @@ const _modes = { + showWelcomeDialog: false, + allowSettings: false, + allowScreencast: false, ++ debugFlags: [], + enabledExtensions: [], + hasRunDialog: false, + hasWorkspaces: false, diff --git a/debian/patches/ubuntu/Revert-dash-Use-pin-instead-of-favorites.patch b/debian/patches/ubuntu/Revert-dash-Use-pin-instead-of-favorites.patch new file mode 100644 index 0000000..1f9cde6 --- /dev/null +++ b/debian/patches/ubuntu/Revert-dash-Use-pin-instead-of-favorites.patch @@ -0,0 +1,90 @@ +From: Gunnar Hjalmarsson +Date: Mon, 11 Apr 2022 21:10:37 +0200 +Subject: Revert "dash: Use pin instead of favorites" + +This effectively reverts this commit when using the ubuntu session: +https://gitlab.gnome.org/GNOME/gnome-shell/-/commit/a67877f5 + +We do that as a temporary measure in Ubuntu 22.04 in order to address +a translation issue. The issue was reported by Mitsuya Shibata: + +* https://github.com/micheleg/dash-to-dock/issues/1697 + +* https://lists.ubuntu.com/archives/ubuntu-translators/2022-April/007829.html + +In short: By using the old labels for those menu items, we can make use +of existing gnome-shell translations in Launchpad both for gnome-shell +and ubuntu-dock. Thanks Jeremy Bicha for the idea! + +So even if it technically introduces new translatable strings very late, +it does not break the UIF spirit. + +Forwarded: not-needed +--- + js/ui/appFavorites.js | 12 ++++++++++-- + js/ui/appMenu.js | 5 +++-- + js/ui/dash.js | 3 +-- + 3 files changed, 14 insertions(+), 6 deletions(-) + +diff --git a/js/ui/appFavorites.js b/js/ui/appFavorites.js +index ca65695..93b8e24 100644 +--- a/js/ui/appFavorites.js ++++ b/js/ui/appFavorites.js +@@ -164,7 +164,11 @@ class AppFavorites extends Signals.EventEmitter { + + let app = Shell.AppSystem.get_default().lookup_app(appId); + +- let msg = _('%s has been pinned to the dash.').format(app.get_name()); ++ let msg; ++ if (imports.misc.desktop.is('ubuntu')) ++ msg = _('%s has been added to your favorites.').format(app.get_name()); ++ else ++ msg = _('%s has been pinned to the dash.').format(app.get_name()); + Main.overview.setMessage(msg, { + forFeedback: true, + undoCallback: () => this._removeFavorite(appId), +@@ -197,7 +201,11 @@ class AppFavorites extends Signals.EventEmitter { + if (!this._removeFavorite(appId)) + return; + +- let msg = _('%s has been unpinned from the dash.').format(app.get_name()); ++ let msg; ++ if (imports.misc.desktop.is('ubuntu')) ++ msg = _('%s has been removed from your favorites.').format(app.get_name()); ++ else ++ msg = _('%s has been unpinned from the dash.').format(app.get_name()); + Main.overview.setMessage(msg, { + forFeedback: true, + undoCallback: () => this._addFavorite(appId, pos), +diff --git a/js/ui/appMenu.js b/js/ui/appMenu.js +index fec74cf..37f8012 100644 +--- a/js/ui/appMenu.js ++++ b/js/ui/appMenu.js +@@ -153,9 +153,10 @@ var AppMenu = class AppMenu extends PopupMenu.PopupMenu { + return; + + const { id } = this._app; ++ const isUbuntu = imports.misc.desktop.is('ubuntu'); + this._toggleFavoriteItem.label.text = this._appFavorites.isFavorite(id) +- ? _('Unpin') +- : _('Pin to Dash'); ++ ? (isUbuntu ? _('Remove from Favorites') : _('Unpin')) ++ : (isUbuntu ? _('Add to Favorites') : _('Pin to Dash')); + } + + _updateGpuItem() { +diff --git a/js/ui/dash.js b/js/ui/dash.js +index 1883088..e7cbe67 100644 +--- a/js/ui/dash.js ++++ b/js/ui/dash.js +@@ -245,9 +245,8 @@ class ShowAppsIcon extends DashItemContainer { + this.toggleButton.set_hover(canRemove); + if (this._iconActor) + this._iconActor.set_hover(canRemove); +- + if (canRemove) +- this.setLabelText(_('Unpin')); ++ this.setLabelText(imports.misc.desktop.is('ubuntu') ? _('Remove from Favorites') : _('Unpin')); + else + this.setLabelText(_('Show Apps')); + } diff --git a/debian/patches/ubuntu/background_login.patch b/debian/patches/ubuntu/background_login.patch new file mode 100644 index 0000000..e5f9566 --- /dev/null +++ b/debian/patches/ubuntu/background_login.patch @@ -0,0 +1,39 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Tue, 10 Sep 2019 13:13:14 +0100 +Subject: js/ui/background.js: Match theme login screen color + +This way the login animation will appear to expand over the login +screen (system background) instead of suddenly replacing it. + +Original author: Didier Roche +Original author: Daniel van Vugt +Author: Marco Trevisan + +Last-Update: 2022-08-30 +Forwarded: not-needed +--- + js/ui/background.js | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index a1f6601..4717f46 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -528,7 +528,16 @@ var SystemBackground = GObject.registerClass({ + _init() { + if (_systemBackground == null) { + _systemBackground = new Meta.Background({ meta_display: global.display }); +- _systemBackground.set_color(DEFAULT_BACKGROUND_COLOR); ++ ++ let backgroundColor = DEFAULT_BACKGROUND_COLOR; ++ if (imports.misc.desktop.is("ubuntu")) { ++ const dummyBgActor = new imports.gi.St.Widget({ name: 'lockDialogGroup' }); ++ Main.uiGroup.add_actor(dummyBgActor); ++ backgroundColor = dummyBgActor.get_theme_node().get_background_color(); ++ dummyBgActor.destroy(); ++ } ++ ++ _systemBackground.set_color(backgroundColor); + } + + super._init({ diff --git a/debian/patches/ubuntu/configure_login_screen.patch b/debian/patches/ubuntu/configure_login_screen.patch new file mode 100644 index 0000000..28b0b59 --- /dev/null +++ b/debian/patches/ubuntu/configure_login_screen.patch @@ -0,0 +1,199 @@ +From: Ubuntu Developers +Date: Thu, 11 Mar 2021 10:12:06 +0200 +Subject: Allow configuring login screen background + +Configuring login screen backgound and properties is a recurring request +especially on corporate environment. +Allows to override the default embedded style in the theme with specific +gsettings keys. +Forwarded: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/680 +Bug: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1918613 +Origin: ubuntu +--- + data/com.ubuntu.login-screen.gschema.xml.in | 70 +++++++++++++++++++++++++++++ + data/meson.build | 8 +++- + js/ui/background.js | 4 ++ + js/ui/screenShield.js | 37 +++++++++++++++ + 4 files changed, 118 insertions(+), 1 deletion(-) + create mode 100644 data/com.ubuntu.login-screen.gschema.xml.in + +diff --git a/data/com.ubuntu.login-screen.gschema.xml.in b/data/com.ubuntu.login-screen.gschema.xml.in +new file mode 100644 +index 0000000..ee8b3a2 +--- /dev/null ++++ b/data/com.ubuntu.login-screen.gschema.xml.in +@@ -0,0 +1,70 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ '' ++ ++ Sets the background image for the login screen. ++ ++ ++ URI to use for the background image. Note that the backend only ++ supports local (file://) URIs. ++ It overrides the value defined in the default style sheet. ++ ++ ++ ++ '' ++ ++ The background-color property sets the background color. ++ ++ ++ The background-color property sets the background color to use when ++ the background picture URI is missing or when it doesn't cover the whole background. ++ It overrides the value defined in the default style sheet. ++ ++ ++ ++ 'default' ++ ++ The background-repeat property sets if/how the background image will be repeated. ++ ++ ++ The background-repeat property sets if/how a background image will be repeated. ++ By default, a background-image is repeated both vertically and horizontally. ++ ++ It overrides the value defined in the default style sheet. ++ ++ ++ ++ 'default' ++ ++ The background-size property specifies the size of the background image. ++ ++ ++ The background-size property specifies the size of the background images. ++ ++ There are three keywords you can use with this property: ++ auto: The background image is displayed in its original size; ++ cover: Resize the background image to cover the entire container, even if it has to stretch the image or cut a little bit off one of the edges; ++ contain: Resize the background image to make sure the image is fully visible. ++ ++ It overrides the value defined in the default style sheet. ++ ++ ++ ++ +diff --git a/data/meson.build b/data/meson.build +index a31efcc..07d6d4a 100644 +--- a/data/meson.build ++++ b/data/meson.build +@@ -97,6 +97,12 @@ schema = configure_file( + configuration: schemaconf, + install_dir: schemadir + ) ++schema_ubuntu_login = configure_file( ++ input: 'com.ubuntu.login-screen.gschema.xml.in', ++ output: 'com.ubuntu.login-screen.gschema.xml', ++ configuration: schemaconf, ++ install_dir: schemadir ++) + install_data('00_org.gnome.shell.gschema.override', install_dir: schemadir) + + if have_systemd +@@ -125,7 +131,7 @@ endif + + # for unit tests - gnome.compile_schemas() only looks in srcdir + custom_target('compile-schemas', +- input: schema, ++ input: [schema, schema_ubuntu_login], + output: 'gschemas.compiled', + command: [find_program('glib-compile-schemas'), data_builddir], + build_by_default: true) +diff --git a/js/ui/background.js b/js/ui/background.js +index 4717f46..a5be402 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -531,7 +531,11 @@ var SystemBackground = GObject.registerClass({ + + let backgroundColor = DEFAULT_BACKGROUND_COLOR; + if (imports.misc.desktop.is("ubuntu")) { ++ const loginSettings = new Gio.Settings({ schema_id: 'com.ubuntu.login-screen' }); ++ const bgColor = loginSettings.get_string('background-color'); + const dummyBgActor = new imports.gi.St.Widget({ name: 'lockDialogGroup' }); ++ if (bgColor) ++ dummyBgActor.set_style(`background-color: ${bgColor};`); + Main.uiGroup.add_actor(dummyBgActor); + backgroundColor = dummyBgActor.get_theme_node().get_background_color(); + dummyBgActor.destroy(); +diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js +index 038c1df..df542d0 100644 +--- a/js/ui/screenShield.js ++++ b/js/ui/screenShield.js +@@ -29,6 +29,12 @@ const DISABLE_LOCK_KEY = 'disable-lock-screen'; + + const LOCKED_STATE_STR = 'screenShield.locked'; + ++const LOGIN_SCREEN_SCHEMA = 'com.ubuntu.login-screen'; ++const LOGIN_SCREEN_BACKGROUND_COLOR_KEY = 'background-color'; ++const LOGIN_SCREEN_BACKGROUND_PICTURE_URI_KEY = 'background-picture-uri'; ++const LOGIN_SCREEN_BACKGROUND_REPEAT_KEY = 'background-repeat'; ++const LOGIN_SCREEN_BACKGROUND_SIZE_KEY = 'background-size'; ++ + // ScreenShield animation time + // - STANDARD_FADE_TIME is used when the session goes idle + // - MANUAL_FADE_TIME is used for lowering the shield when asked by the user, +@@ -112,6 +118,16 @@ var ScreenShield = class extends Signals.EventEmitter { + this._lockSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA }); + this._lockSettings.connect(`changed::${DISABLE_LOCK_KEY}`, this._syncInhibitor.bind(this)); + ++ this._loginScreenSettings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA }); ++ [ ++ LOGIN_SCREEN_BACKGROUND_COLOR_KEY, ++ LOGIN_SCREEN_BACKGROUND_PICTURE_URI_KEY, ++ LOGIN_SCREEN_BACKGROUND_REPEAT_KEY, ++ LOGIN_SCREEN_BACKGROUND_SIZE_KEY, ++ ].forEach(schema => this._loginScreenSettings.connect(`changed::${schema}`, ++ () => this._refreshBackground())); ++ this._refreshBackground(); ++ + this._isModal = false; + this._isGreeter = false; + this._isActive = false; +@@ -212,6 +228,27 @@ var ScreenShield = class extends Signals.EventEmitter { + return this._isModal; + } + ++ _refreshBackground() { ++ const inlineStyle = []; ++ ++ const getSetting = s => this._loginScreenSettings.get_string(s); ++ const backgroundColor = getSetting(LOGIN_SCREEN_BACKGROUND_COLOR_KEY); ++ const backgroundPictureUri = getSetting(LOGIN_SCREEN_BACKGROUND_PICTURE_URI_KEY); ++ const backgroundRepeat = getSetting(LOGIN_SCREEN_BACKGROUND_REPEAT_KEY); ++ const backgroundSize = getSetting(LOGIN_SCREEN_BACKGROUND_SIZE_KEY); ++ ++ if (backgroundColor) ++ inlineStyle.push(`background-color: ${backgroundColor}`); ++ if (backgroundPictureUri) ++ inlineStyle.push(`background-image: url("${backgroundPictureUri}")`); ++ if (backgroundRepeat !== 'default') ++ inlineStyle.push(`background-repeat: ${backgroundRepeat}`); ++ if (backgroundSize !== 'default') ++ inlineStyle.push(`background-size: ${backgroundSize}`); ++ ++ this._lockDialogGroup.set_style(inlineStyle.join('; ')); ++ } ++ + async _syncInhibitor() { + const lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY) || + this._settings.get_boolean(SUSPEND_LOCK_ENABLED_KEY); diff --git a/debian/patches/ubuntu/darkMode-Add-support-to-Yaru-theme-color-variants.patch b/debian/patches/ubuntu/darkMode-Add-support-to-Yaru-theme-color-variants.patch new file mode 100644 index 0000000..c720f0e --- /dev/null +++ b/debian/patches/ubuntu/darkMode-Add-support-to-Yaru-theme-color-variants.patch @@ -0,0 +1,81 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Wed, 24 Aug 2022 19:15:36 +0200 +Subject: darkMode: Add support to Yaru theme color variants + +Support switching to dark mode when using the Yaru theme color accents. +--- + js/ui/status/darkMode.js | 43 +++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 41 insertions(+), 2 deletions(-) + +diff --git a/js/ui/status/darkMode.js b/js/ui/status/darkMode.js +index d4620f0..cf6fcf1 100644 +--- a/js/ui/status/darkMode.js ++++ b/js/ui/status/darkMode.js +@@ -1,5 +1,5 @@ + /* exported Indicator */ +-const {Gio, GObject} = imports.gi; ++const {Gio, GObject, St} = imports.gi; + + const Main = imports.ui.main; + const {QuickToggle, SystemIndicator} = imports.ui.quickSettings; +@@ -18,6 +18,9 @@ class DarkModeToggle extends QuickToggle { + this._changedId = this._settings.connect('changed::color-scheme', + () => this._sync()); + ++ St.Settings.get().connect('notify::gtk-theme', () => this._sync()); ++ St.Settings.get().connect('notify::gtk-theme-variant', () => this._sync()); ++ + this.connectObject( + 'destroy', () => this._settings.run_dispose(), + 'clicked', () => this._toggleMode(), +@@ -27,13 +30,49 @@ class DarkModeToggle extends QuickToggle { + + _toggleMode() { + Main.layoutManager.screenTransition.run(); ++ const preferDark = !this.checked; ++ const {gtkTheme, gtkThemeVariant} = St.Settings.get(); ++ const themeVariant = gtkThemeVariant?.toLowerCase(); + this._settings.set_string('color-scheme', + this.checked ? 'default' : 'prefer-dark'); ++ ++ if (gtkTheme === 'Yaru') ++ this._setYaruSettings(themeVariant, preferDark); ++ } ++ ++ _setYaruSettings(themeVariant, preferDark) { ++ const currentlyDark = themeVariant === 'dark' || themeVariant?.endsWith('-dark'); ++ if (currentlyDark) ++ themeVariant = themeVariant.slice(0, -'-dark'.length); ++ ++ if (currentlyDark !== preferDark) { ++ const newTheme = `Yaru${ ++ themeVariant ? `-${themeVariant}` : ''}${ ++ preferDark ? '-dark' : ''}`; ++ ++ this._settings.set_string('gtk-theme', newTheme); ++ this._settings.set_string('icon-theme', newTheme); ++ } ++ ++ const schemaSource = Gio.SettingsSchemaSource.get_default(); ++ const geditSchema = schemaSource.lookup('org.gnome.gedit.preferences.editor', true); ++ ++ if (geditSchema) { ++ const geditSettings = Gio.Settings.new_full(geditSchema, null, null); ++ const geditScheme = geditSettings.get_user_value('scheme')?.unpack(); ++ ++ if (geditScheme?.startsWith('Yaru') && ++ geditScheme.endsWith('-dark') !== preferDark) ++ geditSettings.set_string('scheme', `Yaru${preferDark ? '-dark' : ''}`); ++ } + } + + _sync() { + const colorScheme = this._settings.get_string('color-scheme'); +- const checked = colorScheme === 'prefer-dark'; ++ const {gtkTheme, gtkThemeVariant} = St.Settings.get(); ++ let checked = colorScheme === 'prefer-dark'; ++ if (gtkTheme === 'Yaru' && !gtkThemeVariant?.endsWith('dark')) ++ checked = false; + if (this.checked !== checked) + this.set({checked}); + } diff --git a/debian/patches/ubuntu/desktop_detect.patch b/debian/patches/ubuntu/desktop_detect.patch new file mode 100644 index 0000000..3f73bb0 --- /dev/null +++ b/debian/patches/ubuntu/desktop_detect.patch @@ -0,0 +1,66 @@ +From: Ubuntu Developers +Date: Wed, 20 Jun 2018 19:22:06 +0200 +Subject: Add an helper to detect current desktop + +We will differentiate some behavior depending on current desktop. Add an +helper to centralize the current desktop detection. +Forwarded: not-needed +Origin: ubuntu +=================================================================== +--- + js/js-resources.gresource.xml | 1 + + js/misc/desktop.js | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 34 insertions(+) + create mode 100644 js/misc/desktop.js + +diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml +index c6e4791..3fc5302 100644 +--- a/js/js-resources.gresource.xml ++++ b/js/js-resources.gresource.xml +@@ -13,6 +13,7 @@ + + misc/config.js + misc/extensionUtils.js ++ misc/desktop.js + misc/fileUtils.js + misc/dbusUtils.js + misc/gnomeSession.js +diff --git a/js/misc/desktop.js b/js/misc/desktop.js +new file mode 100644 +index 0000000..8bdca57 +--- /dev/null ++++ b/js/misc/desktop.js +@@ -0,0 +1,33 @@ ++// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- ++ ++const GLib = imports.gi.GLib; ++ ++// current desktop doesn't change unless we restart the shell or control ++// the env variable. It's safe to cache matching result ++const _currentDesktopsMatches = new Map(); ++ ++// is: ++// @name: desktop string you want to assert if it matches the current desktop env ++// ++// The function examples XDG_CURRENT_DESKTOP and return if the current desktop ++// is part of that desktop string. ++// ++// Return value: if the environment isn't set or doesn't match, return False ++// otherwise, return True. ++function is(name) { ++ if (!_currentDesktopsMatches.size) { ++ const desktopsEnv = GLib.getenv('XDG_CURRENT_DESKTOP'); ++ if (!desktopsEnv) { ++ _currentDesktopsMatches.set(name, false); ++ return false; ++ } ++ ++ const desktops = desktopsEnv.split(':'); ++ desktops.forEach(d => _currentDesktopsMatches.set(d, true)); ++ ++ if (!_currentDesktopsMatches.size) ++ _currentDesktopsMatches.set(name, _currentDesktopsMatches.has(name)); ++ } ++ ++ return !!_currentDesktopsMatches.get(name); ++} diff --git a/debian/patches/ubuntu/gdm_alternatives.patch b/debian/patches/ubuntu/gdm_alternatives.patch new file mode 100644 index 0000000..58b3e73 --- /dev/null +++ b/debian/patches/ubuntu/gdm_alternatives.patch @@ -0,0 +1,42 @@ +From: Jeremy Soller +Date: Wed, 20 Jun 2018 19:22:06 +0200 +Subject: Add support for GDM theme alternatives + +GNOME vanilla and systemd76 derivative ships their own GDM theme. + +This allows to provide alternative gresource file for gdm3 that must contain +a `gdm3.css` stylesheet that will be applied. + +Bug: https://bugzilla.gnome.org/show_bug.cgi?id=787454 +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1715722 +Last-Update: 2017-09-08 +--- + data/gnome-shell-theme.gresource.xml | 1 + + js/ui/sessionMode.js | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/data/gnome-shell-theme.gresource.xml b/data/gnome-shell-theme.gresource.xml +index 24b3be8..2632e5d 100644 +--- a/data/gnome-shell-theme.gresource.xml ++++ b/data/gnome-shell-theme.gresource.xml +@@ -9,6 +9,7 @@ + checkbox-off-focused.svg + checkbox-off-light.svg + checkbox-off.svg ++ gnome-shell.css + gnome-shell.css + gnome-shell-high-contrast.css + gnome-shell-start.svg +diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js +index c67b4a7..7831646 100644 +--- a/js/ui/sessionMode.js ++++ b/js/ui/sessionMode.js +@@ -50,6 +50,8 @@ const _modes = { + + 'gdm': { + hasNotifications: true, ++ stylesheetName: 'gdm.css', ++ themeResourceName: 'gdm-theme.gresource', + isGreeter: true, + isPrimary: true, + unlockDialog: imports.gdm.loginDialog.LoginDialog, diff --git a/debian/patches/ubuntu/keep-ubuntu-logo-bright-lp1867133-v1.patch b/debian/patches/ubuntu/keep-ubuntu-logo-bright-lp1867133-v1.patch new file mode 100644 index 0000000..3ebba4f --- /dev/null +++ b/debian/patches/ubuntu/keep-ubuntu-logo-bright-lp1867133-v1.patch @@ -0,0 +1,36 @@ +From: Daniel van Vugt +Date: Thu, 2 Apr 2020 17:16:27 +0800 +Subject: Keep the Ubuntu logo at full brightness during startup animation + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1867133 +Forwarded: not-needed +Last-Update: 2020-03-18 +--- + js/gdm/loginDialog.js | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index 7e7d884..52f3a56 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -1261,7 +1261,11 @@ var LoginDialog = GObject.registerClass({ + { sortGroup: CtrlAltTab.SortGroup.MIDDLE }); + this.activate(); + +- this.opacity = 0; ++ // Clutter doesn't yet fully support invisible parents with forced ++ // visible children and will make everything invisible (flicker) on ++ // the first frame if we start at 0. So we start at 1 instead... ++ this.opacity = 1; ++ this._logoBin.set_opacity_override(255); + + this._grab = Main.pushModal(global.stage, { actionMode: Shell.ActionMode.LOGIN_SCREEN }); + +@@ -1269,6 +1273,7 @@ var LoginDialog = GObject.registerClass({ + opacity: 255, + duration: 1000, + mode: Clutter.AnimationMode.EASE_IN_QUAD, ++ onComplete: () => { this._logoBin.set_opacity_override(-1); }, + }); + + return true; diff --git a/debian/patches/ubuntu/layout-Try-to-allocate-before-getting-size-of-tracke.patch b/debian/patches/ubuntu/layout-Try-to-allocate-before-getting-size-of-tracke.patch new file mode 100644 index 0000000..e43fc8c --- /dev/null +++ b/debian/patches/ubuntu/layout-Try-to-allocate-before-getting-size-of-tracke.patch @@ -0,0 +1,34 @@ +From: Daniel van Vugt +Date: Wed, 31 Mar 2021 17:59:09 +0800 +Subject: layout: Try to allocate before getting size of tracked actors + +Because we're about to `get_transformed_{position,size}` of each, +which will return NaNs if not yet allocated. Those NaNs were finding +their way into the workspace strut definitions on startup and not +getting corrected until after the startup animation completed. This +meant any extensions depending on the `workareas-changed` signal were +getting an incorrect workarea (the whole workspace) and so were +rendered out of place during the login animation. Now they're not. + +Author: Daniel van Vugt +Origin: https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1785 +Bug-Ubuntu: https://launchpad.net/bugs/1917939, https://launchpad.net/bugs/1919979 +Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1627 +Forwarded: yes +Last-Update: 2021-04-07 +--- + js/ui/layout.js | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/js/ui/layout.js b/js/ui/layout.js +index e53ff9d..6fa9566 100644 +--- a/js/ui/layout.js ++++ b/js/ui/layout.js +@@ -1051,6 +1051,7 @@ var LayoutManager = GObject.registerClass({ + if (!(actorData.affectsInputRegion && wantsInputRegion) && !actorData.affectsStruts) + continue; + ++ actorData.actor.get_allocation_box(); + let [x, y] = actorData.actor.get_transformed_position(); + let [w, h] = actorData.actor.get_transformed_size(); + x = Math.round(x); diff --git a/debian/patches/ubuntu/lightdm-user-switching.patch b/debian/patches/ubuntu/lightdm-user-switching.patch new file mode 100644 index 0000000..faf0b9f --- /dev/null +++ b/debian/patches/ubuntu/lightdm-user-switching.patch @@ -0,0 +1,93 @@ +From: Tim Lunn +Date: Tue, 9 Oct 2012 11:18:28 +0200 +Subject: [PATCH] userMenu: allow user switching when using lightdm + +When running lightdm and gnome-shell, its currently not possible to +switch users via the usermenu. This commit adds a dbus call to +switch to the lightdm greeter. + +https://bugzilla.gnome.org/show_bug.cgi?id=685794 +--- + js/misc/systemActions.js | 47 ++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 40 insertions(+), 7 deletions(-) + +diff --git a/js/misc/systemActions.js b/js/misc/systemActions.js +index 759862a..6c84fe2 100644 +--- a/js/misc/systemActions.js ++++ b/js/misc/systemActions.js +@@ -224,6 +224,34 @@ const SystemActions = GObject.registerClass({ + return this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName; + } + ++ _lightdmLoginSession() { ++ try { ++ let seat = GLib.getenv("XDG_SEAT_PATH"); ++ let result = Gio.DBus.system.call_sync('org.freedesktop.DisplayManager', ++ seat, ++ 'org.freedesktop.DisplayManager.Seat', ++ 'SwitchToGreeter', null, null, ++ Gio.DBusCallFlags.NONE, ++ -1, null); ++ return result; ++ } catch(e) { ++ return false; ++ } ++ } ++ ++ _sensorProxyAppeared() { ++ this._sensorProxy = new SensorProxy(Gio.DBus.system, SENSOR_BUS_NAME, SENSOR_OBJECT_PATH, ++ (proxy, error) => { ++ if (error) { ++ log(error.message); ++ return; ++ } ++ this._sensorProxy.connect('g-properties-changed', ++ () => { this._updateOrientationLock(); }); ++ this._updateOrientationLock(); ++ }); ++ } ++ + _updateOrientationLock() { + const available = this._monitorManager.get_panel_orientation_managed(); + +@@ -325,7 +353,7 @@ const SystemActions = GObject.registerClass({ + _updateLockScreen() { + let showLock = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; + let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY); +- this._actions.get(LOCK_SCREEN_ACTION_ID).available = showLock && allowLockScreen && LoginManager.canLock(); ++ this._actions.get(LOCK_SCREEN_ACTION_ID).available = showLock && allowLockScreen; + this.notify('can-lock-screen'); + } + +@@ -413,20 +441,25 @@ const SystemActions = GObject.registerClass({ + if (!this._actions.get(LOCK_SCREEN_ACTION_ID).available) + throw new Error('The lock-screen action is not available!'); + +- Main.screenShield.lock(true); ++ if (Main.screenShield) ++ Main.screenShield.lock(true); ++ else ++ this._lightdmLoginSession(); + } + + activateSwitchUser() { + if (!this._actions.get(SWITCH_USER_ACTION_ID).available) + throw new Error('The switch-user action is not available!'); + +- if (Main.screenShield) ++ if (Main.screenShield) { + Main.screenShield.lock(false); + +- Clutter.threads_add_repaint_func_full(Clutter.RepaintFlags.POST_PAINT, () => { +- Gdm.goto_login_session_sync(null); +- return false; +- }); ++ Clutter.threads_add_repaint_func_full(Clutter.RepaintFlags.POST_PAINT, () => { ++ Gdm.goto_login_session_sync(null); ++ return false; ++ }); ++ } else ++ this._lightdmLoginSession(); + } + + activateLogout() { diff --git a/debian/patches/ubuntu/lock_on_suspend.patch b/debian/patches/ubuntu/lock_on_suspend.patch new file mode 100644 index 0000000..c3e34e9 --- /dev/null +++ b/debian/patches/ubuntu/lock_on_suspend.patch @@ -0,0 +1,48 @@ +From: Tim Lunn +Date: Wed, 20 Jun 2018 19:22:06 +0200 +Subject: add support for the ubuntu lock on suspend option + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1063110 +--- + js/ui/screenShield.js | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js +index b6c3c55..038c1df 100644 +--- a/js/ui/screenShield.js ++++ b/js/ui/screenShield.js +@@ -22,6 +22,7 @@ const { adjustAnimationTime } = imports.ui.environment; + const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver'; + const LOCK_ENABLED_KEY = 'lock-enabled'; + const LOCK_DELAY_KEY = 'lock-delay'; ++const SUSPEND_LOCK_ENABLED_KEY = 'ubuntu-lock-on-suspend'; + + const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown'; + const DISABLE_LOCK_KEY = 'disable-lock-screen'; +@@ -106,6 +107,7 @@ var ScreenShield = class extends Signals.EventEmitter { + + this._settings = new Gio.Settings({ schema_id: SCREENSAVER_SCHEMA }); + this._settings.connect(`changed::${LOCK_ENABLED_KEY}`, this._syncInhibitor.bind(this)); ++ this._settings.connect(`changed::${SUSPEND_LOCK_ENABLED_KEY}`, this._syncInhibitor.bind(this)); + + this._lockSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA }); + this._lockSettings.connect(`changed::${DISABLE_LOCK_KEY}`, this._syncInhibitor.bind(this)); +@@ -211,7 +213,8 @@ var ScreenShield = class extends Signals.EventEmitter { + } + + async _syncInhibitor() { +- const lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY); ++ const lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY) || ++ this._settings.get_boolean(SUSPEND_LOCK_ENABLED_KEY); + const lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY); + const inhibit = !!this._loginSession && this._loginSession.Active && + !this._isActive && lockEnabled && !lockLocked && +@@ -242,7 +245,7 @@ var ScreenShield = class extends Signals.EventEmitter { + + _prepareForSleep(loginManager, aboutToSuspend) { + if (aboutToSuspend) { +- if (this._settings.get_boolean(LOCK_ENABLED_KEY)) ++ if (this._settings.get_boolean(SUSPEND_LOCK_ENABLED_KEY)) + this.lock(true); + } else { + this._wakeUpScreen(); diff --git a/debian/patches/ubuntu/main-Support-loading-multiple-Yaru-theme-variants.patch b/debian/patches/ubuntu/main-Support-loading-multiple-Yaru-theme-variants.patch new file mode 100644 index 0000000..02b5109 --- /dev/null +++ b/debian/patches/ubuntu/main-Support-loading-multiple-Yaru-theme-variants.patch @@ -0,0 +1,345 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Fri, 25 Feb 2022 01:07:12 +0100 +Subject: main: Support loading multiple Yaru theme variants + +Yaru can provide multiple variants, we can support using more theme +variants in GNOME shell as it happens on Gtk apps. + +So, make StSettings to compute the main theme and the chosen variant, +and we use those to pick the correct .css file. + +We don't make difference between dark/light themes here, as we assume +that the shell theme will always be dark or light. + +Forwarded: not-needed +--- + data/meson.build | 8 +- + data/org.gnome.shell.ubuntu.gschema.xml.in | 17 ++++ + js/ui/main.js | 42 ++++++++++ + src/st/st-settings.c | 120 +++++++++++++++++++++++++++++ + 4 files changed, 186 insertions(+), 1 deletion(-) + create mode 100644 data/org.gnome.shell.ubuntu.gschema.xml.in + +diff --git a/data/meson.build b/data/meson.build +index 07d6d4a..3274af2 100644 +--- a/data/meson.build ++++ b/data/meson.build +@@ -97,6 +97,12 @@ schema = configure_file( + configuration: schemaconf, + install_dir: schemadir + ) ++schema_ubuntu = configure_file( ++ input: 'org.gnome.shell.ubuntu.gschema.xml.in', ++ output: 'org.gnome.shell.ubuntu.gschema.xml', ++ configuration: schemaconf, ++ install_dir: schemadir ++) + schema_ubuntu_login = configure_file( + input: 'com.ubuntu.login-screen.gschema.xml.in', + output: 'com.ubuntu.login-screen.gschema.xml', +@@ -131,7 +137,7 @@ endif + + # for unit tests - gnome.compile_schemas() only looks in srcdir + custom_target('compile-schemas', +- input: [schema, schema_ubuntu_login], ++ input: [schema, schema_ubuntu, schema_ubuntu_login], + output: 'gschemas.compiled', + command: [find_program('glib-compile-schemas'), data_builddir], + build_by_default: true) +diff --git a/data/org.gnome.shell.ubuntu.gschema.xml.in b/data/org.gnome.shell.ubuntu.gschema.xml.in +new file mode 100644 +index 0000000..6f9cc62 +--- /dev/null ++++ b/data/org.gnome.shell.ubuntu.gschema.xml.in +@@ -0,0 +1,17 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 'default' ++ Color scheme ++ ++ The preferred color scheme for the shell user interface. Valid values are “default”, “prefer-dark”, “prefer-light”. ++ ++ ++ ++ +diff --git a/js/ui/main.js b/js/ui/main.js +index b39bcf4..0d786b1 100644 +--- a/js/ui/main.js ++++ b/js/ui/main.js +@@ -186,6 +186,9 @@ function start() { + sessionMode.connect('updated', _sessionUpdated); + + St.Settings.get().connect('notify::high-contrast', _loadDefaultStylesheet); ++ St.Settings.get().connect('notify::gtk-theme', _loadDefaultStylesheet); ++ St.Settings.get().connect('notify::gtk-theme-variant', _loadDefaultStylesheet); ++ St.Settings.get().connect('notify::shell-color-scheme', _loadDefaultStylesheet); + + // Initialize ParentalControlsManager before the UI + ParentalControlsManager.getDefault(); +@@ -434,6 +437,38 @@ function _getStylesheet(name) { + return null; + } + ++function _getYaruStyleSheet(themeVariant) { ++ const { shellColorScheme: colorScheme } = St.Settings.get(); ++ const baseThemeName = sessionMode.stylesheetName.split(".css").at(0); ++ const isDark = themeVariant === 'dark' || themeVariant?.endsWith('-dark'); ++ let colorSchemeVariant; ++ ++ if (isDark && colorScheme == 'prefer-light') { ++ colorSchemeVariant = themeVariant.split('-').slice(0, -1).join('-'); ++ } else if (!isDark && colorScheme == 'prefer-dark' ) { ++ colorSchemeVariant = themeVariant ? `${themeVariant}-dark` : 'dark'; ++ } ++ ++ if (colorSchemeVariant !== undefined) { ++ if (colorSchemeVariant.length) ++ colorSchemeVariant = `-${colorSchemeVariant}`; ++ const stylesheet = _getStylesheet(`${baseThemeName}${colorSchemeVariant}.css`); ++ if (stylesheet) ++ return stylesheet; ++ } ++ ++ if (!themeVariant) ++ return null; ++ ++ const stylesheet = _getStylesheet(`${baseThemeName}-${themeVariant}.css`); ++ ++ // Try to use the dark theme if a dark variant is selected ++ if (!stylesheet && isDark) ++ return _getStylesheet(`${baseThemeName}-dark.css`); ++ ++ return stylesheet; ++} ++ + function _getDefaultStylesheet() { + let stylesheet = null; + let name = sessionMode.stylesheetName; +@@ -442,6 +477,13 @@ function _getDefaultStylesheet() { + if (St.Settings.get().high_contrast) + stylesheet = _getStylesheet(name.replace('.css', '-high-contrast.css')); + ++ if (stylesheet == null) { ++ const settings = St.Settings.get(); ++ ++ if (settings.gtkTheme === 'Yaru') ++ stylesheet = _getYaruStyleSheet(settings.gtkThemeVariant?.toLowerCase()); ++ } ++ + if (stylesheet == null) + stylesheet = _getStylesheet(sessionMode.stylesheetName); + +diff --git a/src/st/st-settings.c b/src/st/st-settings.c +index 04bf68f..cb625b2 100644 +--- a/src/st/st-settings.c ++++ b/src/st/st-settings.c +@@ -33,6 +33,8 @@ + #define KEY_FONT_NAME "font-name" + #define KEY_HIGH_CONTRAST "high-contrast" + #define KEY_GTK_ICON_THEME "icon-theme" ++#define KEY_GTK_THEME "gtk-theme" ++#define KEY_COLOR_SCHEME "color-scheme" + #define KEY_MAGNIFIER_ACTIVE "screen-magnifier-enabled" + #define KEY_DISABLE_SHOW_PASSWORD "disable-show-password" + +@@ -43,7 +45,10 @@ enum { + PROP_DRAG_THRESHOLD, + PROP_FONT_NAME, + PROP_HIGH_CONTRAST, ++ PROP_GTK_THEME, ++ PROP_GTK_THEME_VARIANT, + PROP_GTK_ICON_THEME, ++ PROP_SHELL_COLOR_SCHEME, + PROP_MAGNIFIER_ACTIVE, + PROP_SLOW_DOWN_FACTOR, + PROP_DISABLE_SHOW_PASSWORD, +@@ -60,10 +65,13 @@ struct _StSettings + GSettings *a11y_applications_settings; + GSettings *a11y_interface_settings; + GSettings *lockdown_settings; ++ GSettings *ubuntu_settings; + + gchar *font_name; + gboolean high_contrast; + gchar *gtk_icon_theme; ++ gchar *gtk_theme; ++ gchar *gtk_theme_variant; + int inhibit_animations_count; + gboolean enable_animations; + gboolean primary_paste; +@@ -133,7 +141,10 @@ st_settings_finalize (GObject *object) + g_object_unref (settings->a11y_applications_settings); + g_object_unref (settings->a11y_interface_settings); + g_object_unref (settings->lockdown_settings); ++ g_object_unref (settings->ubuntu_settings); + g_free (settings->font_name); ++ g_free (settings->gtk_theme); ++ g_free (settings->gtk_theme_variant); + g_free (settings->gtk_icon_theme); + + G_OBJECT_CLASS (st_settings_parent_class)->finalize (object); +@@ -185,6 +196,16 @@ st_settings_get_property (GObject *object, + case PROP_GTK_ICON_THEME: + g_value_set_string (value, settings->gtk_icon_theme); + break; ++ case PROP_GTK_THEME: ++ g_value_set_string (value, settings->gtk_theme); ++ break; ++ case PROP_GTK_THEME_VARIANT: ++ g_value_set_string (value, settings->gtk_theme_variant); ++ break; ++ case PROP_SHELL_COLOR_SCHEME: ++ g_value_take_string (value, ++ g_settings_get_string (settings->ubuntu_settings, KEY_COLOR_SCHEME)); ++ break; + case PROP_MAGNIFIER_ACTIVE: + g_value_set_boolean (value, settings->magnifier_active); + break; +@@ -275,6 +296,39 @@ st_settings_class_init (StSettingsClass *klass) + "", + ST_PARAM_READABLE); + ++ /** ++ * StSettings:gtk-theme: ++ * ++ * The current GTK theme ++ */ ++ props[PROP_GTK_THEME] = g_param_spec_string ("gtk-theme", ++ "GTK Theme", ++ "GTK Theme", ++ "", ++ ST_PARAM_READABLE); ++ ++ /** ++ * StSettings:gtk-theme-variant: ++ * ++ * The current GTK theme ++ */ ++ props[PROP_GTK_THEME_VARIANT] = g_param_spec_string ("gtk-theme-variant", ++ "GTK Theme Variant", ++ "GTK Theme Variant", ++ "", ++ ST_PARAM_READABLE); ++ ++ /** ++ * StSettings:shell-color-scheme: ++ * ++ * The current GTK theme ++ */ ++ props[PROP_SHELL_COLOR_SCHEME] = g_param_spec_string ("shell-color-scheme", ++ "Shell Color Scheme", ++ "Shell Color Scheme", ++ "default", ++ ST_PARAM_READABLE); ++ + /** + * StSettings:magnifier-active: + * +@@ -311,6 +365,45 @@ st_settings_class_init (StSettingsClass *klass) + g_object_class_install_properties (object_class, N_PROPS, props); + } + ++static void ++update_theme_settings (StSettings *settings) ++{ ++ g_auto(GStrv) parts = NULL; ++ g_autofree char *theme = NULL; ++ g_autofree char *variant = NULL; ++ ++ theme = g_settings_get_string (settings->interface_settings, KEY_GTK_THEME); ++ parts = g_strsplit (theme, "-", 2); ++ ++ switch (g_strv_length (parts)) ++ { ++ case 2: ++ variant = g_strdup (parts[1]); ++ /* fallthrough */ ++ case 1: ++ theme = g_strdup (parts[0]); ++ break; ++ } ++ ++ if (g_strcmp0 (settings->gtk_theme, theme) != 0) ++ { ++ g_free (settings->gtk_theme); ++ settings->gtk_theme = g_steal_pointer (&theme); ++ ++ g_object_notify_by_pspec (G_OBJECT (settings), ++ props[PROP_GTK_THEME]); ++ } ++ ++ if (g_strcmp0 (settings->gtk_theme_variant, variant) != 0) ++ { ++ g_free (settings->gtk_theme_variant); ++ settings->gtk_theme_variant = g_steal_pointer (&variant); ++ ++ g_object_notify_by_pspec (G_OBJECT (settings), ++ props[PROP_GTK_THEME_VARIANT]); ++ } ++} ++ + static void + on_interface_settings_changed (GSettings *g_settings, + const gchar *key, +@@ -332,6 +425,10 @@ on_interface_settings_changed (GSettings *g_settings, + settings->font_name = g_settings_get_string (g_settings, key); + g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_FONT_NAME]); + } ++ else if (g_str_equal (key, KEY_GTK_THEME)) ++ { ++ update_theme_settings (settings); ++ } + else if (g_str_equal (key, KEY_GTK_ICON_THEME)) + { + g_free (settings->gtk_icon_theme); +@@ -339,6 +436,23 @@ on_interface_settings_changed (GSettings *g_settings, + g_object_notify_by_pspec (G_OBJECT (settings), + props[PROP_GTK_ICON_THEME]); + } ++ else if (g_str_equal (key, KEY_COLOR_SCHEME)) ++ { ++ g_object_notify_by_pspec (G_OBJECT (settings), ++ props[PROP_SHELL_COLOR_SCHEME]); ++ } ++} ++ ++static void ++on_ubuntu_settings_changed (GSettings *g_settings, ++ const gchar *key, ++ StSettings *settings) ++{ ++ if (g_str_equal (key, KEY_COLOR_SCHEME)) ++ { ++ g_object_notify_by_pspec (G_OBJECT (settings), ++ props[PROP_SHELL_COLOR_SCHEME]); ++ } + } + + static void +@@ -398,6 +512,10 @@ st_settings_init (StSettings *settings) + g_signal_connect (settings->interface_settings, "changed", + G_CALLBACK (on_interface_settings_changed), settings); + ++ settings->ubuntu_settings = g_settings_new ("org.gnome.shell.ubuntu"); ++ g_signal_connect (settings->ubuntu_settings, "changed", ++ G_CALLBACK (on_ubuntu_settings_changed), settings); ++ + settings->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse"); + g_signal_connect (settings->mouse_settings, "changed", + G_CALLBACK (on_mouse_settings_changed), settings); +@@ -414,6 +532,8 @@ st_settings_init (StSettings *settings) + g_signal_connect (settings->lockdown_settings, "changed", + G_CALLBACK (on_lockdown_settings_changed), settings); + ++ update_theme_settings (settings); ++ + settings->enable_animations = g_settings_get_boolean (settings->interface_settings, + KEY_ENABLE_ANIMATIONS); + settings->primary_paste = g_settings_get_boolean (settings->interface_settings, diff --git a/debian/patches/ubuntu/resolve_alternate_theme_path.patch b/debian/patches/ubuntu/resolve_alternate_theme_path.patch new file mode 100644 index 0000000..10a23d8 --- /dev/null +++ b/debian/patches/ubuntu/resolve_alternate_theme_path.patch @@ -0,0 +1,50 @@ +From: Didier Roche +Date: Tue, 22 Oct 2019 11:22:06 +0200 +Subject: Resolve real path name for theme file + + We are using alternative theme paths. Some of them are symlinks like + gdm3.css. It points to a different directory and we need to ensure + assets are loaded from the real theme path then (assets path are + relative to it). + Resolve them symlinks to ensure we use the original file itself when + loading the stylesheet. +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1798747 +Forwarded: Not-needed (upstream doesn't support officially theming) +--- + js/ui/main.js | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/js/ui/main.js b/js/ui/main.js +index 5c3cb8e..1b4c9fd 100644 +--- a/js/ui/main.js ++++ b/js/ui/main.js +@@ -404,6 +404,14 @@ async function _handleLockScreenWarning() { + } + } + ++function _realpath(path) { ++ try { ++ while (GLib.file_test(path, GLib.FileTest.IS_SYMLINK)) ++ path = GLib.file_read_link(path); ++ } catch (e) { } ++ return path; ++} ++ + function _getStylesheet(name) { + let stylesheet; + +@@ -414,12 +422,12 @@ function _getStylesheet(name) { + let dataDirs = GLib.get_system_data_dirs(); + for (let i = 0; i < dataDirs.length; i++) { + let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'theme', name]); +- stylesheet = Gio.file_new_for_path(path); ++ stylesheet = Gio.file_new_for_path(_realpath(path)); + if (stylesheet.query_exists(null)) + return stylesheet; + } + +- stylesheet = Gio.File.new_for_path(`${global.datadir}/theme/${name}`); ++ stylesheet = Gio.File.new_for_path(_realpath(`${global.datadir}/theme/${name}`)); + if (stylesheet.query_exists(null)) + return stylesheet; + diff --git a/debian/patches/ubuntu/search-call-XUbuntuCancel-method-on-providers-when-no-dat.patch b/debian/patches/ubuntu/search-call-XUbuntuCancel-method-on-providers-when-no-dat.patch new file mode 100644 index 0000000..6c9ed45 --- /dev/null +++ b/debian/patches/ubuntu/search-call-XUbuntuCancel-method-on-providers-when-no-dat.patch @@ -0,0 +1,163 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Thu, 23 Aug 2018 20:00:57 +0200 +Subject: search: call XUbuntuCancel method on providers when no data is + needed + +Add XUbuntuCancel method to search providers and call it when a search provider +is still doing operations. +Ignore the result when the method does not exist or is cancelled. + +This will allow to stop operations on providers. + +Fixes LP: #1756826 + +Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/bionic/+source/gnome-shell/+bug/1756826 +Forwarded: not-needed +--- + .../org.gnome.ShellSearchProvider.xml | 6 ++++ + .../org.gnome.ShellSearchProvider2.xml | 6 ++++ + js/ui/remoteSearch.js | 12 ++++++++ + js/ui/search.js | 33 ++++++++++++++++++++++ + 4 files changed, 57 insertions(+) + +diff --git a/data/dbus-interfaces/org.gnome.ShellSearchProvider.xml b/data/dbus-interfaces/org.gnome.ShellSearchProvider.xml +index 78ad305..393cb01 100644 +--- a/data/dbus-interfaces/org.gnome.ShellSearchProvider.xml ++++ b/data/dbus-interfaces/org.gnome.ShellSearchProvider.xml +@@ -69,5 +69,11 @@ + + + ++ ++ ++ + + +diff --git a/data/dbus-interfaces/org.gnome.ShellSearchProvider2.xml b/data/dbus-interfaces/org.gnome.ShellSearchProvider2.xml +index 9502340..8141bc0 100644 +--- a/data/dbus-interfaces/org.gnome.ShellSearchProvider2.xml ++++ b/data/dbus-interfaces/org.gnome.ShellSearchProvider2.xml +@@ -83,5 +83,11 @@ + + + ++ ++ ++ + + +diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js +index 592dfe1..e50ded6 100644 +--- a/js/ui/remoteSearch.js ++++ b/js/ui/remoteSearch.js +@@ -26,6 +26,7 @@ const SearchProviderIface = ` + + + ++ + + `; + +@@ -54,6 +55,7 @@ const SearchProvider2Iface = ` + + + ++ + + `; + +@@ -299,6 +301,16 @@ var RemoteSearchProvider = class { + return resultMetas; + } + ++ async XUbuntuCancel(cancellable) { ++ try { ++ await this.proxy.XUbuntuCancelAsync(cancellable); ++ } catch (error) { ++ if (!error.matches(Gio.DBusError, Gio.DBusError.UNKNOWN_METHOD) && ++ !error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) ++ log(`Received error from D-Bus search provider ${this.id} during XUbuntuCancel: ${error}`); ++ } ++ } ++ + activateResult(id) { + this.proxy.ActivateResultAsync(id).catch(logError); + } +diff --git a/js/ui/search.js b/js/ui/search.js +index 7d50ef2..53a812b 100644 +--- a/js/ui/search.js ++++ b/js/ui/search.js +@@ -218,7 +218,9 @@ var SearchResultsBase = GObject.registerClass({ + this._cancellable.cancel(); + this._cancellable.reset(); + ++ this.provider.resultsMetasInProgress = true; + const metas = await this.provider.getResultMetas(metasNeeded, this._cancellable); ++ this.provider.resultsMetasInProgress = this._cancellable.is_cancelled(); + + if (this._cancellable.is_cancelled()) { + if (metas.length > 0) +@@ -596,6 +598,10 @@ var SearchResultsView = GObject.registerClass({ + + this._searchTimeoutId = 0; + this._cancellable = new Gio.Cancellable(); ++ this._searchCancelCancellable = new Gio.Cancellable(); ++ const cancellableCancelledId = this._cancellable.connect(() => ++ this._cancelSearchProviderRequest()); ++ this.connect('destroy', () => this._cancellable.disconnect(cancellableCancelledId)); + + this._registerProvider(new AppDisplay.AppSearchProvider()); + +@@ -644,11 +650,31 @@ var SearchResultsView = GObject.registerClass({ + } + } + ++ _cancelSearchProviderRequest() { ++ if (this._terms.length !== 0 || this._searchCancelTimeoutId) ++ return; ++ ++ this._searchCancelTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, () => { ++ Promise.all(this._providers.map(async provider => { ++ if (provider.isRemoteProvider && ++ (provider.searchInProgress || provider.resultsMetasInProgress)) { ++ await provider.XUbuntuCancel(this._searchCancelCancellable); ++ provider.searchInProgress = false; ++ provider.resultsMetasInProgress = false; ++ } ++ })).catch(logError); ++ ++ delete this._searchCancelTimeoutId; ++ return GLib.SOURCE_REMOVE; ++ }); ++ } ++ + _reset() { + this._terms = []; + this._results = {}; + this._clearDisplay(); + this._clearSearchTimeout(); ++ this._cancelSearchProviderRequest(); + this._defaultResult = null; + this._startingSearch = false; + +@@ -720,6 +746,13 @@ var SearchResultsView = GObject.registerClass({ + if (this._terms.length > 0) + isSubSearch = searchString.indexOf(previousSearchString) == 0; + ++ this._searchCancelCancellable.cancel(); ++ this._searchCancelCancellable.reset(); ++ if (this._searchCancelTimeoutId) { ++ GLib.source_remove(this._searchCancelTimeoutId); ++ delete this._searchCancelTimeoutId; ++ } ++ + this._terms = terms; + this._isSubSearch = isSubSearch; + this._updateSearchProgress(); diff --git a/debian/patches/ubuntu/secure_mode_extension.patch b/debian/patches/ubuntu/secure_mode_extension.patch new file mode 100644 index 0000000..fb91c19 --- /dev/null +++ b/debian/patches/ubuntu/secure_mode_extension.patch @@ -0,0 +1,89 @@ +From: Ubuntu Developers +Date: Wed, 20 Jun 2018 19:22:06 +0200 +Subject: Don't allow ubuntu mode extension to update + +Ensure that no update is proposed or loaded if sideloaded (always +prefer system version) on the ubuntu session. +We want to ensure that the default code running is going through +our QA and security team process than being loaded from a 3rd +party website. +Also, that will enable us to upload newer versions on GNOME +extension website while still letting older ubuntu release versions +running expected extension version. +Origin: ubuntu +Forwarded: https://bugzilla.gnome.org/show_bug.cgi?id=789852 +--- + js/ui/extensionDownloader.js | 11 +++++++++++ + js/ui/extensionSystem.js | 9 +++++++++ + 2 files changed, 20 insertions(+) + +diff --git a/js/ui/extensionDownloader.js b/js/ui/extensionDownloader.js +index 197cc1c..2c92a6c 100644 +--- a/js/ui/extensionDownloader.js ++++ b/js/ui/extensionDownloader.js +@@ -4,6 +4,7 @@ + const { Clutter, Gio, GLib, GObject, Soup } = imports.gi; + + const Config = imports.misc.config; ++const Desktop = imports.misc.desktop; + const Dialog = imports.ui.dialog; + const ExtensionUtils = imports.misc.extensionUtils; + const FileUtils = imports.misc.fileUtils; +@@ -32,6 +33,13 @@ async function installExtension(uuid, invocation) { + shell_version: Config.PACKAGE_VERSION, + }; + ++ if (Desktop.is('ubuntu') && Main.extensionManager.isModeExtension(uuid)) { ++ const msg = _("This is an extension enabled by your current mode, you can't install manually any update in that session."); ++ Main.notifyError(_("Can't install “%s”:").format(uuid), msg); ++ invocation.return_dbus_error('org.gnome.Shell.ExtensionError', msg); ++ return; ++ } ++ + const message = Soup.Message.new_from_encoded_form('GET', + REPOSITORY_URL_INFO, + Soup.form_encode_hash(params)); +@@ -188,6 +196,9 @@ async function checkForUpdates() { + return; + if (extension.hasUpdate) + return; ++ // don't updates out of repository mode extension ++ if (Desktop.is("ubuntu") && Main.extensionManager.isModeExtension(uuid)) ++ return; + metadatas[uuid] = { + version: extension.metadata.version, + }; +diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js +index d9cdf77..4cc2ca3 100644 +--- a/js/ui/extensionSystem.js ++++ b/js/ui/extensionSystem.js +@@ -4,6 +4,7 @@ + const { GLib, Gio, GObject, Shell, St } = imports.gi; + const Signals = imports.misc.signals; + ++const Desktop = imports.misc.desktop; + const ExtensionDownloader = imports.ui.extensionDownloader; + const ExtensionUtils = imports.misc.extensionUtils; + const FileUtils = imports.misc.fileUtils; +@@ -446,6 +447,10 @@ var ExtensionManager = class extends Signals.EventEmitter { + await this.loadExtension(newExtension); + } + ++ isModeExtension(uuid) { ++ return this._getModeExtensions().indexOf(uuid) !== -1; ++ } ++ + async _callExtensionInit(uuid) { + if (!this._extensionSupportsSessionMode(uuid)) + return false; +@@ -662,6 +667,10 @@ var ExtensionManager = class extends Signals.EventEmitter { + let type = dir.has_prefix(perUserDir) + ? ExtensionType.PER_USER + : ExtensionType.SYSTEM; ++ if (Desktop.is("ubuntu") && this.isModeExtension(uuid) && type === ExtensionType.PER_USER) { ++ log(`Found user extension ${uuid}, but not loading from ${dir.get_path()} directory as part of session mode.`); ++ return; ++ } + try { + extension = this.createExtensionObject(uuid, dir, type); + } catch (error) { diff --git a/debian/patches/ubuntu/sessionMode-Add-support-for-configuring-an-icons-resource.patch b/debian/patches/ubuntu/sessionMode-Add-support-for-configuring-an-icons-resource.patch new file mode 100644 index 0000000..f3d151d --- /dev/null +++ b/debian/patches/ubuntu/sessionMode-Add-support-for-configuring-an-icons-resource.patch @@ -0,0 +1,38 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Thu, 24 Feb 2022 04:22:32 +0100 +Subject: sessionMode: Add support for configuring an icons resource name + +Similar to what we did (and upstreamed) for the theme, in this case +however there's very likely no interest from upstream for this. + +Forwarded: not-needed +--- + js/ui/main.js | 2 +- + js/ui/sessionMode.js | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/js/ui/main.js b/js/ui/main.js +index 1b4c9fd..b39bcf4 100644 +--- a/js/ui/main.js ++++ b/js/ui/main.js +@@ -491,7 +491,7 @@ function reloadThemeResource() { + + /** @private */ + function _loadIcons() { +- _iconResource = Gio.Resource.load(`${global.datadir}/gnome-shell-icons.gresource`); ++ _iconResource = Gio.Resource.load(`${global.datadir}/${sessionMode.iconsResourceName}`); + _iconResource._register(); + } + +diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js +index 5478b2a..863df7c 100644 +--- a/js/ui/sessionMode.js ++++ b/js/ui/sessionMode.js +@@ -24,6 +24,7 @@ const _modes = { + parentMode: null, + stylesheetName: 'gnome-shell.css', + themeResourceName: 'gnome-shell-theme.gresource', ++ iconsResourceName: 'gnome-shell-icons.gresource', + hasOverview: false, + showCalendarEvents: false, + showWelcomeDialog: false, diff --git a/debian/patches/ubuntu/shell-global-util-Do-not-move-snap-apps-to-gnome-apps-sco.patch b/debian/patches/ubuntu/shell-global-util-Do-not-move-snap-apps-to-gnome-apps-sco.patch new file mode 100644 index 0000000..0ecf02a --- /dev/null +++ b/debian/patches/ubuntu/shell-global-util-Do-not-move-snap-apps-to-gnome-apps-sco.patch @@ -0,0 +1,75 @@ +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= +Date: Mon, 27 Mar 2023 21:02:02 +0200 +Subject: shell-global, util: Do not move snap apps to gnome-apps scope + +Snap applications already have their own scope so we must not move them. + +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/2011806 +--- + js/misc/util.js | 20 ++++++++++++++++++-- + src/shell-global.c | 7 +++++++ + 2 files changed, 25 insertions(+), 2 deletions(-) + +diff --git a/js/misc/util.js b/js/misc/util.js +index e6065c4..c3c2dc7 100644 +--- a/js/misc/util.js ++++ b/js/misc/util.js +@@ -110,6 +110,20 @@ function spawnApp(argv) { + // this will throw an error. + function trySpawn(argv) { + var success_, pid; ++ let path = argv[0]; ++ ++ if (!path?.includes('/')) { ++ path = GLib.find_program_in_path(argv[0]); ++ if (!path) { ++ throw new GLib.SpawnError({ ++ code: GLib.SpawnError.NOENT, ++ message: _('Command not found'), ++ }); ++ } ++ ++ argv = [path, ...argv.slice(1)]; ++ } ++ + try { + [success_, pid] = GLib.spawn_async( + null, argv, null, +@@ -141,8 +155,10 @@ function trySpawn(argv) { + } + } + +- // Async call, we don't need the reply though +- GnomeDesktop.start_systemd_scope(argv[0], pid, null, null, null, () => {}); ++ if (!path?.includes('/snap/bin') && !argv?.join(' ').includes('snap run')) { ++ // Async call, we don't need the reply though ++ GnomeDesktop.start_systemd_scope(argv[0], pid, null, null, null, () => {}); ++ } + + // Dummy child watch; we don't want to double-fork internally + // because then we lose the parent-child relationship, which +diff --git a/src/shell-global.c b/src/shell-global.c +index f34dc3b..fc475cd 100644 +--- a/src/shell-global.c ++++ b/src/shell-global.c +@@ -1485,6 +1485,7 @@ shell_global_app_launched_cb (GAppLaunchContext *context, + { + gint32 pid; + const gchar *app_name; ++ const gchar *command_line; + + if (!g_variant_lookup (platform_data, "pid", "i", &pid)) + return; +@@ -1498,6 +1499,12 @@ shell_global_app_launched_cb (GAppLaunchContext *context, + if (app_name == NULL) + app_name = g_app_info_get_executable (info); + ++ command_line = g_app_info_get_commandline (info); ++ if (command_line && ++ (strstr (command_line, "/snap/bin") || ++ strstr (command_line, "snap run"))) ++ return; ++ + /* Start async request; we don't care about the result */ + gnome_start_systemd_scope (app_name, + pid, diff --git a/debian/shlibs.local b/debian/shlibs.local new file mode 100644 index 0000000..486e4fa --- /dev/null +++ b/debian/shlibs.local @@ -0,0 +1 @@ +libgnome-bluetooth-applet 0 gnome-bluetooth (>= 3.0.0)