From e9bc0169f65d48f6d4b67b222bf7e33505bd25c9 Mon Sep 17 00:00:00 2001 From: bbedward Date: Sun, 26 Jul 2026 17:45:50 -0400 Subject: [PATCH] cc: migrate some settings to cache port 1.5 --- quickshell/Common/CacheData.qml | 70 +++++++++++++++++-- quickshell/Common/SettingsData.qml | 10 ++- quickshell/Common/settings/SettingsSpec.js | 5 -- quickshell/Common/settings/SettingsStore.js | 26 +++++++ .../Details/AudioInputDetail.qml | 6 +- .../Details/AudioOutputDetail.qml | 6 +- .../ControlCenter/Details/BluetoothDetail.qml | 6 +- .../Details/BrightnessDetail.qml | 14 ++-- .../ControlCenter/Details/NetworkDetail.qml | 6 +- .../Widgets/BrightnessSliderRow.qml | 2 +- .../DankBar/Widgets/ControlCenterButton.qml | 2 +- .../Modules/Settings/NetworkWifiTab.qml | 6 +- quickshell/Services/DisplayService.qml | 2 +- 13 files changed, 119 insertions(+), 42 deletions(-) diff --git a/quickshell/Common/CacheData.qml b/quickshell/Common/CacheData.qml index 5e6ef5f04..a0883bb65 100644 --- a/quickshell/Common/CacheData.qml +++ b/quickshell/Common/CacheData.qml @@ -11,16 +11,27 @@ Singleton { id: root readonly property var log: Log.scoped("CacheData") - readonly property int cacheConfigVersion: 1 + readonly property int cacheConfigVersion: 2 readonly property string _stateUrl: StandardPaths.writableLocation(StandardPaths.GenericCacheLocation) readonly property string _stateDir: Paths.strip(_stateUrl) property bool _loading: false + property bool _hasLoaded: false + property int _loadedCacheVersion: 0 + + readonly property var _pinKeys: ["brightnessDevicePins", "wifiNetworkPins", "bluetoothDevicePins", "audioInputDevicePins", "audioOutputDevicePins"] + readonly property var _dataKeys: ["wallpaperLastPath", "profileLastPath", "fileBrowserSettings"].concat(_pinKeys) property string wallpaperLastPath: "" property string profileLastPath: "" + property var brightnessDevicePins: ({}) + property var wifiNetworkPins: ({}) + property var bluetoothDevicePins: ({}) + property var audioInputDevicePins: ({}) + property var audioOutputDevicePins: ({}) + property var fileBrowserSettings: ({ "wallpaper": { "lastPath": "", @@ -78,8 +89,46 @@ Singleton { function loadCache() { _loading = true; - parseCache(cacheFile.text()); - _loading = false; + try { + parseCache(cacheFile.text()); + } finally { + _loading = false; + _hasLoaded = true; + } + } + + function set(key, value) { + if (_dataKeys.indexOf(key) < 0) { + log.warn("Unknown cache key:", key); + return; + } + root[key] = value; + saveCache(); + } + + function migratePins(pins) { + if (!pins) + return; + if (!_hasLoaded) + loadCache(); + if (_loadedCacheVersion >= cacheConfigVersion) + return; + + let migrated = false; + for (const key of _pinKeys) { + const legacy = pins[key]; + if (!legacy || Object.keys(legacy).length === 0) + continue; + if (Object.keys(root[key] || {}).length > 0) + continue; + root[key] = legacy; + migrated = true; + } + + if (!migrated) + return; + log.info("Migrated device pins from settings.json"); + saveCache(); } function parseCache(content) { @@ -87,6 +136,7 @@ Singleton { try { if (content && content.trim()) { const cache = JSON.parse(content); + _loadedCacheVersion = cache.configVersion || 0; wallpaperLastPath = cache.wallpaperLastPath !== undefined ? cache.wallpaperLastPath : ""; profileLastPath = cache.profileLastPath !== undefined ? cache.profileLastPath : ""; @@ -122,6 +172,10 @@ Singleton { }; } + for (const key of _pinKeys) { + root[key] = cache[key] !== undefined ? cache[key] : {}; + } + if (cache.configVersion === undefined) { migrateFromUndefinedToV1(cache); cleanupUnusedKeys(); @@ -138,12 +192,16 @@ Singleton { function saveCache() { if (_loading) return; - cacheFile.setText(JSON.stringify({ + const data = { "wallpaperLastPath": wallpaperLastPath, "profileLastPath": profileLastPath, "fileBrowserSettings": fileBrowserSettings, "configVersion": cacheConfigVersion - }, null, 2)); + }; + for (const key of _pinKeys) { + data[key] = root[key]; + } + cacheFile.setText(JSON.stringify(data, null, 2)); } function migrateFromUndefinedToV1(cache) { @@ -151,7 +209,7 @@ Singleton { } function cleanupUnusedKeys() { - const validKeys = ["wallpaperLastPath", "profileLastPath", "fileBrowserSettings", "configVersion"]; + const validKeys = _dataKeys.concat(["configVersion"]); try { const content = cacheFile.text(); diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 9508cbc3e..e8b69a0a6 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -15,7 +15,7 @@ Singleton { id: root readonly property var log: Log.scoped("SettingsData") - readonly property int settingsConfigVersion: 12 + readonly property int settingsConfigVersion: 13 enum Position { Top, @@ -790,11 +790,6 @@ Singleton { property bool fadeToDpmsEnabled: true property int fadeToDpmsGracePeriod: 5 property string launchPrefix: "" - property var brightnessDevicePins: ({}) - property var wifiNetworkPins: ({}) - property var bluetoothDevicePins: ({}) - property var audioInputDevicePins: ({}) - property var audioOutputDevicePins: ({}) property bool gtkThemingEnabled: false property bool qtThemingEnabled: false @@ -1757,6 +1752,7 @@ Singleton { let obj = (txt && txt.trim()) ? JSON.parse(txt) : null; const oldVersion = obj?.configVersion ?? 0; + const legacyPins = oldVersion < 13 ? Store.extractPins(obj) : null; if (oldVersion < settingsConfigVersion) { const migrated = Store.migrateToVersion(obj, settingsConfigVersion); if (migrated) { @@ -1764,6 +1760,8 @@ Singleton { obj = migrated; } } + if (legacyPins) + Qt.callLater(() => CacheData.migratePins(legacyPins)); if (obj?.lockScreenActiveMonitor !== undefined) { var oldVal = obj.lockScreenActiveMonitor; diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index d5393f807..88c75e93a 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -373,11 +373,6 @@ var SPEC = { fadeToDpmsEnabled: { def: true }, fadeToDpmsGracePeriod: { def: 5 }, launchPrefix: { def: "" }, - brightnessDevicePins: { def: {} }, - wifiNetworkPins: { def: {} }, - bluetoothDevicePins: { def: {} }, - audioInputDevicePins: { def: {} }, - audioOutputDevicePins: { def: {} }, gtkThemingEnabled: { def: false, onChange: "regenSystemThemes" }, qtThemingEnabled: { def: false, onChange: "regenSystemThemes" }, diff --git a/quickshell/Common/settings/SettingsStore.js b/quickshell/Common/settings/SettingsStore.js index 6af77c360..1a4720831 100644 --- a/quickshell/Common/settings/SettingsStore.js +++ b/quickshell/Common/settings/SettingsStore.js @@ -2,6 +2,21 @@ .import "./SettingsSpec.js" as SpecModule +var PIN_KEYS = ["brightnessDevicePins", "wifiNetworkPins", "bluetoothDevicePins", "audioInputDevicePins", "audioOutputDevicePins"]; + +function extractPins(obj) { + if (!obj) return null; + + var pins = null; + for (var i = 0; i < PIN_KEYS.length; i++) { + var value = obj[PIN_KEYS[i]]; + if (!value || Object.keys(value).length === 0) continue; + if (!pins) pins = {}; + pins[PIN_KEYS[i]] = value; + } + return pins; +} + function parse(root, jsonObj) { var SPEC = SpecModule.SPEC; @@ -263,6 +278,17 @@ function migrateToVersion(obj, targetVersion) { settings.configVersion = 12; } + if (currentVersion < 13) { + console.info("Migrating settings from version", currentVersion, "to version 13"); + console.info("Moving device and network pins to cache.json"); + + for (var p = 0; p < PIN_KEYS.length; p++) { + delete settings[PIN_KEYS[p]]; + } + + settings.configVersion = 13; + } + return settings; } diff --git a/quickshell/Modules/ControlCenter/Details/AudioInputDetail.qml b/quickshell/Modules/ControlCenter/Details/AudioInputDetail.qml index bbf3cd3b7..120774525 100644 --- a/quickshell/Modules/ControlCenter/Details/AudioInputDetail.qml +++ b/quickshell/Modules/ControlCenter/Details/AudioInputDetail.qml @@ -159,7 +159,7 @@ Rectangle { } function getPinnedInputs() { - const pins = SettingsData.audioInputDevicePins || {}; + const pins = CacheData.audioInputDevicePins || {}; return normalizePinList(pins["preferredInput"]); } @@ -315,7 +315,7 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y) onClicked: { - const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {})); + const pins = JSON.parse(JSON.stringify(CacheData.audioInputDevicePins || {})); let pinnedList = audioContent.normalizePinList(pins["preferredInput"]); const pinIndex = pinnedList.indexOf(modelData.name); @@ -332,7 +332,7 @@ Rectangle { else delete pins["preferredInput"]; - SettingsData.set("audioInputDevicePins", pins); + CacheData.set("audioInputDevicePins", pins); } } } diff --git a/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml b/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml index 390dd7a05..2bbec13c4 100644 --- a/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml +++ b/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml @@ -169,7 +169,7 @@ Rectangle { } function getPinnedOutputs() { - const pins = SettingsData.audioOutputDevicePins || {}; + const pins = CacheData.audioOutputDevicePins || {}; return normalizePinList(pins["preferredOutput"]); } @@ -324,7 +324,7 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y) onClicked: { - const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {})); + const pins = JSON.parse(JSON.stringify(CacheData.audioOutputDevicePins || {})); let pinnedList = audioContent.normalizePinList(pins["preferredOutput"]); const pinIndex = pinnedList.indexOf(modelData.name); @@ -341,7 +341,7 @@ Rectangle { else delete pins["preferredOutput"]; - SettingsData.set("audioOutputDevicePins", pins); + CacheData.set("audioOutputDevicePins", pins); } } } diff --git a/quickshell/Modules/ControlCenter/Details/BluetoothDetail.qml b/quickshell/Modules/ControlCenter/Details/BluetoothDetail.qml index 97dcaee85..ba277eddc 100644 --- a/quickshell/Modules/ControlCenter/Details/BluetoothDetail.qml +++ b/quickshell/Modules/ControlCenter/Details/BluetoothDetail.qml @@ -104,7 +104,7 @@ Rectangle { } function getPinnedDevices() { - const pins = SettingsData.bluetoothDevicePins || {}; + const pins = CacheData.bluetoothDevicePins || {}; return normalizePinList(pins["preferredDevice"]); } @@ -395,7 +395,7 @@ Rectangle { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: { - const pins = JSON.parse(JSON.stringify(SettingsData.bluetoothDevicePins || {})); + const pins = JSON.parse(JSON.stringify(CacheData.bluetoothDevicePins || {})); let pinnedList = root.normalizePinList(pins["preferredDevice"]); const pinIndex = pinnedList.indexOf(pairedDelegate.modelData.address); @@ -413,7 +413,7 @@ Rectangle { delete pins["preferredDevice"]; } - SettingsData.set("bluetoothDevicePins", pins); + CacheData.set("bluetoothDevicePins", pins); } } } diff --git a/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml b/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml index d75a48d08..f81d921ca 100644 --- a/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml +++ b/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml @@ -37,7 +37,7 @@ Rectangle { const pinKey = getScreenPinKey(); if (pinKey.length > 0) { - const pins = SettingsData.brightnessDevicePins || {}; + const pins = CacheData.brightnessDevicePins || {}; const pinnedDevice = pins[pinKey]; if (pinnedDevice && pinnedDevice.length > 0) { const found = devices.find(d => d.name === pinnedDevice); @@ -85,12 +85,12 @@ Rectangle { } const pinKey = getScreenPinKey(); if (pinKey.length > 0) { - const pins = SettingsData.brightnessDevicePins || {}; + const pins = CacheData.brightnessDevicePins || {}; const existing = pins[pinKey]; if (existing && existing !== deviceName) { const next = JSON.parse(JSON.stringify(pins)); delete next[pinKey]; - SettingsData.set("brightnessDevicePins", next); + CacheData.set("brightnessDevicePins", next); } } root.currentDeviceName = deviceName; @@ -106,7 +106,7 @@ Rectangle { const pinKey = getScreenPinKey(); if (!pinKey || !deviceName) return false; - const pins = SettingsData.brightnessDevicePins || {}; + const pins = CacheData.brightnessDevicePins || {}; return pins[pinKey] === deviceName; } @@ -114,13 +114,13 @@ Rectangle { const pinKey = getScreenPinKey(); if (!pinKey || !deviceName) return; - const pins = JSON.parse(JSON.stringify(SettingsData.brightnessDevicePins || {})); + const pins = JSON.parse(JSON.stringify(CacheData.brightnessDevicePins || {})); if (pins[pinKey] === deviceName) { delete pins[pinKey]; } else { pins[pinKey] = deviceName; } - SettingsData.set("brightnessDevicePins", pins); + CacheData.set("brightnessDevicePins", pins); } implicitHeight: { @@ -269,7 +269,7 @@ Rectangle { readonly property bool selected: !!(modelData && modelData.name === root.currentDeviceName) readonly property bool devicePinnedHere: { - SettingsData.brightnessDevicePins; + CacheData.brightnessDevicePins; return root.isDevicePinnedToScreen(modelData ? modelData.name : ""); } diff --git a/quickshell/Modules/ControlCenter/Details/NetworkDetail.qml b/quickshell/Modules/ControlCenter/Details/NetworkDetail.qml index f5608f071..79abb4853 100644 --- a/quickshell/Modules/ControlCenter/Details/NetworkDetail.qml +++ b/quickshell/Modules/ControlCenter/Details/NetworkDetail.qml @@ -75,7 +75,7 @@ Rectangle { } function getPinnedNetworks() { - const pins = SettingsData.wifiNetworkPins || {}; + const pins = CacheData.wifiNetworkPins || {}; return normalizePinList(pins["preferredWifi"]); } @@ -907,7 +907,7 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y) onClicked: { - const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {})); + const pins = JSON.parse(JSON.stringify(CacheData.wifiNetworkPins || {})); let pinnedList = root.normalizePinList(pins["preferredWifi"]); const pinIndex = pinnedList.indexOf(modelData.ssid); @@ -924,7 +924,7 @@ Rectangle { else delete pins["preferredWifi"]; - SettingsData.set("wifiNetworkPins", pins); + CacheData.set("wifiNetworkPins", pins); } } } diff --git a/quickshell/Modules/ControlCenter/Widgets/BrightnessSliderRow.qml b/quickshell/Modules/ControlCenter/Widgets/BrightnessSliderRow.qml index bb0e904d1..9c21f53e1 100644 --- a/quickshell/Modules/ControlCenter/Widgets/BrightnessSliderRow.qml +++ b/quickshell/Modules/ControlCenter/Widgets/BrightnessSliderRow.qml @@ -34,7 +34,7 @@ Row { if (screenName && screenName.length > 0) { const screen = Quickshell.screens.find(s => s.name === screenName); const pinKey = screen ? SettingsData.getScreenDisplayName(screen) : screenName; - const pins = SettingsData.brightnessDevicePins || {}; + const pins = CacheData.brightnessDevicePins || {}; const pinnedDevice = pins[pinKey]; if (pinnedDevice && pinnedDevice.length > 0) { const found = DisplayService.devices.find(dev => dev.name === pinnedDevice); diff --git a/quickshell/Modules/DankBar/Widgets/ControlCenterButton.qml b/quickshell/Modules/DankBar/Widgets/ControlCenterButton.qml index 2417bc2d3..a32dcb9ca 100644 --- a/quickshell/Modules/DankBar/Widgets/ControlCenterButton.qml +++ b/quickshell/Modules/DankBar/Widgets/ControlCenterButton.qml @@ -203,7 +203,7 @@ BasePill { const pinKey = getScreenPinKey(); if (!pinKey) return ""; - const pins = SettingsData.brightnessDevicePins || {}; + const pins = CacheData.brightnessDevicePins || {}; return pins[pinKey] || ""; } diff --git a/quickshell/Modules/Settings/NetworkWifiTab.qml b/quickshell/Modules/Settings/NetworkWifiTab.qml index 28171ae35..6567dc373 100644 --- a/quickshell/Modules/Settings/NetworkWifiTab.qml +++ b/quickshell/Modules/Settings/NetworkWifiTab.qml @@ -55,12 +55,12 @@ Item { } function getPinnedWifiNetworks() { - const pins = SettingsData.wifiNetworkPins || {}; + const pins = CacheData.wifiNetworkPins || {}; return normalizePinList(pins["preferredWifi"]); } function toggleWifiPin(ssid) { - const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {})); + const pins = JSON.parse(JSON.stringify(CacheData.wifiNetworkPins || {})); let pinnedList = normalizePinList(pins["preferredWifi"]); const pinIndex = pinnedList.indexOf(ssid); @@ -77,7 +77,7 @@ Item { else delete pins["preferredWifi"]; - SettingsData.set("wifiNetworkPins", pins); + CacheData.set("wifiNetworkPins", pins); } property var forgetNetworkConfirm: ConfirmModal {} diff --git a/quickshell/Services/DisplayService.qml b/quickshell/Services/DisplayService.qml index 521b8c96e..88c5d611d 100644 --- a/quickshell/Services/DisplayService.qml +++ b/quickshell/Services/DisplayService.qml @@ -948,7 +948,7 @@ Singleton { if (!focusedScreen) return ""; - const pins = SettingsData.brightnessDevicePins || {}; + const pins = CacheData.brightnessDevicePins || {}; const screenKey = SettingsData.getScreenDisplayName(focusedScreen); if (!screenKey) return "";