From b424d98585a520eaaedea461d24dc044f7fb45c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Sat, 14 Mar 2026 12:39:26 +0100 Subject: [PATCH 1/8] util: fixupPCIDescription: fix missing global flag in regex replacements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two regex replacements in fixupPCIDescription() were missing the /g (global) flag, causing only the first occurrence of each pattern to be replaced rather than all occurrences: - /[_,]/ → /[_,]/g (replace all underscores/commas with spaces) - /\([\s\S][^\(\)]{2,}\)/ → same with /g (strip all parenthesized info longer than 2 characters, not just the first one) Co-Authored-By: Claude Sonnet 4.6 --- js/misc/util.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/misc/util.js b/js/misc/util.js index 670fbff769..9dff70a646 100644 --- a/js/misc/util.js +++ b/js/misc/util.js @@ -369,12 +369,12 @@ const _IGNORED_PHRASES = [ ]; function fixupPCIDescription(desc) { - desc = desc.replace(/[_,]/, ' '); + desc = desc.replace(/[_,]/g, ' '); /* Remove any parenthesized info longer than 2 chars (which may be disambiguating numbers if there are multiple identical cards present) */ - desc = desc.replace(/\([\s\S][^\(\)]{2,}\)/, ''); + desc = desc.replace(/\([\s\S][^\(\)]{2,}\)/g, ''); /* Attempt to shorten ID by ignoring certain phrases */ for (let i = 0; i < _IGNORED_PHRASES.length; i++) { From 593a5a9e2bdfffa5ea277a271dbba0934e2d6185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Sat, 14 Mar 2026 12:39:36 +0100 Subject: [PATCH 2/8] keyboardManager: fix implicit global variable declarations Five schema/key constants at the top of the file were assigned without a var/let/const keyword, making them implicit globals that pollute the global scope. Inconsistent with the var declarations used elsewhere in the same file. Add var to each: DESKTOP_INPUT_SOURCES_SCHEMA, KEY_INPUT_SOURCES, KEY_KEYBOARD_OPTIONS, KEY_PER_WINDOW, KEY_SOURCE_LAYOUTS. Co-Authored-By: Claude Sonnet 4.6 --- js/ui/keyboardManager.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/js/ui/keyboardManager.js b/js/ui/keyboardManager.js index bf23d4b58e..ff9f94f2bc 100644 --- a/js/ui/keyboardManager.js +++ b/js/ui/keyboardManager.js @@ -12,11 +12,11 @@ const PopupMenu = imports.ui.popupMenu; const Cairo = imports.cairo; const Util = imports.misc.util; -DESKTOP_INPUT_SOURCES_SCHEMA = 'org.cinnamon.desktop.input-sources'; -KEY_INPUT_SOURCES = 'sources'; -KEY_KEYBOARD_OPTIONS = 'xkb-options'; -KEY_PER_WINDOW = 'per-window'; -KEY_SOURCE_LAYOUTS = 'source-layouts'; +var DESKTOP_INPUT_SOURCES_SCHEMA = 'org.cinnamon.desktop.input-sources'; +var KEY_INPUT_SOURCES = 'sources'; +var KEY_KEYBOARD_OPTIONS = 'xkb-options'; +var KEY_PER_WINDOW = 'per-window'; +var KEY_SOURCE_LAYOUTS = 'source-layouts'; var INPUT_SOURCE_TYPE_XKB = 'xkb'; var INPUT_SOURCE_TYPE_IBUS = 'ibus'; From 263028e607bc10976ca66986bbd6f8933653038d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Sat, 14 Mar 2026 16:42:21 +0100 Subject: [PATCH 3/8] notificationDaemon: add default case for unknown urgency in icon switch The switch on hints.urgency had no default branch, leaving stockIcon undefined when urgency is any value other than LOW (0), NORMAL (1), or CRITICAL (2). Passing icon_name: undefined to St.Icon silently creates a broken icon actor. Fall back to the information icon for unrecognised urgency values, matching the behaviour for LOW and NORMAL urgency. Co-Authored-By: Claude Sonnet 4.6 --- js/ui/notificationDaemon.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js index 7c01633a5c..3754de05ee 100644 --- a/js/ui/notificationDaemon.js +++ b/js/ui/notificationDaemon.js @@ -173,6 +173,9 @@ NotificationDaemon.prototype = { case Urgency.CRITICAL: stockIcon = 'xsi-dialog-error-symbolic'; break; + default: + stockIcon = 'xsi-dialog-information-symbolic'; + break; } return new St.Icon({ icon_name: stockIcon, icon_type: St.IconType.SYMBOLIC, From 1f2a2d746b74d1d8741686a11a4ff6093647af19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Sat, 14 Mar 2026 16:42:31 +0100 Subject: [PATCH 4/8] notificationDaemon: fix crash in _expireNotification when notification is null When NotifyAsync receives a notification for a sender it has not seen before, it adds ndata to _expireNotifications and starts the expire timer before the async GetConnectionUnixProcessID D-Bus call completes. ndata.notification is only set later, inside _notifyForSource(). If the expire timer fires during that window, _expireNotification() called ndata.notification.destroy() on undefined, crashing with a TypeError. Guard the destroy call: if ndata.notification does not exist yet, remove the orphaned entry from the queue and restart the timer for the next one. Co-Authored-By: Claude Sonnet 4.6 --- js/ui/notificationDaemon.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js index 3754de05ee..2ba1b3d29b 100644 --- a/js/ui/notificationDaemon.js +++ b/js/ui/notificationDaemon.js @@ -268,7 +268,13 @@ NotificationDaemon.prototype = { let ndata = this._expireNotifications[0]; if (ndata) { - ndata.notification.destroy(MessageTray.NotificationDestroyedReason.EXPIRED); + if (ndata.notification) { + ndata.notification.destroy(MessageTray.NotificationDestroyedReason.EXPIRED); + } else { + // notification object not yet created (async PID lookup still pending) + this._expireNotifications.shift(); + this._restartExpire(); + } } this._expireTimer = 0; From f7a351b4a39ebbc030dd34044137bff92771fdc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Sat, 14 Mar 2026 16:42:37 +0100 Subject: [PATCH 5/8] windowManager: fix ngettext missing count argument in display-change dialog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ngettext(singular, plural) requires a third argument — the integer count used to select the correct plural form. Without it the function always returns the singular string ("Reverting in 5 second." instead of "Reverting in 5 seconds."). Pass this._countDown as the count, matching the pattern used in endSessionDialog.js. Co-Authored-By: Claude Sonnet 4.6 --- js/ui/windowManager.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js index 5075b19965..6f5fd57db6 100644 --- a/js/ui/windowManager.js +++ b/js/ui/windowManager.js @@ -100,9 +100,9 @@ class DisplayChangeDialog extends ModalDialog.ModalDialog { } _formatCountDown() { - let fmt = ngettext("Reverting to previous display settings in %d second.", - "Reverting to previous display settings in %d seconds."); - return fmt.format(this._countDown); + return ngettext("Reverting to previous display settings in %d second.", + "Reverting to previous display settings in %d seconds.", + this._countDown).format(this._countDown); } _tick() { From dc43b8406e9fb8110d63a3408e4554313dfa8e74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Sat, 14 Mar 2026 16:42:52 +0100 Subject: [PATCH 6/8] cinnamonDBus: fix crash in activateCallback when xlet is not found _getXletObject() returns null when no applet, desklet, or extension matches the given uuid/instance_id combination. The very next line then called null[callback].bind(null), throwing a TypeError. This can happen when cinnamon-settings calls a callback for an xlet that has been removed without a full shell restart. Add a null guard and log a warning instead of crashing. Co-Authored-By: Claude Sonnet 4.6 --- js/ui/cinnamonDBus.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/ui/cinnamonDBus.js b/js/ui/cinnamonDBus.js index 086e3ef837..358b8a74de 100644 --- a/js/ui/cinnamonDBus.js +++ b/js/ui/cinnamonDBus.js @@ -374,6 +374,10 @@ var CinnamonDBus = class { activateCallback(callback, uuid, instance_id) { let obj = this._getXletObject(uuid, instance_id); + if (!obj) { + global.logWarning(`[CinnamonDBus] activateCallback: xlet not found (uuid=${uuid}, instance_id=${instance_id})`); + return; + } let cb = obj[callback].bind(obj); cb(); } From 52825eadc7e58d1b9748b81b555d213fe930b2dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Sat, 14 Mar 2026 16:43:00 +0100 Subject: [PATCH 7/8] cinnamonDBus: fix crash in updateSetting when instance_id is not found updateSetting() already guards against an unknown uuid, but not against an unknown instance_id within a valid uuid. Accessing uuids[uuid][instance_id].remoteUpdate() when instance_id is absent throws "Cannot read property 'remoteUpdate' of undefined". This can happen when cinnamon-settings updates a setting for an xlet instance that was removed without a full shell restart. Add a second guard and log a warning instead of crashing. Co-Authored-By: Claude Sonnet 4.6 --- js/ui/cinnamonDBus.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/js/ui/cinnamonDBus.js b/js/ui/cinnamonDBus.js index 358b8a74de..7f66f418b9 100644 --- a/js/ui/cinnamonDBus.js +++ b/js/ui/cinnamonDBus.js @@ -390,6 +390,13 @@ var CinnamonDBus = class { ); return; } + if (!Main.settingsManager.uuids[uuid][instance_id]) { + global.logWarning( + `[CinnamonDBus] [${uuid}] Unable to find instance '${instance_id}' from SettingsManager - ` + + 'this is likely due to configuring settings from a removed xlet instance.' + ); + return; + } Main.settingsManager.uuids[uuid][instance_id].remoteUpdate(key, payload); } From 38ca44f3aa02028cef5a5518526ebd6ceeabe45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A1lm=C3=A1n=20=E2=80=9EKAMI=E2=80=9D=20Szalai?= Date: Sat, 14 Mar 2026 16:43:04 +0100 Subject: [PATCH 8/8] cinnamonDBus: remove leftover debug comment in GetInputSources Remove a stray '// global.log(source.preferences);' debug line that was accidentally left in GetInputSources(). Co-Authored-By: Claude Sonnet 4.6 --- js/ui/cinnamonDBus.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/ui/cinnamonDBus.js b/js/ui/cinnamonDBus.js index 7f66f418b9..21e9bf394f 100644 --- a/js/ui/cinnamonDBus.js +++ b/js/ui/cinnamonDBus.js @@ -560,7 +560,6 @@ var CinnamonDBus = class { for (let idx in sources) { const source = sources[idx]; - // global.log(source.preferences); ret.push([ source.type, source.id,