diff --git a/.gitignore b/.gitignore index f98e0b1..afa1cff 100644 --- a/.gitignore +++ b/.gitignore @@ -234,3 +234,4 @@ gnome-shell-2.31.5.tar.bz2 /gnome-shell-47.1.tar.xz /gnome-shell-47.2.tar.xz /gnome-shell-47.3.tar.xz +/gnome-shell-47.4.tar.xz diff --git a/0001-st-theme-Reuse-stylesheets-if-possible.patch b/0001-st-theme-Reuse-stylesheets-if-possible.patch deleted file mode 100644 index f608a92..0000000 --- a/0001-st-theme-Reuse-stylesheets-if-possible.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 4ad7120d0188dcf21146da02637f82bac2ac7ad6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Florian=20M=C3=BCllner?= -Date: Wed, 29 Jan 2025 02:46:44 +0100 -Subject: [PATCH] st/theme: Reuse stylesheets if possible - -The following happens when processing an `@import()` rule: - - 1. `_st_theme_resolve_url()` to resolve file - 2. `insert_stylesheet()` to track file/sheet - a. take ownership of file/sheet (ref) - b. use file as key in `stylesheets_by_file` hash table - c. use file as value in `files_by_stylesheet` hash table - 3. release reference to file - -This leads to a refcount error when importing a file that -was already parsed before: - - 1. file start with refcount 1 - 2. `insert_stylesheet()` - a. increases refcount to 2 - b. inserting into `stylesheets_by_file` *decreases* the - passed-in key if the key already exists - c. `files_by_stylesheet` now tracks a file with recount 1 - 3. releases the last reference to file - -The file object tracked in `files_by_stylesheet` is now invalid, -and accessing it results in a crash. - -Avoid this issue by reusing existing stylesheets, so we don't insert -a stylesheet that's already tracked. - -As a side-effect, this also saves us from re-parsing the same file -unnecessarily. - -Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7306 ---- - src/st/st-theme.c | 32 ++++++++++++++++++++++++++------ - 1 file changed, 26 insertions(+), 6 deletions(-) - -diff --git a/src/st/st-theme.c b/src/st/st-theme.c -index 9867ee1510..9ad99e2b1a 100644 ---- a/src/st/st-theme.c -+++ b/src/st/st-theme.c -@@ -244,6 +244,27 @@ insert_stylesheet (StTheme *theme, - g_hash_table_insert (theme->files_by_stylesheet, stylesheet, file); - } - -+static CRStyleSheet * -+resolve_stylesheet (StTheme *theme, -+ GFile *file, -+ GError **error) -+{ -+ CRStyleSheet *sheet; -+ -+ sheet = g_hash_table_lookup (theme->stylesheets_by_file, file); -+ if (sheet) -+ { -+ cr_stylesheet_ref (sheet); -+ return sheet; -+ } -+ -+ sheet = parse_stylesheet (file, error); -+ if (sheet) -+ insert_stylesheet (theme, file, sheet); -+ -+ return sheet; -+} -+ - /** - * st_theme_load_stylesheet: - * @theme: a #StTheme -@@ -261,13 +282,12 @@ st_theme_load_stylesheet (StTheme *theme, - { - CRStyleSheet *stylesheet; - -- stylesheet = parse_stylesheet (file, error); -+ stylesheet = resolve_stylesheet (theme, file, error); - if (!stylesheet) - return FALSE; - - stylesheet->app_data = GUINT_TO_POINTER (TRUE); - -- insert_stylesheet (theme, file, stylesheet); - cr_stylesheet_ref (stylesheet); - theme->custom_stylesheets = g_slist_prepend (theme->custom_stylesheets, stylesheet); - g_signal_emit (theme, signals[STYLESHEETS_CHANGED], 0); -@@ -884,6 +904,7 @@ add_matched_properties (StTheme *a_this, - - if (import_rule->sheet == NULL) - { -+ CRStyleSheet *sheet = NULL; - GFile *file = NULL; - - if (import_rule->url->stryng && import_rule->url->stryng->str) -@@ -891,13 +912,12 @@ add_matched_properties (StTheme *a_this, - file = _st_theme_resolve_url (a_this, - a_nodesheet, - import_rule->url->stryng->str); -- import_rule->sheet = parse_stylesheet (file, NULL); -+ sheet = resolve_stylesheet (a_this, file, NULL); - } - -- if (import_rule->sheet) -+ if (sheet) - { -- insert_stylesheet (a_this, file, import_rule->sheet); -- /* refcount of stylesheets starts off at zero, so we don't need to unref! */ -+ import_rule->sheet = sheet; - } - else - { --- -2.48.1 - diff --git a/gdm-support-banner-message-file.patch b/gdm-support-banner-message-file.patch new file mode 100644 index 0000000..5157f26 --- /dev/null +++ b/gdm-support-banner-message-file.patch @@ -0,0 +1,232 @@ +From f328eee88c4e700a29625e87fd6fc997a138c66b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 22 Nov 2024 19:23:59 +0100 +Subject: [PATCH 1/3] loginDialog: Split out getBannerText() helper + +The new methods will make it easier to add alternative sources +for the banner text. + +Part-of: +--- + js/gdm/loginDialog.js | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index 27baae83ad..c3c397c0d1 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -873,11 +873,18 @@ export const LoginDialog = GObject.registerClass({ + this._authPrompt.cancelButton.visible = cancelVisible; + } + ++ _getBannerText() { ++ const enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); ++ if (!enabled) ++ return null; ++ ++ return this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); ++ } ++ + _updateBanner() { +- let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); +- let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); ++ const text = this._getBannerText(); + +- if (enabled && text) { ++ if (text) { + this._bannerLabel.set_text(text); + this._bannerLabel.show(); + } else { +-- +2.48.1 + + +From 5f92c12c727bd447d7e539b1e6c8f3ac6ddf715a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 22 Nov 2024 19:36:42 +0100 +Subject: [PATCH 2/3] loginDialog: Update banner asynchronously + +We will soon allow reading the banner text from a file. Prepare +for that by making the method asynchronous. + +Part-of: +--- + js/gdm/loginDialog.js | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index c3c397c0d1..125cf299fa 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -505,9 +505,9 @@ export const LoginDialog = GObject.registerClass({ + this._settings = new Gio.Settings({schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA}); + + this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_KEY}`, +- this._updateBanner.bind(this)); ++ () => this._updateBanner().catch(logError)); + this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_TEXT_KEY}`, +- this._updateBanner.bind(this)); ++ () => this._updateBanner().catch(logError)); + this._settings.connect(`changed::${GdmUtil.DISABLE_USER_LIST_KEY}`, + this._updateDisableUserList.bind(this)); + this._settings.connect(`changed::${GdmUtil.LOGO_KEY}`, +@@ -576,7 +576,7 @@ export const LoginDialog = GObject.registerClass({ + this._bannerLabel.clutter_text.line_wrap = true; + this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; + bannerBox.add_child(this._bannerLabel); +- this._updateBanner(); ++ this._updateBanner().catch(logError); + + this._sessionMenuButton = new SessionMenuButton(); + this._sessionMenuButton.connect('session-activated', +@@ -873,16 +873,19 @@ export const LoginDialog = GObject.registerClass({ + this._authPrompt.cancelButton.visible = cancelVisible; + } + +- _getBannerText() { ++ async _getBannerText() { + const enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); + if (!enabled) + return null; + ++ // placeholder ++ await false; ++ + return this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); + } + +- _updateBanner() { +- const text = this._getBannerText(); ++ async _updateBanner() { ++ const text = await this._getBannerText(); + + if (text) { + this._bannerLabel.set_text(text); +-- +2.48.1 + + +From a73a4f8455b1374b38724a532137a9b614a7fb19 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 22 Nov 2024 19:17:44 +0100 +Subject: [PATCH 3/3] loginDialog: Support loading banner message from file + +Support the new `banner-message-path` and `banner-message-source` +settings, which allows loading the banner message from a path +instead of GSettings. This is mainly useful for `/etc/motd` and +similar mechanisms, to show the same message for both graphical +and non-graphical logins. + +Part-of: +--- + js/gdm/loginDialog.js | 53 +++++++++++++++++++++++++++++++++++++++++-- + js/gdm/util.js | 2 ++ + 2 files changed, 53 insertions(+), 2 deletions(-) + +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index 125cf299fa..fa91615026 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -46,6 +46,8 @@ const _SCROLL_ANIMATION_TIME = 500; + const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; + const _CONFLICTING_SESSION_DIALOG_TIMEOUT = 60; + ++Gio._promisify(Gio.File.prototype, 'load_contents_async'); ++ + export const UserListItem = GObject.registerClass({ + Signals: {'activate': {}}, + }, class UserListItem extends St.Button { +@@ -508,6 +510,16 @@ export const LoginDialog = GObject.registerClass({ + () => this._updateBanner().catch(logError)); + this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_TEXT_KEY}`, + () => this._updateBanner().catch(logError)); ++ this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_SOURCE_KEY}`, ++ () => { ++ if (this._updateBannerMessageFile()) ++ this._updateBanner().catch(logError); ++ }); ++ this._settings.connect(`changed::${GdmUtil.BANNER_MESSAGE_PATH_KEY}`, ++ () => { ++ if (this._updateBannerMessageFile()) ++ this._updateBanner().catch(logError); ++ }); + this._settings.connect(`changed::${GdmUtil.DISABLE_USER_LIST_KEY}`, + this._updateDisableUserList.bind(this)); + this._settings.connect(`changed::${GdmUtil.LOGO_KEY}`, +@@ -576,6 +588,8 @@ export const LoginDialog = GObject.registerClass({ + this._bannerLabel.clutter_text.line_wrap = true; + this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; + bannerBox.add_child(this._bannerLabel); ++ ++ this._updateBannerMessageFile(); + this._updateBanner().catch(logError); + + this._sessionMenuButton = new SessionMenuButton(); +@@ -873,13 +887,48 @@ export const LoginDialog = GObject.registerClass({ + this._authPrompt.cancelButton.visible = cancelVisible; + } + ++ _updateBannerMessageFile() { ++ const path = this._settings.get_string(GdmUtil.BANNER_MESSAGE_SOURCE_KEY) === 'file' ++ ? this._settings.get_string(GdmUtil.BANNER_MESSAGE_PATH_KEY) ++ : null; ++ const file = path ++ ? Gio.File.new_for_path(path) ++ : null; ++ ++ if (!file && !this._bannerMessageFile) ++ return false; ++ ++ if (file && this._bannerMessageFile && this._bannerMessageFile.equal(file)) ++ return false; ++ ++ this._bannerMessageMonitor?.disconnectObject(this); ++ this._bannerMessageMonitor = null; ++ ++ this._bannerMessageFile = file; ++ ++ if (file) { ++ this._bannerMessageMonitor = file.monitor_file(Gio.FileMonitorFlags.NONE, null); ++ this._bannerMessageMonitor.connectObject( ++ 'changed', () => this._updateBanner().catch(logError), this); ++ } ++ ++ return true; ++ } ++ + async _getBannerText() { + const enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); + if (!enabled) + return null; + +- // placeholder +- await false; ++ if (this._bannerMessageFile) { ++ try { ++ const [contents] = await this._bannerMessageFile.load_contents_async(null); ++ return new TextDecoder().decode(contents); ++ } catch (e) { ++ console.error(`Failed to read banner from ${this._bannerMessageFile.get_path()}: ${e.message}`); ++ return null; ++ } ++ } + + return this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); + } +diff --git a/js/gdm/util.js b/js/gdm/util.js +index 1e0154f36f..f6b797c321 100644 +--- a/js/gdm/util.js ++++ b/js/gdm/util.js +@@ -33,7 +33,9 @@ export const PASSWORD_AUTHENTICATION_KEY = 'enable-password-authentication'; + export const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication'; + export const SMARTCARD_AUTHENTICATION_KEY = 'enable-smartcard-authentication'; + export const BANNER_MESSAGE_KEY = 'banner-message-enable'; ++export const BANNER_MESSAGE_SOURCE_KEY = 'banner-message-source'; + export const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text'; ++export const BANNER_MESSAGE_PATH_KEY = 'banner-message-path'; + export const ALLOWED_FAILURES_KEY = 'allowed-failures'; + + export const LOGO_KEY = 'logo'; +-- +2.48.1 + diff --git a/gnome-shell.spec b/gnome-shell.spec index bbad30f..9e42b14 100644 --- a/gnome-shell.spec +++ b/gnome-shell.spec @@ -8,7 +8,7 @@ %endif Name: gnome-shell -Version: 47.3 +Version: 47.4 Release: %autorelease Summary: Window management and application launching for GNOME @@ -30,6 +30,7 @@ Patch: 0001-gdm-Work-around-failing-fingerprint-auth.patch Patch: 0001-screenShield-unblank-when-inserting-smartcard.patch Patch: enforce-smartcard-at-unlock.patch Patch: disable-unlock-entry-until-question.patch +Patch: gdm-support-banner-message-file.patch # Extensions Patch: 0001-extensionDownloader-Refuse-to-override-system-extens.patch @@ -45,7 +46,6 @@ Patch: 0001-data-Update-generated-stylesheets.patch %if 0%{!?almalinux} Patch: 0001-theme-Welcome-Illustration.patch %endif -Patch: 0001-st-theme-Reuse-stylesheets-if-possible.patch %define eds_version 3.45.1 %define gnome_desktop_version 44.0-7 diff --git a/sources b/sources index 8e9f2c4..8f242ab 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gnome-shell-47.3.tar.xz) = d9d553ec0ccdd98fb7878b7bd7f64f966320d34df75c10967c85ceb79edf13a70d0c0898abdc46f3c790246dc387b4586dbfd0cc47ef321ab858f5c4863cc6e2 +SHA512 (gnome-shell-47.4.tar.xz) = 65a0dab1bdd6957e52c624fde21ff3fe1d189aa0d6e2a13035ab53ab51e82ff8a88d28a5308c77d4650d5e1b0f643be702ee767379c96a10308752924c79dd72