diff --git a/patches/Revert-keyboard-Spawn-tecla-to-show-keyboard-map.patch b/patches/Revert-keyboard-Spawn-tecla-to-show-keyboard-map.patch new file mode 100644 index 0000000..ae9cc85 --- /dev/null +++ b/patches/Revert-keyboard-Spawn-tecla-to-show-keyboard-map.patch @@ -0,0 +1,24 @@ +From: =?utf-8?q?Jeremy_B=C3=ADcha?= +Date: Fri, 1 Sep 2023 11:29:45 -0400 +Subject: Revert "keyboard: Spawn "tecla" to show keyboard map" + +Tecla is not ready yet: +https://gitlab.gnome.org/GNOME/tecla/-/issues/7 + +This reverts commit 04aaa4b67bffbfe6d472e7f25c8e892f43151ed2. +--- + js/ui/status/keyboard.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/js/ui/status/keyboard.js b/js/ui/status/keyboard.js +index 8d98e16..106f1e8 100644 +--- a/js/ui/status/keyboard.js ++++ b/js/ui/status/keyboard.js +@@ -1103,6 +1103,6 @@ class InputSourceIndicator extends PanelMenu.Button { + if (xkbVariant.length > 0) + description = `${description}\t${xkbVariant}`; + +- Util.spawn(['tecla', description]); ++ Util.spawn(['gkbd-keyboard-display', '-l', description]); + } + }); diff --git a/patches/Revert-st-Apply-css-foreground-color-to-text-as-a-PangoAt.patch b/patches/Revert-st-Apply-css-foreground-color-to-text-as-a-PangoAt.patch new file mode 100644 index 0000000..c46d831 --- /dev/null +++ b/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 0de195e..ba49101 100644 +--- a/src/st/st-entry.c ++++ b/src/st/st-entry.c +@@ -1101,6 +1101,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/patches/debian/Revert-build-Port-to-gcr4.patch b/patches/debian/Revert-build-Port-to-gcr4.patch new file mode 100644 index 0000000..d5d33cb --- /dev/null +++ b/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/misc/dependencies.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/misc/dependencies.js b/js/misc/dependencies.js +index c61753e..7a827bc 100644 +--- a/js/misc/dependencies.js ++++ b/js/misc/dependencies.js +@@ -7,7 +7,7 @@ import gi from 'gi'; + import 'gi://AccountsService?version=1.0'; + import 'gi://Atk?version=1.0'; + import 'gi://Atspi?version=2.0'; +-import 'gi://Gcr?version=4'; ++import 'gi://Gcr?version=3'; + import 'gi://Gdk?version=4.0'; + import 'gi://Gdm?version=1.0'; + import 'gi://Geoclue?version=2.0'; +diff --git a/meson.build b/meson.build +index 70ba711..8e1f1f4 100644 +--- a/meson.build ++++ b/meson.build +@@ -21,7 +21,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' +@@ -74,7 +74,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 070312b..6a9b266 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -217,7 +217,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/patches/debian/Revert-tests-Fail-on-warnings-too.patch b/patches/debian/Revert-tests-Fail-on-warnings-too.patch new file mode 100644 index 0000000..e0fac85 --- /dev/null +++ b/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 a22a0d9..59070c3 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -56,7 +56,7 @@ libgvc_path = fs.parent(libgvc.get_variable('libgvc').full_path()) + background_file = files(join_paths('data', 'background.png')) + + shell_testenv = environment() +-shell_testenv.set('G_DEBUG', 'fatal-warnings') ++shell_testenv.set('G_DEBUG', 'fatal-criticals') + shell_testenv.set('G_MESSAGES_DEBUG', 'GNOME Shell') + shell_testenv.set('GNOME_SHELL_DATADIR', data_builddir) + shell_testenv.set('GNOME_SHELL_BUILDDIR', src_builddir) diff --git a/patches/debian/gnome-shell-extension-prefs-Give-Debian-specific-advice.patch b/patches/debian/gnome-shell-extension-prefs-Give-Debian-specific-advice.patch new file mode 100644 index 0000000..9759e4b --- /dev/null +++ b/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: gdm/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 | 129 +++++++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 102 insertions(+), 27 deletions(-) + +diff --git a/js/gdm/util.js b/js/gdm/util.js +index 89ad544..3697ecd 100644 +--- a/js/gdm/util.js ++++ b/js/gdm/util.js +@@ -43,6 +43,7 @@ export const DISABLE_USER_LIST_KEY = 'disable-user-list'; + + // Give user 48ms to read each character of a PAM message + const USER_READ_TIME = 48; ++const FINGERPRINT_SERVICE_PROXY_TIMEOUT = 5000; + const FINGERPRINT_ERROR_TIMEOUT_WAIT = 15; + + /** +@@ -108,16 +109,50 @@ export class ShellUserVerifier 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._fprintManager = new FprintManagerProxy(Gio.DBus.system, +- 'net.reactivated.Fprint', +- '/net/reactivated/Fprint/Manager', +- null, +- null, +- Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES); ++ 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._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 +@@ -136,6 +171,7 @@ export class ShellUserVerifier extends Signals.EventEmitter { + this.reauthenticating = false; + + this._failCounter = 0; ++ this._startedServices = new Set(); + this._unavailableServices = new Set(); + + this._credentialManagers = {}; +@@ -225,6 +261,7 @@ export class ShellUserVerifier extends Signals.EventEmitter { + + this._clearUserVerifier(); + this._clearMessageQueue(); ++ this._startedServices.clear(); + } + + destroy() { +@@ -345,27 +382,52 @@ export class ShellUserVerifier 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) { +@@ -466,6 +528,7 @@ export class ShellUserVerifier 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), +@@ -519,6 +582,10 @@ export class ShellUserVerifier 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'); +@@ -557,11 +624,14 @@ export class ShellUserVerifier 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) { +@@ -654,8 +724,9 @@ export class ShellUserVerifier 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'); + } +@@ -736,6 +807,10 @@ export class ShellUserVerifier 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/patches/global-make-possible-to-set-debug-flags-dynamically.patch b/patches/global-make-possible-to-set-debug-flags-dynamically.patch new file mode 100644 index 0000000..ec780b9 --- /dev/null +++ b/patches/global-make-possible-to-set-debug-flags-dynamically.patch @@ -0,0 +1,249 @@ +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 | 61 +++++++++++++++++++++++++++++++++++++++++------------- + src/shell-global.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ + src/shell-global.h | 4 ++++ + 3 files changed, 103 insertions(+), 14 deletions(-) + +diff --git a/src/main.c b/src/main.c +index dca5f64..aa2f4dc 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -374,14 +374,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)); + } + +@@ -483,6 +483,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, +@@ -614,6 +650,7 @@ main (int argc, char **argv) + g_autoptr (GFile) automation_script = NULL; + g_autofree char *cwd = NULL; + GError *error = NULL; ++ const char *debug_flags; + int ecode = EXIT_SUCCESS; + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); +@@ -649,17 +686,6 @@ main (int argc, char **argv) + g_setenv ("GJS_DEBUG_OUTPUT", "stderr", TRUE); + g_setenv ("GJS_DEBUG_TOPICS", "JS ERROR;JS LOG", TRUE); + +- 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); +- } +- + if (script_path) + automation_script = g_file_new_for_commandline_arg_and_cwd (script_path, cwd); + +@@ -668,10 +694,16 @@ main (int argc, char **argv) + * resolve internal modules. + */ + _shell_global_init ("session-mode", session_mode, ++ "debug-flags", debug_flags, + "force-animations", force_animations, + "automation-script", automation_script, + NULL); + ++ g_signal_connect (shell_global_get (), "notify::debug-flags", ++ G_CALLBACK (global_notify_debug_flags), NULL); ++ ++ setup_debug_signal_listners (); ++ + /* Setup Meta _after_ the Shell global to avoid GjsContext + * iterating on the main loop once Meta starts adding events + */ +@@ -681,7 +713,8 @@ main (int argc, char **argv) + return EXIT_FAILURE; + } + +- 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 (); +diff --git a/src/shell-global.c b/src/shell-global.c +index 66b2f57..2a6e7fd 100644 +--- a/src/shell-global.c ++++ b/src/shell-global.c +@@ -62,6 +62,7 @@ struct _ShellGlobal { + Display *xdisplay; + + char *session_mode; ++ char *debug_flags; + + XserverRegion input_region; + +@@ -123,6 +124,7 @@ enum { + PROP_SWITCHEROO_CONTROL, + PROP_FORCE_ANIMATIONS, + PROP_AUTOMATION_SCRIPT, ++ PROP_DEBUG_FLAGS, + + N_PROPS + }; +@@ -255,6 +257,9 @@ shell_global_set_property(GObject *object, + case PROP_AUTOMATION_SCRIPT: + g_set_object (&global->automation_script, g_value_get_object (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; +@@ -347,6 +352,9 @@ shell_global_get_property(GObject *object, + case PROP_AUTOMATION_SCRIPT: + g_value_set_object (value, global->automation_script); + 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; +@@ -704,6 +712,13 @@ shell_global_class_init (ShellGlobalClass *klass) + G_TYPE_FILE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 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); + } + +@@ -2004,3 +2019,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/patches/magnifier-Show-cursor-when-magnifier-is-enabled-and-scale.patch b/patches/magnifier-Show-cursor-when-magnifier-is-enabled-and-scale.patch new file mode 100644 index 0000000..78e4b3e --- /dev/null +++ b/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 3ba9b96..4d5cd5a 100644 +--- a/js/ui/layout.js ++++ b/js/ui/layout.js +@@ -981,22 +981,38 @@ export const LayoutManager = GObject.registerClass({ + return ws.get_work_area_for_monitor(monitorIndex); + } + ++ _findIndexForRect(x, y, width, height) { ++ const rect = new Mtk.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(); +- const rect = new Mtk.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 ab8150b..13da38f 100644 +--- a/js/ui/magnifier.js ++++ b/js/ui/magnifier.js +@@ -51,6 +51,8 @@ const MouseSpriteContent = GObject.registerClass({ + }, class MouseSpriteContent extends GObject.Object { + _init() { + super._init(); ++ this._scale = 1.0; ++ this._monitorScale = 1.0; + this._texture = null; + } + +@@ -58,7 +60,10 @@ const 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) { +@@ -75,6 +80,29 @@ const 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; + } +@@ -89,7 +117,19 @@ const 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(); + } + }); +@@ -121,6 +161,8 @@ export 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); + }); +@@ -128,6 +170,13 @@ export 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. +@@ -269,6 +318,8 @@ export 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/patches/main-add-backtrace-crashes-all-and-backtrace-all.patch b/patches/main-add-backtrace-crashes-all-and-backtrace-all.patch new file mode 100644 index 0000000..ac395de --- /dev/null +++ b/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 619136a..0aa224b 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -59,6 +59,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 08952b8..e60b574 100644 +--- a/src/shell-global.c ++++ b/src/shell-global.c +@@ -2045,6 +2045,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/patches/main-increase-the-granularity-of-backtraces-in-SHELL_DEBU.patch b/patches/main-increase-the-granularity-of-backtraces-in-SHELL_DEBU.patch new file mode 100644 index 0000000..661326e --- /dev/null +++ b/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 aa2f4dc..619136a 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -43,16 +43,26 @@ static char *session_mode = NULL; + static int caught_signal = 0; + static gboolean force_animations = FALSE; + static char *script_path = NULL; ++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, +@@ -376,13 +386,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 +@@ -493,10 +513,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)) + { +@@ -649,8 +682,9 @@ main (int argc, char **argv) + g_autoptr (MetaContext) context = NULL; + g_autoptr (GFile) automation_script = NULL; + g_autofree char *cwd = 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); +@@ -694,7 +728,7 @@ main (int argc, char **argv) + * resolve internal modules. + */ + _shell_global_init ("session-mode", session_mode, +- "debug-flags", debug_flags, ++ "debug-flags", debug_flags_string, + "force-animations", force_animations, + "automation-script", automation_script, + NULL); +@@ -713,8 +747,14 @@ main (int argc, char **argv) + return EXIT_FAILURE; + } + +- 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 (); +diff --git a/src/shell-global.c b/src/shell-global.c +index 2a6e7fd..08952b8 100644 +--- a/src/shell-global.c ++++ b/src/shell-global.c +@@ -2037,11 +2037,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/patches/main-show-an-error-message-on-gnome-shell-crash.patch b/patches/main-show-an-error-message-on-gnome-shell-crash.patch new file mode 100644 index 0000000..951e6da --- /dev/null +++ b/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 dec0efa..dca5f64 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -444,6 +444,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/patches/series b/patches/series new file mode 100644 index 0000000..cec3607 --- /dev/null +++ b/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 +Revert-keyboard-Spawn-tecla-to-show-keyboard-map.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/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/patches/sessionMode-add-support-for-debugFlags-parameter.patch b/patches/sessionMode-add-support-for-debugFlags-parameter.patch new file mode 100644 index 0000000..92e5c15 --- /dev/null +++ b/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 6240b12..b3fff22 100644 +--- a/js/ui/main.js ++++ b/js/ui/main.js +@@ -136,6 +136,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(':')) ++ } + } + + /** @returns {void} */ +diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js +index e27f4fa..45320ea 100644 +--- a/js/ui/sessionMode.js ++++ b/js/ui/sessionMode.js +@@ -32,6 +32,7 @@ const _modes = { + showWelcomeDialog: false, + allowSettings: false, + allowScreencast: false, ++ debugFlags: [], + enabledExtensions: [], + hasRunDialog: false, + hasWorkspaces: false, diff --git a/patches/ubuntu/background_login.patch b/patches/ubuntu/background_login.patch index e5f9566..10bc2eb 100644 --- a/patches/ubuntu/background_login.patch +++ b/patches/ubuntu/background_login.patch @@ -12,22 +12,33 @@ Author: Marco Trevisan Last-Update: 2022-08-30 Forwarded: not-needed --- - js/ui/background.js | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) + js/ui/background.js | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/js/ui/background.js b/js/ui/background.js -index a1f6601..4717f46 100644 +index 8301330..cef7c87 100644 --- a/js/ui/background.js +++ b/js/ui/background.js -@@ -528,7 +528,16 @@ var SystemBackground = GObject.registerClass({ +@@ -101,8 +101,10 @@ import GObject from 'gi://GObject'; + import GnomeBG from 'gi://GnomeBG'; + import GnomeDesktop from 'gi://GnomeDesktop'; + import Meta from 'gi://Meta'; ++import St from 'gi://St'; + import * as Signals from '../misc/signals.js'; + ++import * as Desktop from '../misc/desktop.js'; + import * as LoginManager from '../misc/loginManager.js'; + import * as Main from './main.js'; + import * as Params from '../misc/params.js'; +@@ -538,7 +540,16 @@ export const SystemBackground = GObject.registerClass({ _init() { if (_systemBackground == null) { - _systemBackground = new Meta.Background({ meta_display: global.display }); + _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' }); ++ if (Desktop.is('ubuntu')) { ++ const dummyBgActor = new St.Widget({name: 'lockDialogGroup'}); + Main.uiGroup.add_actor(dummyBgActor); + backgroundColor = dummyBgActor.get_theme_node().get_background_color(); + dummyBgActor.destroy(); diff --git a/patches/ubuntu/configure_login_screen.patch b/patches/ubuntu/configure_login_screen.patch new file mode 100644 index 0000000..a4d93e8 --- /dev/null +++ b/patches/ubuntu/configure_login_screen.patch @@ -0,0 +1,211 @@ +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 | 42 +++++++++++++++++ + 4 files changed, 123 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 cef7c87..0da99da 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -543,7 +543,11 @@ export const SystemBackground = GObject.registerClass({ + + let backgroundColor = DEFAULT_BACKGROUND_COLOR; + if (Desktop.is('ubuntu')) { ++ const loginSettings = new Gio.Settings({schema_id: 'com.ubuntu.login-screen'}); ++ const bgColor = loginSettings.get_string('background-color'); + const dummyBgActor = new 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 993e436..c27f44b 100644 +--- a/js/ui/screenShield.js ++++ b/js/ui/screenShield.js +@@ -33,6 +33,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, +@@ -116,6 +122,16 @@ export class ScreenShield 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; +@@ -216,6 +232,31 @@ export class ScreenShield 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 && !backgroundColor.includes('rgba')) ++ 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}`); ++ ++ const lockDialogGroupStyle = inlineStyle.join('; ') || null; ++ this._lockDialogGroup.set_style(lockDialogGroupStyle); ++ this._dialog?.set_style(lockDialogGroupStyle ? ` ++ background-image: none; ++ background-color: transparent;` : null); ++ } ++ + async _syncInhibitor() { + const lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY) || + this._settings.get_boolean(SUSPEND_LOCK_ENABLED_KEY); +@@ -433,6 +474,7 @@ export class ScreenShield extends Signals.EventEmitter { + } + + this._dialog = new constructor(this._lockDialogGroup); ++ this._refreshBackground(); + + let time = global.get_current_time(); + if (!this._dialog.open(time)) { diff --git a/patches/ubuntu/darkMode-Add-support-to-Yaru-theme-color-variants.patch b/patches/ubuntu/darkMode-Add-support-to-Yaru-theme-color-variants.patch new file mode 100644 index 0000000..25fc00d --- /dev/null +++ b/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 | 42 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 41 insertions(+), 1 deletion(-) + +diff --git a/js/ui/status/darkMode.js b/js/ui/status/darkMode.js +index 4e68a74..321a88b 100644 +--- a/js/ui/status/darkMode.js ++++ b/js/ui/status/darkMode.js +@@ -1,5 +1,6 @@ + import Gio from 'gi://Gio'; + import GObject from 'gi://GObject'; ++import St from 'gi://St'; + + import * as Main from '../main.js'; + +@@ -19,6 +20,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(), +@@ -28,13 +32,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/patches/ubuntu/desktop_detect.patch b/patches/ubuntu/desktop_detect.patch new file mode 100644 index 0000000..b6477a2 --- /dev/null +++ b/patches/ubuntu/desktop_detect.patch @@ -0,0 +1,65 @@ +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 ee4b763..a69c004 100644 +--- a/js/js-resources.gresource.xml ++++ b/js/js-resources.gresource.xml +@@ -17,6 +17,7 @@ + misc/animationUtils.js + misc/config.js + misc/extensionUtils.js ++ misc/desktop.js + misc/fileUtils.js + misc/dateUtils.js + misc/dbusUtils.js +diff --git a/js/misc/desktop.js b/js/misc/desktop.js +new file mode 100644 +index 0000000..05044c1 +--- /dev/null ++++ b/js/misc/desktop.js +@@ -0,0 +1,33 @@ ++// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- ++ ++import GLib from '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. ++export 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/patches/ubuntu/gdm_alternatives.patch b/patches/ubuntu/gdm_alternatives.patch new file mode 100644 index 0000000..bb7bb9b --- /dev/null +++ b/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 8a4948e..5fbb672 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-dark.css + gnome-shell-dark.css + gnome-shell-light.css + gnome-shell-high-contrast.css +diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js +index 8e30a66..e27f4fa 100644 +--- a/js/ui/sessionMode.js ++++ b/js/ui/sessionMode.js +@@ -53,6 +53,8 @@ const _modes = { + + 'gdm': { + hasNotifications: true, ++ stylesheetName: 'gdm.css', ++ themeResourceName: 'gdm-theme.gresource', + isGreeter: true, + isPrimary: true, + unlockDialog: LoginDialog, diff --git a/patches/ubuntu/keep-ubuntu-logo-bright-lp1867133-v1.patch b/patches/ubuntu/keep-ubuntu-logo-bright-lp1867133-v1.patch new file mode 100644 index 0000000..a182de5 --- /dev/null +++ b/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 a3e4372..104fb93 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -1272,7 +1272,11 @@ export const 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}); + +@@ -1280,6 +1284,7 @@ export const 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/patches/ubuntu/layout-Try-to-allocate-before-getting-size-of-tracke.patch b/patches/ubuntu/layout-Try-to-allocate-before-getting-size-of-tracke.patch new file mode 100644 index 0000000..27f7ec7 --- /dev/null +++ b/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 4d5cd5a..06ed440 100644 +--- a/js/ui/layout.js ++++ b/js/ui/layout.js +@@ -1058,6 +1058,7 @@ export const 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/patches/ubuntu/lightdm-user-switching.patch b/patches/ubuntu/lightdm-user-switching.patch new file mode 100644 index 0000000..6fc4078 --- /dev/null +++ b/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 efb875b..75a7016 100644 +--- a/js/misc/systemActions.js ++++ b/js/misc/systemActions.js +@@ -231,6 +231,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(); + +@@ -332,7 +360,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'); + } + +@@ -420,20 +448,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/patches/ubuntu/lock_on_suspend.patch b/patches/ubuntu/lock_on_suspend.patch new file mode 100644 index 0000000..e494912 --- /dev/null +++ b/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 f8c59fa..993e436 100644 +--- a/js/ui/screenShield.js ++++ b/js/ui/screenShield.js +@@ -26,6 +26,7 @@ import {adjustAnimationTime} from '../misc/animationUtils.js'; + 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'; +@@ -110,6 +111,7 @@ export class ScreenShield 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)); +@@ -215,7 +217,8 @@ export class ScreenShield 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 && +@@ -246,7 +249,7 @@ export class ScreenShield 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/patches/ubuntu/main-Support-loading-multiple-Yaru-theme-variants.patch b/patches/ubuntu/main-Support-loading-multiple-Yaru-theme-variants.patch index 02b5109..5f9e703 100644 --- a/patches/ubuntu/main-Support-loading-multiple-Yaru-theme-variants.patch +++ b/patches/ubuntu/main-Support-loading-multiple-Yaru-theme-variants.patch @@ -70,32 +70,32 @@ index 0000000..6f9cc62 + + diff --git a/js/ui/main.js b/js/ui/main.js -index b39bcf4..0d786b1 100644 +index e5921eb..2c6c580 100644 --- a/js/ui/main.js +++ b/js/ui/main.js -@@ -186,6 +186,9 @@ function start() { - sessionMode.connect('updated', _sessionUpdated); +@@ -163,6 +163,9 @@ export async function start() { St.Settings.get().connect('notify::high-contrast', _loadDefaultStylesheet); + St.Settings.get().connect('notify::color-scheme', _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; +@@ -434,6 +437,38 @@ export function getStyleVariant() { + } } +function _getYaruStyleSheet(themeVariant) { -+ const { shellColorScheme: colorScheme } = St.Settings.get(); ++ const styleVariant = getStyleVariant() || 'light'; + const baseThemeName = sessionMode.stylesheetName.split(".css").at(0); + const isDark = themeVariant === 'dark' || themeVariant?.endsWith('-dark'); + let colorSchemeVariant; + -+ if (isDark && colorScheme == 'prefer-light') { ++ if (isDark && styleVariant === 'light') { + colorSchemeVariant = themeVariant.split('-').slice(0, -1).join('-'); -+ } else if (!isDark && colorScheme == 'prefer-dark' ) { ++ } else if (!isDark && styleVariant == 'dark' ) { + colorSchemeVariant = themeVariant ? `${themeVariant}-dark` : 'dark'; + } + @@ -133,15 +133,15 @@ index b39bcf4..0d786b1 100644 + stylesheet = _getYaruStyleSheet(settings.gtkThemeVariant?.toLowerCase()); + } + - if (stylesheet == null) - stylesheet = _getStylesheet(sessionMode.stylesheetName); + if (stylesheet === null) + stylesheet = _getStylesheet(name.replace('.css', `-${getStyleVariant()}.css`)); diff --git a/src/st/st-settings.c b/src/st/st-settings.c -index 04bf68f..cb625b2 100644 +index 790ec64..de6db1b 100644 --- a/src/st/st-settings.c +++ b/src/st/st-settings.c -@@ -33,6 +33,8 @@ - #define KEY_FONT_NAME "font-name" +@@ -35,6 +35,8 @@ + #define KEY_COLOR_SCHEME "color-scheme" #define KEY_HIGH_CONTRAST "high-contrast" #define KEY_GTK_ICON_THEME "icon-theme" +#define KEY_GTK_THEME "gtk-theme" @@ -149,9 +149,9 @@ index 04bf68f..cb625b2 100644 #define KEY_MAGNIFIER_ACTIVE "screen-magnifier-enabled" #define KEY_DISABLE_SHOW_PASSWORD "disable-show-password" -@@ -43,7 +45,10 @@ enum { - PROP_DRAG_THRESHOLD, +@@ -46,7 +48,10 @@ enum { PROP_FONT_NAME, + PROP_COLOR_SCHEME, PROP_HIGH_CONTRAST, + PROP_GTK_THEME, + PROP_GTK_THEME_VARIANT, @@ -160,7 +160,7 @@ index 04bf68f..cb625b2 100644 PROP_MAGNIFIER_ACTIVE, PROP_SLOW_DOWN_FACTOR, PROP_DISABLE_SHOW_PASSWORD, -@@ -60,10 +65,13 @@ struct _StSettings +@@ -63,10 +68,13 @@ struct _StSettings GSettings *a11y_applications_settings; GSettings *a11y_interface_settings; GSettings *lockdown_settings; @@ -174,7 +174,7 @@ index 04bf68f..cb625b2 100644 int inhibit_animations_count; gboolean enable_animations; gboolean primary_paste; -@@ -133,7 +141,10 @@ st_settings_finalize (GObject *object) +@@ -137,7 +145,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); @@ -185,7 +185,7 @@ index 04bf68f..cb625b2 100644 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, +@@ -189,6 +200,16 @@ st_settings_get_property (GObject *object, case PROP_GTK_ICON_THEME: g_value_set_string (value, settings->gtk_icon_theme); break; @@ -199,12 +199,12 @@ index 04bf68f..cb625b2 100644 + 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); + case PROP_COLOR_SCHEME: + g_value_set_enum (value, settings->color_scheme); break; -@@ -275,6 +296,39 @@ st_settings_class_init (StSettingsClass *klass) - "", - ST_PARAM_READABLE); +@@ -294,6 +315,39 @@ st_settings_class_init (StSettingsClass *klass) + ST_SYSTEM_COLOR_SCHEME_DEFAULT, + ST_PARAM_READABLE); + /** + * StSettings:gtk-theme: @@ -242,7 +242,7 @@ index 04bf68f..cb625b2 100644 /** * StSettings:magnifier-active: * -@@ -311,6 +365,45 @@ st_settings_class_init (StSettingsClass *klass) +@@ -330,6 +384,45 @@ st_settings_class_init (StSettingsClass *klass) g_object_class_install_properties (object_class, N_PROPS, props); } @@ -288,7 +288,7 @@ index 04bf68f..cb625b2 100644 static void on_interface_settings_changed (GSettings *g_settings, const gchar *key, -@@ -332,6 +425,10 @@ on_interface_settings_changed (GSettings *g_settings, +@@ -351,6 +444,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]); } @@ -299,9 +299,9 @@ index 04bf68f..cb625b2 100644 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, +@@ -364,6 +461,23 @@ on_interface_settings_changed (GSettings *g_settings, g_object_notify_by_pspec (G_OBJECT (settings), - props[PROP_GTK_ICON_THEME]); + props[PROP_COLOR_SCHEME]); } + else if (g_str_equal (key, KEY_COLOR_SCHEME)) + { @@ -323,7 +323,7 @@ index 04bf68f..cb625b2 100644 } static void -@@ -398,6 +512,10 @@ st_settings_init (StSettings *settings) +@@ -423,6 +537,10 @@ st_settings_init (StSettings *settings) g_signal_connect (settings->interface_settings, "changed", G_CALLBACK (on_interface_settings_changed), settings); @@ -334,7 +334,7 @@ index 04bf68f..cb625b2 100644 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) +@@ -439,6 +557,8 @@ st_settings_init (StSettings *settings) g_signal_connect (settings->lockdown_settings, "changed", G_CALLBACK (on_lockdown_settings_changed), settings); diff --git a/patches/ubuntu/resolve_alternate_theme_path.patch b/patches/ubuntu/resolve_alternate_theme_path.patch new file mode 100644 index 0000000..aa33406 --- /dev/null +++ b/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 b3fff22..8c0664a 100644 +--- a/js/ui/main.js ++++ b/js/ui/main.js +@@ -385,6 +385,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; + +@@ -395,12 +403,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/patches/ubuntu/search-call-XUbuntuCancel-method-on-providers-when-no-dat.patch b/patches/ubuntu/search-call-XUbuntuCancel-method-on-providers-when-no-dat.patch new file mode 100644 index 0000000..62a41d7 --- /dev/null +++ b/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 6bd282b..4804bdd 100644 +--- a/js/ui/remoteSearch.js ++++ b/js/ui/remoteSearch.js +@@ -29,6 +29,7 @@ const SearchProviderIface = ` + + + ++ + + `; + +@@ -57,6 +58,7 @@ const SearchProvider2Iface = ` + + + ++ + + `; + +@@ -307,6 +309,16 @@ class RemoteSearchProvider { + 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 b938b03..4e68bd7 100644 +--- a/js/ui/search.js ++++ b/js/ui/search.js +@@ -224,7 +224,9 @@ const 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) +@@ -602,6 +604,10 @@ export const 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()); + +@@ -650,11 +656,31 @@ export const 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; + +@@ -726,6 +752,13 @@ export const 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/patches/ubuntu/secure_mode_extension.patch b/patches/ubuntu/secure_mode_extension.patch new file mode 100644 index 0000000..403bf7a --- /dev/null +++ b/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 eb17579..eb2d12d 100644 +--- a/js/ui/extensionDownloader.js ++++ b/js/ui/extensionDownloader.js +@@ -7,6 +7,7 @@ import GObject from 'gi://GObject'; + import Soup from 'gi://Soup'; + + import * as Config from '../misc/config.js'; ++import * as Desktop from '../misc/desktop.js'; + import * as Dialog from './dialog.js'; + import * as ExtensionUtils from '../misc/extensionUtils.js'; + import * as FileUtils from '../misc/fileUtils.js'; +@@ -35,6 +36,13 @@ export 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)); +@@ -194,6 +202,9 @@ export 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 21b3b19..25260ec 100644 +--- a/js/ui/extensionSystem.js ++++ b/js/ui/extensionSystem.js +@@ -8,6 +8,7 @@ import Shell from 'gi://Shell'; + import * as Signals from '../misc/signals.js'; + + import * as Config from '../misc/config.js'; ++import * as Desktop from '../misc/desktop.js'; + import * as ExtensionDownloader from './extensionDownloader.js'; + import {ExtensionState, ExtensionType} from '../misc/extensionUtils.js'; + import * as FileUtils from '../misc/fileUtils.js'; +@@ -502,6 +503,10 @@ export class ExtensionManager extends Signals.EventEmitter { + await this.loadExtension(newExtension); + } + ++ isModeExtension(uuid) { ++ return this._getModeExtensions().indexOf(uuid) !== -1; ++ } ++ + async _callExtensionInit(uuid) { + if (!this._extensionSupportsSessionMode(uuid)) + return false; +@@ -709,6 +714,10 @@ export class ExtensionManager 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/patches/ubuntu/sessionMode-Add-support-for-configuring-an-icons-resource.patch b/patches/ubuntu/sessionMode-Add-support-for-configuring-an-icons-resource.patch new file mode 100644 index 0000000..8f3cac6 --- /dev/null +++ b/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 8c0664a..e5921eb 100644 +--- a/js/ui/main.js ++++ b/js/ui/main.js +@@ -547,7 +547,7 @@ export 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 45320ea..a34cf90 100644 +--- a/js/ui/sessionMode.js ++++ b/js/ui/sessionMode.js +@@ -27,6 +27,7 @@ const _modes = { + stylesheetName: 'gnome-shell.css', + colorScheme: 'prefer-dark', + themeResourceName: 'gnome-shell-theme.gresource', ++ iconsResourceName: 'gnome-shell-icons.gresource', + hasOverview: false, + showCalendarEvents: false, + showWelcomeDialog: false, diff --git a/patches/ubuntu/shell-global-util-Do-not-move-snap-apps-to-gnome-apps-sco.patch b/patches/ubuntu/shell-global-util-Do-not-move-snap-apps-to-gnome-apps-sco.patch new file mode 100644 index 0000000..bb667ad --- /dev/null +++ b/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 0201fd1..22d9a5a 100644 +--- a/js/misc/util.js ++++ b/js/misc/util.js +@@ -119,6 +119,20 @@ export function spawnApp(argv) { + */ + export function trySpawn(argv) { + let 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, +@@ -150,8 +164,10 @@ export 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 e60b574..a0c3d5c 100644 +--- a/src/shell-global.c ++++ b/src/shell-global.c +@@ -1501,6 +1501,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; +@@ -1514,6 +1515,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,