debdiff *.dsc | filterdiff -p1 -x.gitlab-ci.yml -x'po/*.po'

diff -Nru gnome-shell-48.2/data/default-apps/utilities-folder.txt gnome-shell-48.3/data/default-apps/utilities-folder.txt
--- gnome-shell-48.2/data/default-apps/utilities-folder.txt	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/data/default-apps/utilities-folder.txt	2025-06-29 11:35:41.000000000 +0100
@@ -1,8 +1,8 @@
 # Sorted by name as shown in menus, not filename
-org.gnome.Decibels                        # Audio Player
+org.gnome.Decibels.desktop                # Audio Player
 org.gnome.Connections.desktop             # Connections
 org.gnome.Evince.desktop                  # Document Viewer
 org.gnome.FileRoller.desktop              # File Roller
 org.gnome.font-viewer.desktop             # Fonts
 org.gnome.Loupe.desktop                   # Image Viewer
-org.gnome.seahorse.Application.desktop    # Passwords and Keys
\ No newline at end of file
+org.gnome.seahorse.Application.desktop    # Passwords and Keys
diff -Nru gnome-shell-48.2/debian/changelog gnome-shell-48.3/debian/changelog
--- gnome-shell-48.2/debian/changelog	2025-06-12 21:08:12.000000000 +0100
+++ gnome-shell-48.3/debian/changelog	2025-07-13 12:24:58.000000000 +0100
@@ -1,3 +1,61 @@
+gnome-shell (48.3-1) unstable; urgency=medium
+
+  * Team upload
+  * New upstream stable release
+    - Accessibility improvements (LP: #2115948)
+      + In the Alt+F2 "run" dialog, provide the dialog title to screen
+        readers and other accessibility tools (gnome-shell!3736 upstream)
+      + In the calendar/notifications menu, label the Events and Weather
+        areas for accessibility tools (gnome-shell!3769 upstream)
+      + In popup menus, tell accessibility tools that separators are
+        not useful to select (gnome-shell!3773 upstream)
+      + In text entry widgets, send the hint (placeholder text) to
+        accessibility tools (gnome-shell!3179 upstream)
+      + In text entry widgets, make the label available to accessibility
+        tools (gnome-shell!3179 upstream)
+      + When running as a gdm greeter, if there is an error such as a wrong
+        password, send it to the screen reader as well as displaying it
+        (gnome-shell!3765 upstream)
+    - When prompting for a password change via Gcr, if the repeated password
+      doesn't match, re-enable the UI widgets so the user can try again
+      (gnome-shell!3757 upstream)
+    - Always update on-screen keyboard layout to reflect the purpose hint,
+      so that the expected features appear (alphanumeric vs. numeric-only,
+      emoji chooser shown or hidden, etc.)
+      (gnome-shell#8377 upstream)
+    - Limit the length of the input method indicator by counting grapheme
+      clusters rather than UTF-16 string lengths, allowing input methods like
+      ibus-typing-booster to use emoji as their indicator
+      (gnome-shell#1026 upstream)
+    - Avoid the top bar disappearing when doing a 3-finger downward swipe
+      gesture on a touchscreen
+      (gnome-shell#7456 upstream)
+    - If Decibels is installed, put it in the Utilities folder as intended
+      (Decibels is not yet in Debian, ITP: #1100886)
+      (gnome-shell!3728 upstream)
+    - If the mouse button modifier (normally Super, i.e. the Windows key)
+      is set to a combination of modifiers such as <Control><Super>, only
+      make the mouse wheel switch between desktops if *all* of those
+      modifiers are held
+      (mutter#4129 upstream)
+    - Avoid flooding the systemd journal with old time-limit transitions if
+      debug messages are enabled
+      (gnome-shell!3740 upstream)
+    - Reuse one proxy object for all communication with the gdm greeter,
+      which is more efficient and can mitigate per-connection memory
+      leaks in gdm
+      (gnome-shell!3749 upstream)
+    - Better build-time compatibility with non-glibc libc
+      (gnome-shell#8457 upstream, no practical effect on Debian)
+    - Remove redundant eslint hints
+      (gnome-shell!3756 upstream, no practical effect since they're comments)
+    - Translation updates
+    - CI changes with no effect on Debian
+  * d/patches: Re-export patch series (no functional changes)
+  * d/control: Update Homepage field (Closes: #1100764)
+
+ -- Simon McVittie <smcv@debian.org>  Sun, 13 Jul 2025 12:24:58 +0100
+
 gnome-shell (48.2-3) unstable; urgency=medium
 
   * Team upload
diff -Nru gnome-shell-48.2/debian/control gnome-shell-48.3/debian/control
--- gnome-shell-48.2/debian/control	2025-06-12 21:08:12.000000000 +0100
+++ gnome-shell-48.3/debian/control	2025-07-13 12:24:58.000000000 +0100
@@ -68,8 +68,8 @@
                xwayland <!nocheck>
 Rules-Requires-Root: no
 Standards-Version: 4.7.2
-Homepage: https://wiki.gnome.org/Projects/GnomeShell
-Vcs-Git: https://salsa.debian.org/gnome-team/gnome-shell.git
+Homepage: https://gitlab.gnome.org/GNOME/gnome-shell
+Vcs-Git: https://salsa.debian.org/gnome-team/gnome-shell.git -b debian/trixie
 Vcs-Browser: https://salsa.debian.org/gnome-team/gnome-shell
 
 Package: gnome-shell
diff -Nru gnome-shell-48.2/debian/gbp.conf gnome-shell-48.3/debian/gbp.conf
--- gnome-shell-48.2/debian/gbp.conf	2025-06-12 21:08:12.000000000 +0100
+++ gnome-shell-48.3/debian/gbp.conf	2025-07-13 12:24:58.000000000 +0100
@@ -1,7 +1,7 @@
 [DEFAULT]
 pristine-tar = True
-debian-branch = debian/latest
-upstream-branch = upstream/latest
+debian-branch = debian/trixie
+upstream-branch = upstream/48.x
 
 [buildpackage]
 sign-tags = True
diff -Nru gnome-shell-48.2/debian/patches/tray-icons/build-Add-explicit-dependency-on-Xfixes.patch gnome-shell-48.3/debian/patches/tray-icons/build-Add-explicit-dependency-on-Xfixes.patch
--- gnome-shell-48.2/debian/patches/tray-icons/build-Add-explicit-dependency-on-Xfixes.patch	2025-06-12 21:08:12.000000000 +0100
+++ gnome-shell-48.3/debian/patches/tray-icons/build-Add-explicit-dependency-on-Xfixes.patch	2025-07-13 12:24:58.000000000 +0100
@@ -13,7 +13,7 @@
  2 files changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/meson.build b/meson.build
-index 94d717f..03a3b2a 100644
+index ffae529..e0ac102 100644
 --- a/meson.build
 +++ b/meson.build
 @@ -93,6 +93,7 @@ have_x11 = mutter_dep.get_variable('have_x11') == 'true'
diff -Nru gnome-shell-48.2/debian/patches/tray-icons/tray-na-xembed-Use-XShape-to-remove-input-on-socket-windo.patch gnome-shell-48.3/debian/patches/tray-icons/tray-na-xembed-Use-XShape-to-remove-input-on-socket-windo.patch
--- gnome-shell-48.2/debian/patches/tray-icons/tray-na-xembed-Use-XShape-to-remove-input-on-socket-windo.patch	2025-06-12 21:08:12.000000000 +0100
+++ gnome-shell-48.3/debian/patches/tray-icons/tray-na-xembed-Use-XShape-to-remove-input-on-socket-windo.patch	2025-07-13 12:24:58.000000000 +0100
@@ -25,7 +25,7 @@
  3 files changed, 17 insertions(+), 1 deletion(-)
 
 diff --git a/meson.build b/meson.build
-index 03a3b2a..3d0f5e5 100644
+index e0ac102..6564149 100644
 --- a/meson.build
 +++ b/meson.build
 @@ -93,6 +93,7 @@ have_x11 = mutter_dep.get_variable('have_x11') == 'true'
diff -Nru gnome-shell-48.2/debian/watch gnome-shell-48.3/debian/watch
--- gnome-shell-48.2/debian/watch	2025-06-12 21:08:12.000000000 +0100
+++ gnome-shell-48.3/debian/watch	2025-07-13 12:24:58.000000000 +0100
@@ -1,4 +1,4 @@
 version=4
 opts="searchmode=plain, uversionmangle=s/\.(alpha|beta|rc)/~$1/, downloadurlmangle=s|cache.json||" \
 https://download.gnome.org/sources/@PACKAGE@/cache.json \
-	[\d.]+/@PACKAGE@-([\d.]+\.?(?:beta|rc)?[\d.]*)@ARCHIVE_EXT@
+	48/@PACKAGE@-([\d.]+\.?(?:beta|rc)?[\d.]*)@ARCHIVE_EXT@
diff -Nru gnome-shell-48.2/js/dbusServices/extensions/extensionPrefsDialog.js gnome-shell-48.3/js/dbusServices/extensions/extensionPrefsDialog.js
--- gnome-shell-48.2/js/dbusServices/extensions/extensionPrefsDialog.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/dbusServices/extensions/extensionPrefsDialog.js	2025-06-29 11:35:41.000000000 +0100
@@ -46,7 +46,6 @@
         this.set_titlebar(w);
     }
 
-    // eslint-disable-next-line camelcase
     set_titlebar() {
         // intercept fatal libadwaita error, show error page instead
         GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
diff -Nru gnome-shell-48.2/js/gdm/authPrompt.js gnome-shell-48.3/js/gdm/authPrompt.js
--- gnome-shell-48.2/js/gdm/authPrompt.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/gdm/authPrompt.js	2025-06-29 11:35:41.000000000 +0100
@@ -1,5 +1,6 @@
 import Clutter from 'gi://Clutter';
 import GLib from 'gi://GLib';
+import Atk from 'gi://Atk';
 import GObject from 'gi://GObject';
 import Pango from 'gi://Pango';
 import Shell from 'gi://Shell';
@@ -571,6 +572,7 @@
             this._message.remove_all_transitions();
             this._message.text = message;
             this._message.opacity = 255;
+            this.get_accessible().emit('notification', message, Atk.Live.ASSERTIVE);
         } else {
             this._message.opacity = 0;
         }
diff -Nru gnome-shell-48.2/js/gdm/loginDialog.js gnome-shell-48.3/js/gdm/loginDialog.js
--- gnome-shell-48.2/js/gdm/loginDialog.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/gdm/loginDialog.js	2025-06-29 11:35:41.000000000 +0100
@@ -990,10 +990,10 @@
         this._showPrompt();
     }
 
-    _resetGreeterProxy() {
+    _ensureGreeterProxy() {
         if (GLib.getenv('GDM_GREETER_TEST') !== '1') {
             if (this._greeter)
-                this._greeter.run_dispose();
+                return;
 
             this._greeter = this._gdmClient.get_greeter_sync(null);
 
@@ -1005,7 +1005,7 @@
     }
 
     _onReset(authPrompt, beginRequest) {
-        this._resetGreeterProxy();
+        this._ensureGreeterProxy();
         this._sessionMenuButton.updateSensitivity(true);
 
         const previousUser = this._user;
diff -Nru gnome-shell-48.2/js/misc/timeLimitsManager.js gnome-shell-48.3/js/misc/timeLimitsManager.js
--- gnome-shell-48.2/js/misc/timeLimitsManager.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/misc/timeLimitsManager.js	2025-06-29 11:35:41.000000000 +0100
@@ -455,7 +455,8 @@
         }
     }
 
-    _addTransition(oldState, newState, wallTimeSecs, recalculateState = true) {
+    _addTransition(oldState, newState, wallTimeSecs,
+        {recalculateState = true, debugLog = true} = {}) {
         this._stateTransitions.push({
             oldState,
             newState,
@@ -464,8 +465,10 @@
 
         this._userState = newState;
 
-        console.debug('TimeLimitsManager: User state changed from ' +
-            `${userStateToString(oldState)} to ${userStateToString(newState)} at ${wallTimeSecs}s`);
+        if (debugLog) {
+            console.debug('TimeLimitsManager: User state changed from ' +
+                `${userStateToString(oldState)} to ${userStateToString(newState)} at ${wallTimeSecs}s`);
+        }
 
         // This potentially changed the limit time and timeout calculations.
         if (recalculateState && this._state !== TimeLimitsState.DISABLED) {
@@ -542,11 +545,15 @@
             this._addTransition(
                 entry['oldState'],
                 entry['newState'],
-                entry['wallTimeSecs'],
-                i === history.length - 1);
+                entry['wallTimeSecs'], {
+                    recalculateState: i === history.length - 1,
+                    debugLog: false,
+                });
             previousWallTimeSecs = entry['wallTimeSecs'];
         }
 
+        console.debug(`TimeLimitsManager: Loaded ${history.length} transitions from history`);
+
         this.thaw_notify();
     }
 
diff -Nru gnome-shell-48.2/js/ui/altTab.js gnome-shell-48.3/js/ui/altTab.js
--- gnome-shell-48.2/js/ui/altTab.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/altTab.js	2025-06-29 11:35:41.000000000 +0100
@@ -682,7 +682,6 @@
         this.add_child(this.label);
     }
 
-    // eslint-disable-next-line camelcase
     set_size(size) {
         this.icon = this.app.create_icon_texture(size);
         this._iconBin.child = this.icon;
diff -Nru gnome-shell-48.2/js/ui/background.js gnome-shell-48.3/js/ui/background.js
--- gnome-shell-48.2/js/ui/background.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/background.js	2025-06-29 11:35:41.000000000 +0100
@@ -661,7 +661,6 @@
         this.loaded = false;
     }
 
-    // eslint-disable-next-line camelcase
     load_async(cancellable, callback) {
         super.load_async(cancellable, () => {
             this.loaded = true;
diff -Nru gnome-shell-48.2/js/ui/components/keyring.js gnome-shell-48.3/js/ui/components/keyring.js
--- gnome-shell-48.2/js/ui/components/keyring.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/components/keyring.js	2025-06-29 11:35:41.000000000 +0100
@@ -173,7 +173,12 @@
 
     _onContinueButton() {
         this._updateSensitivity(false);
-        this.prompt.complete();
+        if (this.prompt.complete())
+            return;
+        // Allow user to correct it when passwords mismatch.
+        this._updateSensitivity(true);
+        if (this.prompt.password_visible)
+            this._passwordEntry.grab_key_focus();
     }
 
     _onCancelButton() {
diff -Nru gnome-shell-48.2/js/ui/dateMenu.js gnome-shell-48.3/js/ui/dateMenu.js
--- gnome-shell-48.2/js/ui/dateMenu.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/dateMenu.js	2025-06-29 11:35:41.000000000 +0100
@@ -132,6 +132,7 @@
             style_class: 'events-title',
         });
         this.child.add_child(this._title);
+        this.labelActor = this._title;
 
         this._eventsList = new St.BoxLayout({
             style_class: 'events-list',
@@ -567,6 +568,7 @@
         });
         titleBox.add_child(this._titleLabel);
         box.add_child(titleBox);
+        this.labelActor = this._titleLabel;
 
         this._titleLocation = new St.Label({
             style_class: 'weather-header location',
diff -Nru gnome-shell-48.2/js/ui/keyboard.js gnome-shell-48.3/js/ui/keyboard.js
--- gnome-shell-48.2/js/ui/keyboard.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/keyboard.js	2025-06-29 11:35:41.000000000 +0100
@@ -1305,7 +1305,7 @@
         this._keyboardController.connectObject(
             'group-changed', this._onGroupChanged.bind(this),
             'panel-state', this._onKeyboardStateChanged.bind(this),
-            'purpose-changed', this._onPurposeChanged.bind(this),
+            'purpose-changed', () => this._updateKeys(),
             'content-hints-changed', this._onContentHintsChanged.bind(this),
             this);
         global.stage.connectObject('notify::key-focus',
@@ -1314,11 +1314,6 @@
         this._relayout();
     }
 
-    _onPurposeChanged(controller, purpose) {
-        this._purpose = purpose;
-        this._updateKeys();
-    }
-
     _onContentHintsChanged(controller, contentHint) {
         this._contentHint = contentHint;
         this._updateLevelFromHints(false);
@@ -1660,7 +1655,8 @@
 
     _updateKeys() {
         const group = this._keyboardController.getCurrentGroup();
-        this._updateLayout(group, this._purpose);
+        const {purpose} = this._keyboardController;
+        this._updateLayout(group, purpose);
         this._setActiveLevel('default');
     }
 
@@ -1994,6 +1990,7 @@
             'current-source-changed', this._onSourceChanged.bind(this),
             'sources-changed', this._onSourcesModified.bind(this), this);
         this._currentSource = this._inputSourceManager.currentSource;
+        this._purpose = Main.inputMethod.contentPurpose;
 
         Main.inputMethod.connectObject(
             'notify::content-purpose', this._onPurposeHintsChanged.bind(this),
@@ -2001,6 +1998,10 @@
             'input-panel-state', (o, state) => this.emit('panel-state', state), this);
     }
 
+    get purpose() {
+        return this._purpose;
+    }
+
     destroy() {
         this._inputSourceManager.disconnectObject(this);
         Main.inputMethod.disconnectObject(this);
diff -Nru gnome-shell-48.2/js/ui/overview.js gnome-shell-48.3/js/ui/overview.js
--- gnome-shell-48.2/js/ui/overview.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/overview.js	2025-06-29 11:35:41.000000000 +0100
@@ -358,6 +358,9 @@
     }
 
     _gestureUpdate(tracker, progress) {
+        if (progress === 0)
+            return;
+
         if (!this._shown) {
             this._shown = true;
             this._visible = true;
diff -Nru gnome-shell-48.2/js/ui/popupMenu.js gnome-shell-48.3/js/ui/popupMenu.js
--- gnome-shell-48.2/js/ui/popupMenu.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/popupMenu.js	2025-06-29 11:35:41.000000000 +0100
@@ -308,6 +308,7 @@
         this.label = new St.Label({text: text || ''});
         this.add_child(this.label);
         this.label_actor = this.label;
+        this.accessible_role = Atk.Role.SEPARATOR;
 
         this.label.connect('notify::text',
             this._syncVisibility.bind(this));
diff -Nru gnome-shell-48.2/js/ui/runDialog.js gnome-shell-48.3/js/ui/runDialog.js
--- gnome-shell-48.2/js/ui/runDialog.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/runDialog.js	2025-06-29 11:35:41.000000000 +0100
@@ -62,9 +62,11 @@
 
         let content = new Dialog.MessageDialogContent({title});
         this.contentLayout.add_child(content);
+        const [labelActor] = content;
 
         let entry = new St.Entry({
             style_class: 'run-dialog-entry',
+            labelActor,
             can_focus: true,
         });
         ShellEntry.addContextMenu(entry);
diff -Nru gnome-shell-48.2/js/ui/status/keyboard.js gnome-shell-48.3/js/ui/status/keyboard.js
--- gnome-shell-48.2/js/ui/status/keyboard.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/status/keyboard.js	2025-06-29 11:35:41.000000000 +0100
@@ -998,6 +998,12 @@
         }
     }
 
+    _getGraphemeClusters(text = '') {
+        const segmenter = new Intl.Segmenter(undefined, {granularity: 'grapheme'});
+        const segments = [...segmenter.segment(text)].map(o => o.segment);
+        return segments;
+    }
+
     _buildPropSubMenu(menu, props) {
         if (!props)
             return;
@@ -1021,7 +1027,8 @@
                 let currentSource = this._inputSourceManager.currentSource;
                 if (currentSource) {
                     let indicatorLabel = this._indicatorLabels[currentSource.index];
-                    if (text && text.length > 0 && text.length < 3)
+                    const graphemeClusters = this._getGraphemeClusters(text);
+                    if (graphemeClusters.length > 0 && graphemeClusters.length < 3)
                         indicatorLabel.set_text(text);
                 }
             }
diff -Nru gnome-shell-48.2/js/ui/status/rfkill.js gnome-shell-48.3/js/ui/status/rfkill.js
--- gnome-shell-48.2/js/ui/status/rfkill.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/status/rfkill.js	2025-06-29 11:35:41.000000000 +0100
@@ -43,7 +43,6 @@
             .catch(e => console.error(e.message));
     }
 
-    /* eslint-disable camelcase */
     get airplane_mode() {
         return this._proxy.AirplaneMode;
     }
@@ -59,7 +58,6 @@
     get show_airplane_mode() {
         return this._proxy.HasAirplaneMode && this._proxy.ShouldShowAirplaneMode;
     }
-    /* eslint-enable camelcase */
 
     _changed(proxy, properties) {
         for (const prop in properties.deepUnpack()) {
diff -Nru gnome-shell-48.2/js/ui/swipeTracker.js gnome-shell-48.3/js/ui/swipeTracker.js
--- gnome-shell-48.2/js/ui/swipeTracker.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/swipeTracker.js	2025-06-29 11:35:41.000000000 +0100
@@ -358,7 +358,7 @@
             return false;
 
         if (!this._began && this.scrollModifiers !== 0 &&
-            (event.get_state() & this.scrollModifiers) === 0)
+            (event.get_state() & this.scrollModifiers) !== this.scrollModifiers)
             return false;
 
         return true;
diff -Nru gnome-shell-48.2/js/ui/windowManager.js gnome-shell-48.3/js/ui/windowManager.js
--- gnome-shell-48.2/js/ui/windowManager.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/js/ui/windowManager.js	2025-06-29 11:35:41.000000000 +0100
@@ -883,7 +883,8 @@
             if (this._workspaceAnimation.canHandleScrollEvent(event))
                 return Clutter.EVENT_PROPAGATE;
 
-            if ((event.get_state() & global.display.compositor_modifiers) === 0)
+            const {compositorModifiers} = global.display;
+            if ((event.get_state() & compositorModifiers) !== compositorModifiers)
                 return Clutter.EVENT_PROPAGATE;
 
             return this.handleWorkspaceScroll(event);
diff -Nru gnome-shell-48.2/meson.build gnome-shell-48.3/meson.build
--- gnome-shell-48.2/meson.build	2025-07-13 22:27:19.000000000 +0100
+++ gnome-shell-48.3/meson.build	2025-07-13 22:27:19.000000000 +0100
@@ -1,6 +1,6 @@
 project('gnome-shell', 'c',
-  version: '48.2',
-  meson_version: '>= 1.1.0',
+  version: '48.3',
+  meson_version: '>= 1.3.0',
   license: 'GPL-2.0-or-later',
 )
 
@@ -166,7 +166,10 @@
 cdata.set('HAVE_MALLINFO2', cc.has_function('mallinfo2'))
 cdata.set('HAVE_SYS_RESOURCE_H', cc.has_header('sys/resource.h'))
 cdata.set('HAVE_EXE_INTROSPECTION',
-  cc.has_header('elf.h') and cc.has_header('link.h'))
+  cc.has_header('elf.h') and
+  cc.has_header('link.h') and
+  cc.has_define('__GLIBC__', prefix: '#include <link.h>')
+)
 cdata.set('HAVE__NL_TIME_FIRST_WEEKDAY',
   cc.has_header_symbol('langinfo.h', '_NL_TIME_FIRST_WEEKDAY')
 )
diff -Nru gnome-shell-48.2/NEWS gnome-shell-48.3/NEWS
--- gnome-shell-48.2/NEWS	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/NEWS	2025-06-29 11:35:41.000000000 +0100
@@ -1,3 +1,21 @@
+48.3
+====
+* Check all modifiers for modifier-scroll [Florian; !3725]
+* Fix visibility of emoji key in on-screen-keyboard [Carlos; !3733]
+* Add missing accessibility labels in various components
+  [Florian, Sergio; !3736, !3765, !3769, !3773, !3179]
+* Allow users to correct keyring password after failure [Alynx; !3757]
+* Misc. bug fixes and cleanups [fossdd, Jordan, Florian, Joan, Mike, Daniel;
+  !3728, !3735, !3740, !3739, !3745, !3749, !3753, !3748, !3777, !3756]
+
+Contributors:
+  Sergio Costas Rodriguez, Mike FABIAN, fossdd, Carlos Garnacho,
+  Florian Müllner, Jordan Petridis, Joan Torres López, Daniel van Vugt,
+  Alynx Zhou
+
+Translators:
+  Fabio Tomat [fur], Takayuki Kusano [ja]
+
 48.2
 ====
 * Only enable surrounding-text IM capability when needed [Takao; !3666]
diff -Nru gnome-shell-48.2/src/st/st-entry.c gnome-shell-48.3/src/st/st-entry.c
--- gnome-shell-48.2/src/st/st-entry.c	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/src/st/st-entry.c	2025-06-29 11:35:41.000000000 +0100
@@ -121,6 +121,9 @@
                       ST, ENTRY_ACCESSIBLE,
                       StWidgetAccessible)
 
+static void update_hint_relation (StEntry *entry);
+static void update_label_relation (StEntry *entry);
+
 static void
 st_entry_set_property (GObject      *gobject,
                        guint         prop_id,
@@ -515,6 +518,14 @@
 }
 
 static void
+st_entry_label_actor_changed_cb (StEntry    *entry,
+                                 GParamSpec *pspec,
+                                 gpointer    user_data G_GNUC_UNUSED)
+{
+  update_label_relation (entry);
+}
+
+static void
 clutter_text_reactive_changed_cb (ClutterActor *text,
                                   GParamSpec   *pspec,
                                   gpointer      user_data)
@@ -1046,6 +1057,9 @@
                           priv->entry, "reactive",
                           G_BINDING_DEFAULT);
 
+  g_signal_connect (entry, "notify::label-actor",
+                    G_CALLBACK (st_entry_label_actor_changed_cb), entry);
+
   g_signal_connect(priv->entry, "notify::reactive",
                    G_CALLBACK (clutter_text_reactive_changed_cb), entry);
 
@@ -1490,6 +1504,8 @@
   st_entry_update_hint_visibility (entry);
   g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_HINT_ACTOR]);
 
+  update_hint_relation (entry);
+
   clutter_actor_queue_relayout (CLUTTER_ACTOR (entry));
 }
 
@@ -1522,6 +1538,9 @@
 typedef struct _StEntryAccessible
 {
   StWidgetAccessible parent;
+
+  AtkObject *current_hint;
+  AtkObject *current_label;
 } StEntryAccessible;
 
 G_DEFINE_FINAL_TYPE (StEntryAccessible, st_entry_accessible, ST_TYPE_WIDGET_ACCESSIBLE)
@@ -1533,6 +1552,17 @@
 }
 
 static void
+st_entry_accessible_dispose (GObject *object)
+{
+  StEntryAccessible *accessible = ST_ENTRY_ACCESSIBLE (object);
+
+  g_clear_object (&accessible->current_hint);
+  g_clear_object (&accessible->current_label);
+
+  G_OBJECT_CLASS (st_entry_accessible_parent_class)->dispose (object);
+}
+
+static void
 st_entry_accessible_initialize (AtkObject *obj,
                                 gpointer   data)
 {
@@ -1540,6 +1570,8 @@
 
   /* StEntry is behaving as a ClutterText container */
   atk_object_set_role (obj, ATK_ROLE_PANEL);
+
+  update_hint_relation (ST_ENTRY (data));
 }
 
 static gint
@@ -1593,8 +1625,88 @@
 st_entry_accessible_class_init (StEntryAccessibleClass *klass)
 {
   AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass);
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->dispose = st_entry_accessible_dispose;
 
   atk_class->initialize = st_entry_accessible_initialize;
   atk_class->get_n_children = st_entry_accessible_get_n_children;
   atk_class->ref_child= st_entry_accessible_ref_child;
 }
+
+static void
+update_hint_relation (StEntry *entry)
+{
+  StEntryPrivate *priv;
+  AtkObject *accessible;
+  StEntryAccessible *entry_accessible;
+
+  priv = st_entry_get_instance_private (entry);
+
+  accessible = clutter_actor_get_accessible (priv->entry);
+  entry_accessible = ST_ENTRY_ACCESSIBLE (atk_object_get_parent (accessible));
+
+  if (entry_accessible->current_hint != NULL)
+    {
+      atk_object_remove_relationship (accessible,
+                                      ATK_RELATION_DESCRIBED_BY,
+                                      entry_accessible->current_hint);
+      atk_object_remove_relationship (entry_accessible->current_hint,
+                                      ATK_RELATION_DESCRIPTION_FOR,
+                                      accessible);
+      g_clear_object (&entry_accessible->current_hint);
+    }
+
+  if (ST_IS_LABEL (priv->hint_actor))
+    {
+      g_set_object (&entry_accessible->current_hint,
+                    clutter_actor_get_accessible (priv->hint_actor));
+
+      atk_object_add_relationship (accessible,
+                                   ATK_RELATION_DESCRIBED_BY,
+                                   entry_accessible->current_hint);
+      atk_object_add_relationship (entry_accessible->current_hint,
+                                   ATK_RELATION_DESCRIPTION_FOR,
+                                   accessible);
+    }
+}
+
+static void
+update_label_relation (StEntry *entry)
+{
+  StEntryPrivate *priv;
+  AtkObject *accessible;
+  StEntryAccessible *entry_accessible;
+  ClutterActor *label_actor;
+
+  priv = st_entry_get_instance_private (entry);
+
+  accessible = clutter_actor_get_accessible (priv->entry);
+  entry_accessible = ST_ENTRY_ACCESSIBLE (atk_object_get_parent (accessible));
+
+  if (entry_accessible->current_label != NULL)
+    {
+      atk_object_remove_relationship (accessible,
+                                      ATK_RELATION_LABELLED_BY,
+                                      entry_accessible->current_label);
+      atk_object_remove_relationship (entry_accessible->current_label,
+                                      ATK_RELATION_LABEL_FOR,
+                                      accessible);
+      g_clear_object (&entry_accessible->current_label);
+    }
+
+  label_actor = st_widget_get_label_actor (ST_WIDGET (entry));
+
+  if (label_actor != NULL)
+    {
+      g_set_object (&entry_accessible->current_label,
+                    clutter_actor_get_accessible (label_actor));
+
+      atk_object_add_relationship (accessible,
+                                   ATK_RELATION_LABELLED_BY,
+                                   entry_accessible->current_label);
+      atk_object_add_relationship (entry_accessible->current_label,
+                                   ATK_RELATION_LABEL_FOR,
+                                   accessible);
+    }
+}
diff -Nru gnome-shell-48.2/subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in gnome-shell-48.3/subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in
--- gnome-shell-48.2/subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/subprojects/extensions-app/data/metainfo/org.gnome.Extensions.metainfo.xml.in	2025-06-29 11:35:41.000000000 +0100
@@ -55,6 +55,7 @@
   </description>
 
   <releases>
+    <release version="48.3" date="2025-06-29"/>
     <release version="48.2" date="2025-05-24"/>
     <release version="48.1" date="2025-04-12"/>
     <release version="48.0" date="2025-03-16">
diff -Nru gnome-shell-48.2/subprojects/extensions-app/meson.build gnome-shell-48.3/subprojects/extensions-app/meson.build
--- gnome-shell-48.2/subprojects/extensions-app/meson.build	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/subprojects/extensions-app/meson.build	2025-06-29 11:35:41.000000000 +0100
@@ -1,5 +1,5 @@
 project('gnome-extensions-app',
-  version: '48.2',
+  version: '48.3',
   meson_version: '>= 0.58.0',
   license: 'GPL-2.0-or-later',
 )
diff -Nru gnome-shell-48.2/subprojects/extensions-app/subprojects/shew/meson.build gnome-shell-48.3/subprojects/extensions-app/subprojects/shew/meson.build
--- gnome-shell-48.2/subprojects/extensions-app/subprojects/shew/meson.build	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/subprojects/extensions-app/subprojects/shew/meson.build	2025-06-29 11:35:41.000000000 +0100
@@ -1,5 +1,5 @@
 project('shew', 'c',
-  version: '48.2',
+  version: '48.3',
   meson_version: '>= 0.58.0',
   license: 'LGPL-2.1-or-later',
 )
diff -Nru gnome-shell-48.2/subprojects/extensions-tool/meson.build gnome-shell-48.3/subprojects/extensions-tool/meson.build
--- gnome-shell-48.2/subprojects/extensions-tool/meson.build	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/subprojects/extensions-tool/meson.build	2025-06-29 11:35:41.000000000 +0100
@@ -1,5 +1,5 @@
 project('gnome-extensions-tool', 'c',
-  version: '48.2',
+  version: '48.3',
   meson_version: '>= 0.58.0',
   license: 'GPL-2.0-or-later',
 )
diff -Nru gnome-shell-48.2/subprojects/shew/meson.build gnome-shell-48.3/subprojects/shew/meson.build
--- gnome-shell-48.2/subprojects/shew/meson.build	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/subprojects/shew/meson.build	2025-06-29 11:35:41.000000000 +0100
@@ -1,5 +1,5 @@
 project('shew', 'c',
-  version: '48.2',
+  version: '48.3',
   meson_version: '>= 0.58.0',
   license: 'LGPL-2.1-or-later',
 )
diff -Nru gnome-shell-48.2/tests/shell/basic.js gnome-shell-48.3/tests/shell/basic.js
--- gnome-shell-48.2/tests/shell/basic.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/tests/shell/basic.js	2025-06-29 11:35:41.000000000 +0100
@@ -96,12 +96,10 @@
 
     Scripting.scriptEvent('applicationsShowStart');
     console.debug('Showing applications');
-    // eslint-disable-next-line require-atomic-updates
     Main.overview.dash.showAppsButton.checked = true;
     await Scripting.waitLeisure();
     Scripting.scriptEvent('applicationsShowDone');
     console.debug('Hiding applications');
-    // eslint-disable-next-line require-atomic-updates
     Main.overview.dash.showAppsButton.checked = false;
     await Scripting.waitLeisure();
 
diff -Nru gnome-shell-48.2/tests/shell/closeWithActiveWindows.js gnome-shell-48.3/tests/shell/closeWithActiveWindows.js
--- gnome-shell-48.2/tests/shell/closeWithActiveWindows.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/tests/shell/closeWithActiveWindows.js	2025-06-29 11:35:41.000000000 +0100
@@ -7,8 +7,6 @@
 
 /** Run test. */
 export async function run() {
-    /* eslint-disable no-await-in-loop */
-
     /* Make created windows remain visible during exit. */
     await Scripting.disableHelperAutoExit();
 
@@ -29,6 +27,4 @@
     await Scripting.waitTestWindows();
     await Scripting.waitLeisure();
     await Scripting.sleep(1000);
-
-    /* eslint-enable no-await-in-loop */
 }
diff -Nru gnome-shell-48.2/tests/shell/core.js gnome-shell-48.3/tests/shell/core.js
--- gnome-shell-48.2/tests/shell/core.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/tests/shell/core.js	2025-06-29 11:35:41.000000000 +0100
@@ -153,11 +153,9 @@
 
     for (let i = 0; i < 2; i++) {
         Scripting.scriptEvent('applicationsShowStart');
-        // eslint-disable-next-line require-atomic-updates
         Main.overview.dash.showAppsButton.checked = true;
         await Scripting.waitLeisure();
         Scripting.scriptEvent('applicationsShowDone');
-        // eslint-disable-next-line require-atomic-updates
         Main.overview.dash.showAppsButton.checked = false;
         await Scripting.waitLeisure();
     }
diff -Nru gnome-shell-48.2/tests/shell/headlessStart.js gnome-shell-48.3/tests/shell/headlessStart.js
--- gnome-shell-48.2/tests/shell/headlessStart.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/tests/shell/headlessStart.js	2025-06-29 11:35:41.000000000 +0100
@@ -48,7 +48,6 @@
  * run:
  */
 export async function run() {
-    /* eslint-disable no-await-in-loop */
     Scripting.defineScriptEvent('overviewShowDone', 'Overview finished showing');
     Scripting.defineScriptEvent('overviewHideDone', 'Overview finished hiding');
 
@@ -61,8 +60,6 @@
 
     Main.overview.show();
     await Scripting.waitLeisure();
-
-    /* eslint-enable no-await-in-loop */
 }
 
 let monitorsChanged = false;
diff -Nru gnome-shell-48.2/tests/shell/hwtest.js gnome-shell-48.3/tests/shell/hwtest.js
--- gnome-shell-48.2/tests/shell/hwtest.js	2025-05-25 16:24:49.000000000 +0100
+++ gnome-shell-48.3/tests/shell/hwtest.js	2025-06-29 11:35:41.000000000 +0100
@@ -97,7 +97,7 @@
     let result = null;
 
     let datastream = Gio.DataInputStream.new(sp.get_stdout_pipe());
-    while (true) { // eslint-disable-line no-constant-condition
+    while (true) {
         let [line, length_] = datastream.read_line_utf8(null);
         if (line === null)
             break;
@@ -143,7 +143,6 @@
     await Scripting.sleep(1000);
 
     Scripting.scriptEvent('applicationsShowStart');
-    // eslint-disable-next-line require-atomic-updates
     Main.overview.dash.showAppsButton.checked = true;
 
     await Scripting.waitLeisure();
