diff options
| author | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
|---|---|---|
| committer | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
| commit | 70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch) | |
| tree | ab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings | |
| parent | 5d94c0a7d44a2255b81815a52a7056a94a39842d (diff) | |
| download | RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip | |
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings')
6 files changed, 1733 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/Lists.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/Lists.qml new file mode 100644 index 0000000..57b5f2d --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/Lists.qml @@ -0,0 +1,94 @@ +pragma Singleton +pragma ComponentBehavior: Bound + +import Quickshell +import QtQuick + +Singleton { + id: root + + function init(leftModel, centerModel, rightModel, left, center, right) { + const dummy = { + widgetId: "dummy", + enabled: true, + size: 20, + selectedGpuIndex: 0, + pciId: "", + mountPath: "/", + minimumWidth: true, + showSwap: false, + mediaSize: 1, + showNetworkIcon: true, + showBluetoothIcon: true, + showAudioIcon: true, + showAudioPercent: true, + showVpnIcon: true, + showBrightnessIcon: false, + showBrightnessPercent: false, + showMicIcon: false, + showMicPercent: true, + showBatteryIcon: false, + showPrinterIcon: false, + showScreenSharingIcon: true + }; + leftModel.append(dummy); + centerModel.append(dummy); + rightModel.append(dummy); + + update(leftModel, left); + update(centerModel, center); + update(rightModel, right); + } + + function update(model, order) { + model.clear(); + for (var i = 0; i < order.length; i++) { + var isObj = typeof order[i] !== "string"; + var widgetId = isObj ? order[i].id : order[i]; + var item = { + widgetId: widgetId, + enabled: isObj ? order[i].enabled : true + }; + if (isObj && order[i].size !== undefined) + item.size = order[i].size; + if (isObj && order[i].selectedGpuIndex !== undefined) + item.selectedGpuIndex = order[i].selectedGpuIndex; + if (isObj && order[i].pciId !== undefined) + item.pciId = order[i].pciId; + if (isObj && order[i].mountPath !== undefined) + item.mountPath = order[i].mountPath; + if (isObj && order[i].minimumWidth !== undefined) + item.minimumWidth = order[i].minimumWidth; + if (isObj && order[i].showSwap !== undefined) + item.showSwap = order[i].showSwap; + if (isObj && order[i].mediaSize !== undefined) + item.mediaSize = order[i].mediaSize; + if (isObj && order[i].showNetworkIcon !== undefined) + item.showNetworkIcon = order[i].showNetworkIcon; + if (isObj && order[i].showBluetoothIcon !== undefined) + item.showBluetoothIcon = order[i].showBluetoothIcon; + if (isObj && order[i].showAudioIcon !== undefined) + item.showAudioIcon = order[i].showAudioIcon; + if (isObj && order[i].showAudioPercent !== undefined) + item.showAudioPercent = order[i].showAudioPercent; + if (isObj && order[i].showVpnIcon !== undefined) + item.showVpnIcon = order[i].showVpnIcon; + if (isObj && order[i].showBrightnessIcon !== undefined) + item.showBrightnessIcon = order[i].showBrightnessIcon; + if (isObj && order[i].showBrightnessPercent !== undefined) + item.showBrightnessPercent = order[i].showBrightnessPercent; + if (isObj && order[i].showMicIcon !== undefined) + item.showMicIcon = order[i].showMicIcon; + if (isObj && order[i].showMicPercent !== undefined) + item.showMicPercent = order[i].showMicPercent; + if (isObj && order[i].showBatteryIcon !== undefined) + item.showBatteryIcon = order[i].showBatteryIcon; + if (isObj && order[i].showPrinterIcon !== undefined) + item.showPrinterIcon = order[i].showPrinterIcon; + if (isObj && order[i].showScreenSharingIcon !== undefined) + item.showScreenSharingIcon = order[i].showScreenSharingIcon; + + model.append(item); + } + } +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/Processes.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/Processes.qml new file mode 100644 index 0000000..a11abae --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/Processes.qml @@ -0,0 +1,602 @@ +pragma Singleton +pragma ComponentBehavior: Bound + +import QtQuick +import Quickshell +import Quickshell.Io +import qs.Common +import qs.Services + +Singleton { + id: root + + property var settingsRoot: null + + property string greetdPamText: "" + property string systemAuthPamText: "" + property string commonAuthPamText: "" + property string passwordAuthPamText: "" + property string systemLoginPamText: "" + property string systemLocalLoginPamText: "" + property string commonAuthPcPamText: "" + property string loginPamText: "" + property string dankshellU2fPamText: "" + property string u2fKeysText: "" + + property string fingerprintProbeOutput: "" + property int fingerprintProbeExitCode: 0 + property bool fingerprintProbeFinalized: false + + property string pamProbeOutput: "" + property bool pamProbeFinalized: false + + readonly property string homeDir: Quickshell.env("HOME") || "" + readonly property string u2fKeysPath: homeDir ? homeDir + "/.config/Yubico/u2f_keys" : "" + readonly property bool homeU2fKeysDetected: u2fKeysPath !== "" && u2fKeysWatcher.loaded && u2fKeysText.trim() !== "" + readonly property bool lockU2fCustomConfigDetected: pamModuleEnabled(dankshellU2fPamText, "pam_u2f") + readonly property bool greeterPamHasFprint: greeterPamStackHasModule("pam_fprintd") + readonly property bool greeterPamHasU2f: greeterPamStackHasModule("pam_u2f") + + function envFlag(name) { + const value = (Quickshell.env(name) || "").trim().toLowerCase(); + if (value === "1" || value === "true" || value === "yes" || value === "on") + return true; + if (value === "0" || value === "false" || value === "no" || value === "off") + return false; + return null; + } + + readonly property var forcedFprintAvailable: envFlag("DMS_FORCE_FPRINT_AVAILABLE") + readonly property var forcedU2fAvailable: envFlag("DMS_FORCE_U2F_AVAILABLE") + + // --- Derived auth probe state --- + + readonly property bool pamFprintSupportDetected: pamProbeFinalized && pamProbeOutput.includes("pam_fprintd.so:true") + readonly property bool pamU2fSupportDetected: pamProbeFinalized && pamProbeOutput.includes("pam_u2f.so:true") + + readonly property string fingerprintProbeState: { + if (forcedFprintAvailable !== null) + return forcedFprintAvailable ? "ready" : "probe_failed"; + if (!fingerprintProbeFinalized) + return "probe_failed"; + return parseFingerprintProbe(fingerprintProbeExitCode, fingerprintProbeOutput, pamFprintSupportDetected); + } + + // --- Lock fingerprint capabilities --- + + readonly property bool lockFingerprintCanEnable: { + if (forcedFprintAvailable !== null) + return forcedFprintAvailable; + switch (fingerprintProbeState) { + case "ready": + case "missing_enrollment": + return true; + default: + return false; + } + } + + readonly property bool lockFingerprintReady: { + if (forcedFprintAvailable !== null) + return forcedFprintAvailable; + return fingerprintProbeState === "ready"; + } + + readonly property string lockFingerprintReason: { + if (forcedFprintAvailable !== null) + return forcedFprintAvailable ? "ready" : "probe_failed"; + return fingerprintProbeState; + } + + // --- Greeter fingerprint capabilities --- + + readonly property bool greeterFingerprintCanEnable: { + if (forcedFprintAvailable !== null) + return forcedFprintAvailable; + if (greeterPamHasFprint) + return fingerprintProbeState !== "missing_reader"; + switch (fingerprintProbeState) { + case "ready": + case "missing_enrollment": + return true; + default: + return false; + } + } + + readonly property bool greeterFingerprintReady: { + if (forcedFprintAvailable !== null) + return forcedFprintAvailable; + return fingerprintProbeState === "ready"; + } + + readonly property string greeterFingerprintReason: { + if (forcedFprintAvailable !== null) + return forcedFprintAvailable ? "ready" : "probe_failed"; + if (greeterPamHasFprint) { + switch (fingerprintProbeState) { + case "ready": + return "configured_externally"; + case "missing_enrollment": + return "missing_enrollment"; + case "missing_reader": + return "missing_reader"; + default: + return "probe_failed"; + } + } + return fingerprintProbeState; + } + + readonly property string greeterFingerprintSource: { + if (forcedFprintAvailable !== null) + return forcedFprintAvailable ? "dms" : "none"; + if (greeterPamHasFprint) + return "pam"; + switch (fingerprintProbeState) { + case "ready": + case "missing_enrollment": + return "dms"; + default: + return "none"; + } + } + + // --- Lock U2F capabilities --- + + readonly property bool lockU2fReady: { + if (forcedU2fAvailable !== null) + return forcedU2fAvailable; + return lockU2fCustomConfigDetected || homeU2fKeysDetected; + } + + readonly property bool lockU2fCanEnable: { + if (forcedU2fAvailable !== null) + return forcedU2fAvailable; + return lockU2fReady || pamU2fSupportDetected; + } + + readonly property string lockU2fReason: { + if (forcedU2fAvailable !== null) + return forcedU2fAvailable ? "ready" : "probe_failed"; + if (lockU2fReady) + return "ready"; + if (lockU2fCanEnable) + return "missing_key_registration"; + return "missing_pam_support"; + } + + // --- Greeter U2F capabilities --- + + readonly property bool greeterU2fReady: { + if (forcedU2fAvailable !== null) + return forcedU2fAvailable; + if (greeterPamHasU2f) + return true; + return homeU2fKeysDetected; + } + + readonly property bool greeterU2fCanEnable: { + if (forcedU2fAvailable !== null) + return forcedU2fAvailable; + if (greeterPamHasU2f) + return true; + return greeterU2fReady || pamU2fSupportDetected; + } + + readonly property string greeterU2fReason: { + if (forcedU2fAvailable !== null) + return forcedU2fAvailable ? "ready" : "probe_failed"; + if (greeterPamHasU2f) + return "configured_externally"; + if (greeterU2fReady) + return "ready"; + if (greeterU2fCanEnable) + return "missing_key_registration"; + return "missing_pam_support"; + } + + readonly property string greeterU2fSource: { + if (forcedU2fAvailable !== null) + return forcedU2fAvailable ? "dms" : "none"; + if (greeterPamHasU2f) + return "pam"; + if (greeterU2fCanEnable) + return "dms"; + return "none"; + } + + // --- Aggregates --- + + readonly property bool fprintdAvailable: lockFingerprintReady || greeterFingerprintReady + readonly property bool u2fAvailable: lockU2fReady || greeterU2fReady + + // --- Auth detection --- + + readonly property var _fprintProbeCommand: ["sh", "-c", "if command -v fprintd-list >/dev/null 2>&1; then fprintd-list \"${USER:-$(id -un)}\" 2>&1; else printf '__missing_command__\\n'; exit 127; fi"] + readonly property var _pamProbeCommand: ["sh", "-c", "for module in pam_fprintd.so pam_u2f.so; do found=false; for dir in /usr/lib64/security /usr/lib/security /lib/security /lib/x86_64-linux-gnu/security /usr/lib/x86_64-linux-gnu/security /usr/lib/aarch64-linux-gnu/security /run/current-system/sw/lib/security; do if [ -f \"$dir/$module\" ]; then found=true; break; fi; done; printf '%s:%s\\n' \"$module\" \"$found\"; done"] + + function detectAuthCapabilities() { + if (forcedFprintAvailable === null) { + fingerprintProbeFinalized = false; + Proc.runCommand("fprint-probe", _fprintProbeCommand, (output, exitCode) => { + fingerprintProbeOutput = output || ""; + fingerprintProbeExitCode = exitCode; + fingerprintProbeFinalized = true; + }, 0); + } + + pamProbeFinalized = false; + Proc.runCommand("pam-probe", _pamProbeCommand, (output, _exitCode) => { + pamProbeOutput = output || ""; + pamProbeFinalized = true; + }, 0); + } + + function detectFprintd() { + detectAuthCapabilities(); + } + + function detectU2f() { + detectAuthCapabilities(); + } + + // --- Auth apply pipeline --- + + property bool authApplyRunning: false + property bool authApplyQueued: false + property bool authApplyRerunRequested: false + property bool authApplyTerminalFallbackFromPrecheck: false + property string authApplyStdout: "" + property string authApplyStderr: "" + property string authApplySudoProbeStderr: "" + property string authApplyTerminalFallbackStderr: "" + + function scheduleAuthApply() { + if (!settingsRoot || settingsRoot.isGreeterMode) + return; + + authApplyQueued = true; + if (authApplyRunning) { + authApplyRerunRequested = true; + return; + } + + authApplyDebounce.restart(); + } + + function beginAuthApply() { + if (!authApplyQueued || authApplyRunning || !settingsRoot || settingsRoot.isGreeterMode) + return; + + authApplyQueued = false; + authApplyRerunRequested = false; + authApplyStdout = ""; + authApplyStderr = ""; + authApplySudoProbeStderr = ""; + authApplyTerminalFallbackStderr = ""; + authApplyTerminalFallbackFromPrecheck = false; + authApplyRunning = true; + authApplySudoProbeProcess.running = true; + } + + function launchAuthApplyTerminalFallback(fromPrecheck, details) { + authApplyTerminalFallbackFromPrecheck = fromPrecheck; + if (details && details !== "") + ToastService.showInfo(I18n.tr("Authentication changes need sudo. Opening terminal so you can use password or fingerprint."), details, "", "auth-sync"); + authApplyTerminalFallbackStderr = ""; + authApplyTerminalFallbackProcess.running = true; + } + + function finishAuthApply() { + const shouldRerun = authApplyQueued || authApplyRerunRequested; + authApplyRunning = false; + authApplyRerunRequested = false; + if (shouldRerun) + authApplyDebounce.restart(); + } + + // --- PAM parsing helpers --- + + function stripPamComment(line) { + if (!line) + return ""; + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("#")) + return ""; + const hashIdx = trimmed.indexOf("#"); + if (hashIdx >= 0) + return trimmed.substring(0, hashIdx).trim(); + return trimmed; + } + + function pamModuleEnabled(pamText, moduleName) { + if (!pamText || !moduleName) + return false; + const lines = pamText.split(/\r?\n/); + for (let i = 0; i < lines.length; i++) { + const line = stripPamComment(lines[i]); + if (!line) + continue; + if (line.includes(moduleName)) + return true; + } + return false; + } + + function pamTextIncludesFile(pamText, filename) { + if (!pamText || !filename) + return false; + const lines = pamText.split(/\r?\n/); + for (let i = 0; i < lines.length; i++) { + const line = stripPamComment(lines[i]); + if (!line) + continue; + if (line.includes(filename) && (line.includes("include") || line.includes("substack") || line.startsWith("@include"))) + return true; + } + return false; + } + + function greeterPamStackHasModule(moduleName) { + if (pamModuleEnabled(greetdPamText, moduleName)) + return true; + const includedPamStacks = [["system-auth", systemAuthPamText], ["common-auth", commonAuthPamText], ["password-auth", passwordAuthPamText], ["system-login", systemLoginPamText], ["system-local-login", systemLocalLoginPamText], ["common-auth-pc", commonAuthPcPamText], ["login", loginPamText]]; + for (let i = 0; i < includedPamStacks.length; i++) { + const stack = includedPamStacks[i]; + if (pamTextIncludesFile(greetdPamText, stack[0]) && pamModuleEnabled(stack[1], moduleName)) + return true; + } + return false; + } + + // --- Fingerprint probe output parsing --- + + function hasEnrolledFingerprintOutput(output) { + const lower = (output || "").toLowerCase(); + if (lower.includes("has fingers enrolled") || lower.includes("has fingerprints enrolled")) + return true; + const lines = lower.split(/\r?\n/); + for (let i = 0; i < lines.length; i++) { + const trimmed = lines[i].trim(); + if (trimmed.startsWith("finger:")) + return true; + if (trimmed.startsWith("- ") && trimmed.includes("finger")) + return true; + } + return false; + } + + function hasMissingFingerprintEnrollmentOutput(output) { + const lower = (output || "").toLowerCase(); + return lower.includes("no fingers enrolled") || lower.includes("no fingerprints enrolled") || lower.includes("no prints enrolled"); + } + + function hasMissingFingerprintReaderOutput(output) { + const lower = (output || "").toLowerCase(); + return lower.includes("no devices available") || lower.includes("no device available") || lower.includes("no devices found") || lower.includes("list_devices failed") || lower.includes("no device"); + } + + function parseFingerprintProbe(exitCode, output, pamFprintDetected) { + if (hasEnrolledFingerprintOutput(output)) + return "ready"; + if (hasMissingFingerprintEnrollmentOutput(output)) + return "missing_enrollment"; + if (hasMissingFingerprintReaderOutput(output)) + return "missing_reader"; + if (exitCode === 0) + return "missing_enrollment"; + if (exitCode === 127 || (output || "").includes("__missing_command__")) + return "probe_failed"; + return pamFprintDetected ? "probe_failed" : "missing_pam_support"; + } + + // --- Qt tools detection --- + + function detectQtTools() { + qtToolsDetectionProcess.running = true; + } + + function checkPluginSettings() { + pluginSettingsCheckProcess.running = true; + } + + property var qtToolsDetectionProcess: Process { + command: ["sh", "-c", "echo -n 'qt5ct:'; command -v qt5ct >/dev/null && echo 'true' || echo 'false'; echo -n 'qt6ct:'; command -v qt6ct >/dev/null && echo 'true' || echo 'false'; echo -n 'gtk:'; (command -v gsettings >/dev/null || command -v dconf >/dev/null) && echo 'true' || echo 'false'"] + running: false + + stdout: StdioCollector { + onStreamFinished: { + if (!settingsRoot) + return; + if (text && text.trim()) { + const lines = text.trim().split("\n"); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (line.startsWith("qt5ct:")) { + settingsRoot.qt5ctAvailable = line.split(":")[1] === "true"; + } else if (line.startsWith("qt6ct:")) { + settingsRoot.qt6ctAvailable = line.split(":")[1] === "true"; + } else if (line.startsWith("gtk:")) { + settingsRoot.gtkAvailable = line.split(":")[1] === "true"; + } + } + } + } + } + } + + Timer { + id: authApplyDebounce + interval: 300 + repeat: false + onTriggered: root.beginAuthApply() + } + + property var authApplyProcess: Process { + command: ["dms", "auth", "sync", "--yes"] + running: false + + stdout: StdioCollector { + onStreamFinished: root.authApplyStdout = text || "" + } + + stderr: StdioCollector { + onStreamFinished: root.authApplyStderr = text || "" + } + + onExited: exitCode => { + const out = (root.authApplyStdout || "").trim(); + const err = (root.authApplyStderr || "").trim(); + + if (exitCode === 0) { + let details = out; + if (err !== "") + details = details !== "" ? details + "\n\nstderr:\n" + err : "stderr:\n" + err; + ToastService.showInfo(I18n.tr("Authentication changes applied."), details, "", "auth-sync"); + root.detectAuthCapabilities(); + root.finishAuthApply(); + return; + } + + let details = ""; + if (out !== "") + details = out; + if (err !== "") + details = details !== "" ? details + "\n\nstderr:\n" + err : "stderr:\n" + err; + ToastService.showWarning(I18n.tr("Background authentication sync failed. Trying terminal mode."), details, "", "auth-sync"); + root.launchAuthApplyTerminalFallback(false, ""); + } + } + + property var authApplySudoProbeProcess: Process { + command: ["sudo", "-n", "true"] + running: false + + stderr: StdioCollector { + onStreamFinished: root.authApplySudoProbeStderr = text || "" + } + + onExited: exitCode => { + const err = (root.authApplySudoProbeStderr || "").trim(); + if (exitCode === 0) { + ToastService.showInfo(I18n.tr("Applying authentication changes…"), "", "", "auth-sync"); + root.authApplyProcess.running = true; + return; + } + + root.launchAuthApplyTerminalFallback(true, err); + } + } + + property var authApplyTerminalFallbackProcess: Process { + command: ["dms", "auth", "sync", "--terminal", "--yes"] + running: false + + stderr: StdioCollector { + onStreamFinished: root.authApplyTerminalFallbackStderr = text || "" + } + + onExited: exitCode => { + if (exitCode === 0) { + const message = root.authApplyTerminalFallbackFromPrecheck ? I18n.tr("Terminal opened. Complete authentication setup there; it will close automatically when done.") : I18n.tr("Terminal fallback opened. Complete authentication setup there; it will close automatically when done."); + ToastService.showInfo(message, "", "", "auth-sync"); + } else { + let details = (root.authApplyTerminalFallbackStderr || "").trim(); + ToastService.showError(I18n.tr("Terminal fallback failed. Install a supported terminal emulator or run 'dms auth sync' manually.") + " (exit " + exitCode + ")", details, "", "auth-sync"); + } + root.finishAuthApply(); + } + } + + FileView { + id: greetdPamWatcher + path: "/etc/pam.d/greetd" + printErrors: false + onLoaded: root.greetdPamText = text() + onLoadFailed: root.greetdPamText = "" + } + + FileView { + id: systemAuthPamWatcher + path: "/etc/pam.d/system-auth" + printErrors: false + onLoaded: root.systemAuthPamText = text() + onLoadFailed: root.systemAuthPamText = "" + } + + FileView { + id: commonAuthPamWatcher + path: "/etc/pam.d/common-auth" + printErrors: false + onLoaded: root.commonAuthPamText = text() + onLoadFailed: root.commonAuthPamText = "" + } + + FileView { + id: passwordAuthPamWatcher + path: "/etc/pam.d/password-auth" + printErrors: false + onLoaded: root.passwordAuthPamText = text() + onLoadFailed: root.passwordAuthPamText = "" + } + + FileView { + id: systemLoginPamWatcher + path: "/etc/pam.d/system-login" + printErrors: false + onLoaded: root.systemLoginPamText = text() + onLoadFailed: root.systemLoginPamText = "" + } + + FileView { + id: systemLocalLoginPamWatcher + path: "/etc/pam.d/system-local-login" + printErrors: false + onLoaded: root.systemLocalLoginPamText = text() + onLoadFailed: root.systemLocalLoginPamText = "" + } + + FileView { + id: commonAuthPcPamWatcher + path: "/etc/pam.d/common-auth-pc" + printErrors: false + onLoaded: root.commonAuthPcPamText = text() + onLoadFailed: root.commonAuthPcPamText = "" + } + + FileView { + id: loginPamWatcher + path: "/etc/pam.d/login" + printErrors: false + onLoaded: root.loginPamText = text() + onLoadFailed: root.loginPamText = "" + } + + FileView { + id: dankshellU2fPamWatcher + path: "/etc/pam.d/dankshell-u2f" + printErrors: false + onLoaded: root.dankshellU2fPamText = text() + onLoadFailed: root.dankshellU2fPamText = "" + } + + FileView { + id: u2fKeysWatcher + path: root.u2fKeysPath + printErrors: false + onLoaded: root.u2fKeysText = text() + onLoadFailed: root.u2fKeysText = "" + } + + property var pluginSettingsCheckProcess: Process { + command: ["test", "-f", settingsRoot?.pluginSettingsPath || ""] + running: false + + onExited: function (exitCode) { + if (!settingsRoot) + return; + settingsRoot.pluginSettingsFileExists = (exitCode === 0); + } + } +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SessionSpec.js b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SessionSpec.js new file mode 100644 index 0000000..e2bb4fe --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SessionSpec.js @@ -0,0 +1,109 @@ +.pragma library + +var SPEC = { + isLightMode: { def: false }, + doNotDisturb: { def: false }, + + wallpaperPath: { def: "" }, + perMonitorWallpaper: { def: false }, + monitorWallpapers: { def: {} }, + perModeWallpaper: { def: false }, + wallpaperPathLight: { def: "" }, + wallpaperPathDark: { def: "" }, + monitorWallpapersLight: { def: {} }, + monitorWallpapersDark: { def: {} }, + monitorWallpaperFillModes: { def: {} }, + wallpaperTransition: { def: "fade" }, + includedTransitions: { def: ["fade", "wipe", "disc", "stripes", "iris bloom", "pixelate", "portal"] }, + + wallpaperCyclingEnabled: { def: false }, + wallpaperCyclingMode: { def: "interval" }, + wallpaperCyclingInterval: { def: 300 }, + wallpaperCyclingTime: { def: "06:00" }, + monitorCyclingSettings: { def: {} }, + + nightModeEnabled: { def: false }, + nightModeTemperature: { def: 4500 }, + nightModeHighTemperature: { def: 6500 }, + nightModeAutoEnabled: { def: false }, + nightModeAutoMode: { def: "time" }, + nightModeStartHour: { def: 18 }, + nightModeStartMinute: { def: 0 }, + nightModeEndHour: { def: 6 }, + nightModeEndMinute: { def: 0 }, + latitude: { def: 0.0 }, + longitude: { def: 0.0 }, + nightModeUseIPLocation: { def: false }, + nightModeLocationProvider: { def: "" }, + + themeModeAutoEnabled: { def: false }, + themeModeAutoMode: { def: "time" }, + themeModeStartHour: { def: 18 }, + themeModeStartMinute: { def: 0 }, + themeModeEndHour: { def: 6 }, + themeModeEndMinute: { def: 0 }, + themeModeShareGammaSettings: { def: true }, + + weatherLocation: { def: "New York, NY" }, + weatherCoordinates: { def: "40.7128,-74.0060" }, + + pinnedApps: { def: [] }, + barPinnedApps: { def: [] }, + dockLauncherPosition: { def: 0 }, + hiddenTrayIds: { def: [] }, + trayItemOrder: { def: [] }, + recentColors: { def: [] }, + showThirdPartyPlugins: { def: false }, + launchPrefix: { def: "" }, + lastBrightnessDevice: { def: "" }, + + brightnessExponentialDevices: { def: {} }, + brightnessUserSetValues: { def: {} }, + brightnessExponentValues: { def: {} }, + + selectedGpuIndex: { def: 0 }, + nvidiaGpuTempEnabled: { def: false }, + nonNvidiaGpuTempEnabled: { def: false }, + enabledGpuPciIds: { def: [] }, + + wifiDeviceOverride: { def: "" }, + weatherHourlyDetailed: { def: true }, + + hiddenApps: { def: [] }, + appOverrides: { def: {} }, + searchAppActions: { def: true }, + + vpnLastConnected: { def: "" }, + + lastPlayerIdentity: { def: "" }, + + deviceMaxVolumes: { def: {} }, + hiddenOutputDeviceNames: { def: [] }, + hiddenInputDeviceNames: { def: [] }, + + locale: { def: "", onChange: "updateLocale" }, + timeLocale: { def: "" }, + + launcherLastMode: { def: "all" }, + launcherLastQuery: { def: "" }, + launcherQueryHistory: { def: [] }, + appDrawerLastMode: { def: "apps" }, + niriOverviewLastMode: { def: "apps" }, + + settingsSidebarExpandedIds: { def: "," }, + settingsSidebarCollapsedIds: { def: "," } +}; + +function getValidKeys() { + return Object.keys(SPEC).concat(["configVersion"]); +} + +function set(root, key, value, saveFn, hooks) { + if (!(key in SPEC)) return; + root[key] = value; + var hookName = SPEC[key].onChange; + if (hookName && hooks && hooks[hookName]) { + hooks[hookName](root); + } + saveFn(); +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SessionStore.js b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SessionStore.js new file mode 100644 index 0000000..c1e2190 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SessionStore.js @@ -0,0 +1,100 @@ +.pragma library + + .import "./SessionSpec.js" as SpecModule + +function parse(root, jsonObj) { + var SPEC = SpecModule.SPEC; + + if (!jsonObj) return; + + for (var k in SPEC) { + if (!(k in jsonObj)) { + root[k] = SPEC[k].def; + } + } + + for (var k in jsonObj) { + if (!SPEC[k]) continue; + var raw = jsonObj[k]; + var spec = SPEC[k]; + var coerce = spec.coerce; + root[k] = coerce ? (coerce(raw) !== undefined ? coerce(raw) : root[k]) : raw; + } +} + +function toJson(root) { + var SPEC = SpecModule.SPEC; + var out = {}; + for (var k in SPEC) { + if (SPEC[k].persist === false) continue; + out[k] = root[k]; + } + out.configVersion = root.sessionConfigVersion; + return out; +} + +function migrateToVersion(obj, targetVersion, settingsData) { + if (!obj) return null; + + var session = JSON.parse(JSON.stringify(obj)); + var currentVersion = session.configVersion || 0; + + if (currentVersion >= targetVersion) { + return null; + } + + if (currentVersion < 2) { + console.info("SessionData: Migrating session from version", currentVersion, "to version 2"); + console.info("SessionData: Importing weather location and coordinates from settings"); + + if (settingsData && typeof settingsData !== "undefined") { + if (session.weatherLocation === undefined || session.weatherLocation === "New York, NY") { + var settingsWeatherLocation = settingsData._legacyWeatherLocation; + if (settingsWeatherLocation && settingsWeatherLocation !== "New York, NY") { + session.weatherLocation = settingsWeatherLocation; + console.info("SessionData: Migrated weatherLocation:", settingsWeatherLocation); + } + } + + if (session.weatherCoordinates === undefined || session.weatherCoordinates === "40.7128,-74.0060") { + var settingsWeatherCoordinates = settingsData._legacyWeatherCoordinates; + if (settingsWeatherCoordinates && settingsWeatherCoordinates !== "40.7128,-74.0060") { + session.weatherCoordinates = settingsWeatherCoordinates; + console.info("SessionData: Migrated weatherCoordinates:", settingsWeatherCoordinates); + } + } + } + + session.configVersion = 2; + } + + if (currentVersion < 3) { + console.info("SessionData: Migrating session to version 3"); + session.configVersion = 3; + } + + return session; +} + +function cleanup(fileText) { + var getValidKeys = SpecModule.getValidKeys; + if (!fileText || !fileText.trim()) return null; + + try { + var session = JSON.parse(fileText); + var validKeys = getValidKeys(); + var needsSave = false; + + for (var key in session) { + if (validKeys.indexOf(key) < 0) { + delete session[key]; + needsSave = true; + } + } + + return needsSave ? JSON.stringify(session, null, 2) : null; + } catch (e) { + console.warn("SessionData: Failed to cleanup unused keys:", e.message); + return null; + } +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SettingsSpec.js b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SettingsSpec.js new file mode 100644 index 0000000..056545e --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SettingsSpec.js @@ -0,0 +1,553 @@ +.pragma library + +function percentToUnit(v) { + if (v === undefined || v === null) return undefined; + return v > 1 ? v / 100 : v; +} + +var SPEC = { + currentThemeName: { def: "raveos", onChange: "applyStoredTheme" }, + currentThemeCategory: { def: "generic" }, + customThemeFile: { def: "" }, + registryThemeVariants: { def: {} }, + matugenScheme: { def: "scheme-tonal-spot", onChange: "regenSystemThemes" }, + matugenContrast: { def: 0, onChange: "regenSystemThemes" }, + runUserMatugenTemplates: { def: true, onChange: "regenSystemThemes" }, + matugenTargetMonitor: { def: "", onChange: "regenSystemThemes" }, + + popupTransparency: { def: 1.0, coerce: percentToUnit }, + dockTransparency: { def: 1.0, coerce: percentToUnit }, + + widgetBackgroundColor: { def: "sch" }, + widgetColorMode: { def: "default" }, + controlCenterTileColorMode: { def: "primary" }, + buttonColorMode: { def: "primary" }, + cornerRadius: { def: 16, onChange: "updateCompositorLayout" }, + niriLayoutGapsOverride: { def: -1, onChange: "updateCompositorLayout" }, + niriLayoutRadiusOverride: { def: -1, onChange: "updateCompositorLayout" }, + niriLayoutBorderSize: { def: -1, onChange: "updateCompositorLayout" }, + hyprlandLayoutGapsOverride: { def: -1, onChange: "updateCompositorLayout" }, + hyprlandLayoutRadiusOverride: { def: -1, onChange: "updateCompositorLayout" }, + hyprlandLayoutBorderSize: { def: -1, onChange: "updateCompositorLayout" }, + mangoLayoutGapsOverride: { def: -1, onChange: "updateCompositorLayout" }, + mangoLayoutRadiusOverride: { def: -1, onChange: "updateCompositorLayout" }, + mangoLayoutBorderSize: { def: -1, onChange: "updateCompositorLayout" }, + + firstDayOfWeek: { def: -1 }, + showWeekNumber: { def: false }, + use24HourClock: { def: true }, + showSeconds: { def: false }, + padHours12Hour: { def: false }, + useFahrenheit: { def: false }, + windSpeedUnit: { def: "kmh" }, + nightModeEnabled: { def: false }, + animationSpeed: { def: 1 }, + customAnimationDuration: { def: 500 }, + syncComponentAnimationSpeeds: { def: true }, + popoutAnimationSpeed: { def: 1 }, + popoutCustomAnimationDuration: { def: 150 }, + modalAnimationSpeed: { def: 1 }, + modalCustomAnimationDuration: { def: 150 }, + enableRippleEffects: { def: true }, + m3ElevationEnabled: { def: true }, + m3ElevationIntensity: { def: 12 }, + m3ElevationOpacity: { def: 30 }, + m3ElevationColorMode: { def: "default" }, + m3ElevationLightDirection: { def: "top" }, + m3ElevationCustomColor: { def: "#000000" }, + modalElevationEnabled: { def: true }, + popoutElevationEnabled: { def: true }, + barElevationEnabled: { def: true }, + blurEnabled: { def: false }, + blurBorderColor: { def: "outline" }, + blurBorderCustomColor: { def: "#ffffff" }, + blurBorderOpacity: { def: 1.0, coerce: percentToUnit }, + wallpaperFillMode: { def: "Fill" }, + blurredWallpaperLayer: { def: false }, + blurWallpaperOnOverview: { def: false }, + + showLauncherButton: { def: true }, + showWorkspaceSwitcher: { def: true }, + showFocusedWindow: { def: true }, + showWeather: { def: true }, + showMusic: { def: true }, + showClipboard: { def: true }, + showCpuUsage: { def: true }, + showMemUsage: { def: true }, + showCpuTemp: { def: true }, + showGpuTemp: { def: true }, + selectedGpuIndex: { def: 0 }, + enabledGpuPciIds: { def: [] }, + showSystemTray: { def: true }, + showClock: { def: true }, + showNotificationButton: { def: true }, + showBattery: { def: true }, + showControlCenterButton: { def: true }, + showCapsLockIndicator: { def: true }, + + controlCenterShowNetworkIcon: { def: true }, + controlCenterShowBluetoothIcon: { def: true }, + controlCenterShowAudioIcon: { def: true }, + controlCenterShowAudioPercent: { def: false }, + controlCenterShowVpnIcon: { def: true }, + controlCenterShowBrightnessIcon: { def: false }, + controlCenterShowBrightnessPercent: { def: false }, + controlCenterShowMicIcon: { def: false }, + controlCenterShowMicPercent: { def: false }, + controlCenterShowBatteryIcon: { def: false }, + controlCenterShowPrinterIcon: { def: false }, + controlCenterShowScreenSharingIcon: { def: true }, + + showPrivacyButton: { def: true }, + privacyShowMicIcon: { def: false }, + privacyShowCameraIcon: { def: false }, + privacyShowScreenShareIcon: { def: false }, + + controlCenterWidgets: { + def: [ + { id: "volumeSlider", enabled: true, width: 50 }, + { id: "brightnessSlider", enabled: true, width: 50 }, + { id: "wifi", enabled: true, width: 50 }, + { id: "bluetooth", enabled: true, width: 50 }, + { id: "audioOutput", enabled: true, width: 50 }, + { id: "audioInput", enabled: true, width: 50 }, + { id: "nightMode", enabled: true, width: 50 }, + { id: "darkMode", enabled: true, width: 50 } + ] + }, + + showWorkspaceIndex: { def: false }, + showWorkspaceName: { def: false }, + showWorkspacePadding: { def: false }, + workspaceScrolling: { def: false }, + showWorkspaceApps: { def: false }, + workspaceDragReorder: { def: true }, + maxWorkspaceIcons: { def: 3 }, + workspaceAppIconSizeOffset: { def: 0 }, + groupWorkspaceApps: { def: true }, + workspaceFollowFocus: { def: false }, + showOccupiedWorkspacesOnly: { def: false }, + reverseScrolling: { def: false }, + dwlShowAllTags: { def: false }, + workspaceActiveAppHighlightEnabled: { def: false }, + workspaceColorMode: { def: "default" }, + workspaceOccupiedColorMode: { def: "none" }, + workspaceUnfocusedColorMode: { def: "default" }, + workspaceUrgentColorMode: { def: "default" }, + workspaceFocusedBorderEnabled: { def: false }, + workspaceFocusedBorderColor: { def: "primary" }, + workspaceFocusedBorderThickness: { def: 2 }, + workspaceNameIcons: { def: {} }, + waveProgressEnabled: { def: true }, + scrollTitleEnabled: { def: true }, + mediaAdaptiveWidthEnabled: { def: true }, + audioVisualizerEnabled: { def: true }, + audioScrollMode: { def: "volume" }, + audioWheelScrollAmount: { def: 5 }, + clockCompactMode: { def: false }, + focusedWindowCompactMode: { def: false }, + runningAppsCompactMode: { def: true }, + barMaxVisibleApps: { def: 0 }, + barMaxVisibleRunningApps: { def: 0 }, + barShowOverflowBadge: { def: true }, + appsDockHideIndicators: { def: false }, + appsDockColorizeActive: { def: false }, + appsDockActiveColorMode: { def: "primary" }, + appsDockEnlargeOnHover: { def: false }, + appsDockEnlargePercentage: { def: 125 }, + appsDockIconSizePercentage: { def: 100 }, + keyboardLayoutNameCompactMode: { def: false }, + runningAppsCurrentWorkspace: { def: true }, + runningAppsGroupByApp: { def: false }, + runningAppsCurrentMonitor: { def: false }, + appIdSubstitutions: { + def: [ + { pattern: "Spotify", replacement: "spotify", type: "exact" }, + { pattern: "beepertexts", replacement: "beeper", type: "exact" }, + { pattern: "home assistant desktop", replacement: "homeassistant-desktop", type: "exact" }, + { pattern: "com.transmissionbt.transmission", replacement: "transmission-gtk", type: "contains" }, + { pattern: "^steam_app_(\\d+)$", replacement: "steam_icon_$1", type: "regex" } + ] + }, + centeringMode: { def: "index" }, + clockDateFormat: { def: "" }, + lockDateFormat: { def: "" }, + greeterRememberLastSession: { def: true }, + greeterRememberLastUser: { def: true }, + greeterEnableFprint: { def: false, onChange: "scheduleAuthApply" }, + greeterEnableU2f: { def: false, onChange: "scheduleAuthApply" }, + greeterWallpaperPath: { def: "" }, + greeterUse24HourClock: { def: true }, + greeterShowSeconds: { def: false }, + greeterPadHours12Hour: { def: false }, + greeterLockDateFormat: { def: "" }, + greeterFontFamily: { def: "" }, + greeterWallpaperFillMode: { def: "" }, + mediaSize: { def: 1 }, + + appLauncherViewMode: { def: "list" }, + spotlightModalViewMode: { def: "list" }, + browserPickerViewMode: { def: "grid" }, + browserUsageHistory: { def: {} }, + appPickerViewMode: { def: "grid" }, + filePickerUsageHistory: { def: {} }, + sortAppsAlphabetically: { def: false }, + appLauncherGridColumns: { def: 4 }, + spotlightCloseNiriOverview: { def: true }, + rememberLastQuery: { def: false }, + spotlightSectionViewModes: { def: {} }, + appDrawerSectionViewModes: { def: {} }, + niriOverviewOverlayEnabled: { def: true }, + dankLauncherV2Size: { def: "compact" }, + dankLauncherV2BorderEnabled: { def: false }, + dankLauncherV2BorderThickness: { def: 2 }, + dankLauncherV2BorderColor: { def: "primary" }, + dankLauncherV2ShowFooter: { def: true }, + dankLauncherV2UnloadOnClose: { def: false }, + dankLauncherV2IncludeFilesInAll: { def: false }, + dankLauncherV2IncludeFoldersInAll: { def: false }, + + useAutoLocation: { def: false }, + weatherEnabled: { def: true }, + + networkPreference: { def: "auto" }, + + iconTheme: { def: "System Default", onChange: "applyStoredIconTheme" }, + availableIconThemes: { def: ["System Default"], persist: false }, + systemDefaultIconTheme: { def: "", persist: false }, + qt5ctAvailable: { def: false, persist: false }, + qt6ctAvailable: { def: false, persist: false }, + gtkAvailable: { def: false, persist: false }, + + cursorSettings: { def: { theme: "System Default", size: 24, niri: { hideWhenTyping: false, hideAfterInactiveMs: 0 }, hyprland: { hideOnKeyPress: false, hideOnTouch: false, inactiveTimeout: 0 }, dwl: { cursorHideTimeout: 0 } }, onChange: "updateCompositorCursor" }, + availableCursorThemes: { def: ["System Default"], persist: false }, + systemDefaultCursorTheme: { def: "", persist: false }, + + launcherLogoMode: { def: "os" }, + launcherLogoCustomPath: { def: "" }, + launcherLogoColorOverride: { def: "" }, + launcherLogoColorInvertOnMode: { def: false }, + launcherLogoBrightness: { def: 0.5 }, + launcherLogoContrast: { def: 1 }, + launcherLogoSizeOffset: { def: 0 }, + + fontFamily: { def: "Inter Variable" }, + monoFontFamily: { def: "Fira Code" }, + fontWeight: { def: 400 }, + fontScale: { def: 1.0 }, + + notepadUseMonospace: { def: true }, + notepadFontFamily: { def: "" }, + notepadFontSize: { def: 14 }, + notepadShowLineNumbers: { def: false }, + notepadTransparencyOverride: { def: -1 }, + notepadLastCustomTransparency: { def: 0.7 }, + + soundsEnabled: { def: true }, + useSystemSoundTheme: { def: false }, + soundLogin: { def: false }, + soundNewNotification: { def: true }, + soundVolumeChanged: { def: true }, + soundPluggedIn: { def: true }, + + acMonitorTimeout: { def: 0 }, + acLockTimeout: { def: 0 }, + acSuspendTimeout: { def: 0 }, + acSuspendBehavior: { def: 0 }, + acProfileName: { def: "" }, + batteryMonitorTimeout: { def: 0 }, + batteryLockTimeout: { def: 0 }, + batterySuspendTimeout: { def: 0 }, + batterySuspendBehavior: { def: 0 }, + batteryProfileName: { def: "" }, + batteryChargeLimit: { def: 100 }, + lockBeforeSuspend: { def: false }, + loginctlLockIntegration: { def: true }, + fadeToLockEnabled: { def: true }, + fadeToLockGracePeriod: { def: 5 }, + 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" }, + syncModeWithPortal: { def: true }, + terminalsAlwaysDark: { def: false, onChange: "regenSystemThemes" }, + + muxType: { def: "tmux" }, + muxUseCustomCommand: { def: false }, + muxCustomCommand: { def: "" }, + muxSessionFilter: { def: "" }, + + runDmsMatugenTemplates: { def: true }, + matugenTemplateGtk: { def: true }, + matugenTemplateNiri: { def: true }, + matugenTemplateHyprland: { def: true }, + matugenTemplateMangowc: { def: true }, + matugenTemplateQt5ct: { def: true }, + matugenTemplateQt6ct: { def: true }, + matugenTemplateFirefox: { def: true }, + matugenTemplatePywalfox: { def: true }, + matugenTemplateZenBrowser: { def: true }, + matugenTemplateVesktop: { def: true }, + matugenTemplateEquibop: { def: true }, + matugenTemplateGhostty: { def: true }, + matugenTemplateKitty: { def: true }, + matugenTemplateFoot: { def: true }, + matugenTemplateAlacritty: { def: true }, + matugenTemplateNeovim: { def: false }, + matugenTemplateWezterm: { def: true }, + matugenTemplateDgop: { def: true }, + matugenTemplateKcolorscheme: { def: true }, + matugenTemplateVscode: { def: true }, + matugenTemplateEmacs: { def: true }, + matugenTemplateZed: { def: true }, + + matugenTemplateNeovimSettings: { + def: { + dark: { baseTheme: "github_dark", harmony: 0.5 }, + light: { baseTheme: "github_light", harmony: 0.5 } + } + }, + matugenTemplateNeovimSetBackground: { def: true }, + + showDock: { def: false }, + dockAutoHide: { def: false }, + dockSmartAutoHide: { def: false }, + dockGroupByApp: { def: false }, + dockRestoreSpecialWorkspaceOnClick: { def: false }, + dockOpenOnOverview: { def: false }, + dockPosition: { def: 1 }, + dockSpacing: { def: 4 }, + dockBottomGap: { def: 0 }, + dockMargin: { def: 0 }, + dockIconSize: { def: 40 }, + dockIndicatorStyle: { def: "circle" }, + dockBorderEnabled: { def: false }, + dockBorderColor: { def: "surfaceText" }, + dockBorderOpacity: { def: 1.0, coerce: percentToUnit }, + dockBorderThickness: { def: 1 }, + dockIsolateDisplays: { def: false }, + dockLauncherEnabled: { def: false }, + dockLauncherLogoMode: { def: "apps" }, + dockLauncherLogoCustomPath: { def: "" }, + dockLauncherLogoColorOverride: { def: "" }, + dockLauncherLogoSizeOffset: { def: 0 }, + dockLauncherLogoBrightness: { def: 0.5, coerce: percentToUnit }, + dockLauncherLogoContrast: { def: 1, coerce: percentToUnit }, + dockMaxVisibleApps: { def: 0 }, + dockMaxVisibleRunningApps: { def: 0 }, + dockShowOverflowBadge: { def: true }, + + notificationOverlayEnabled: { def: false }, + notificationPopupShadowEnabled: { def: true }, + notificationPopupPrivacyMode: { def: false }, + overviewRows: { def: 2, persist: false }, + overviewColumns: { def: 5, persist: false }, + overviewScale: { def: 0.16, persist: false }, + + modalDarkenBackground: { def: true }, + + lockScreenShowPowerActions: { def: true }, + lockScreenShowSystemIcons: { def: true }, + lockScreenShowTime: { def: true }, + lockScreenShowDate: { def: true }, + lockScreenShowProfileImage: { def: true }, + lockScreenShowPasswordField: { def: true }, + lockScreenShowMediaPlayer: { def: true }, + lockScreenPowerOffMonitorsOnLock: { def: false }, + lockAtStartup: { def: false }, + enableFprint: { def: false, onChange: "scheduleAuthApply" }, + maxFprintTries: { def: 15 }, + enableU2f: { def: false, onChange: "scheduleAuthApply" }, + u2fMode: { def: "or" }, + lockScreenActiveMonitor: { def: "all" }, + lockScreenInactiveColor: { def: "#000000" }, + lockScreenNotificationMode: { def: 0 }, + lockScreenVideoEnabled: { def: false }, + lockScreenVideoPath: { def: "" }, + lockScreenVideoCycling: { def: false }, + hideBrightnessSlider: { def: false }, + + notificationTimeoutLow: { def: 5000 }, + notificationTimeoutNormal: { def: 5000 }, + notificationTimeoutCritical: { def: 0 }, + notificationCompactMode: { def: false }, + notificationPopupPosition: { def: 0 }, + notificationAnimationSpeed: { def: 1 }, + notificationCustomAnimationDuration: { def: 400 }, + notificationHistoryEnabled: { def: true }, + notificationHistoryMaxCount: { def: 50 }, + notificationHistoryMaxAgeDays: { def: 7 }, + notificationHistorySaveLow: { def: true }, + notificationHistorySaveNormal: { def: true }, + notificationHistorySaveCritical: { def: true }, + notificationRules: { def: [] }, + notificationFocusedMonitor: { def: false }, + + osdAlwaysShowValue: { def: false }, + osdPosition: { def: 5 }, + osdVolumeEnabled: { def: true }, + osdMediaVolumeEnabled: { def: true }, + osdMediaPlaybackEnabled: { def: false }, + osdBrightnessEnabled: { def: true }, + osdIdleInhibitorEnabled: { def: true }, + osdMicMuteEnabled: { def: true }, + osdCapsLockEnabled: { def: true }, + osdPowerProfileEnabled: { def: false }, + osdAudioOutputEnabled: { def: true }, + + powerActionConfirm: { def: true }, + powerActionHoldDuration: { def: 0.5 }, + powerMenuActions: { def: ["reboot", "logout", "poweroff", "lock", "suspend", "restart"] }, + powerMenuDefaultAction: { def: "logout" }, + powerMenuGridLayout: { def: false }, + customPowerActionLock: { def: "" }, + customPowerActionLogout: { def: "" }, + customPowerActionSuspend: { def: "" }, + customPowerActionHibernate: { def: "" }, + customPowerActionReboot: { def: "" }, + customPowerActionPowerOff: { def: "" }, + + updaterHideWidget: { def: false }, + updaterUseCustomCommand: { def: false }, + updaterCustomCommand: { def: "" }, + updaterTerminalAdditionalParams: { def: "" }, + + displayNameMode: { def: "system" }, + screenPreferences: { def: {} }, + showOnLastDisplay: { def: {} }, + niriOutputSettings: { def: {} }, + hyprlandOutputSettings: { def: {} }, + displayProfiles: { def: {} }, + activeDisplayProfile: { def: {} }, + displayProfileAutoSelect: { def: false }, + displayShowDisconnected: { def: false }, + displaySnapToEdge: { def: true }, + + barConfigs: { + def: [{ + id: "default", + name: "Main Bar", + enabled: true, + position: 0, + screenPreferences: ["all"], + showOnLastDisplay: true, + leftWidgets: ["launcherButton", "workspaceSwitcher", "focusedWindow"], + centerWidgets: ["music", "clock", "weather"], + rightWidgets: ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"], + spacing: 4, + innerPadding: 4, + bottomGap: 0, + transparency: 1.0, + widgetTransparency: 1.0, + squareCorners: false, + noBackground: false, + maximizeWidgetIcons: false, + maximizeWidgetText: false, + removeWidgetPadding: false, + widgetPadding: 8, + gothCornersEnabled: false, + gothCornerRadiusOverride: false, + gothCornerRadiusValue: 12, + borderEnabled: false, + borderColor: "surfaceText", + borderOpacity: 1.0, + borderThickness: 1, + widgetOutlineEnabled: false, + widgetOutlineColor: "primary", + widgetOutlineOpacity: 1.0, + widgetOutlineThickness: 1, + fontScale: 1.0, + iconScale: 1.0, + autoHide: false, + autoHideDelay: 250, + showOnWindowsOpen: false, + openOnOverview: false, + visible: true, + popupGapsAuto: true, + popupGapsManual: 4, + maximizeDetection: true, + scrollEnabled: true, + scrollXBehavior: "column", + scrollYBehavior: "workspace", + shadowIntensity: 0, + shadowOpacity: 60, + shadowColorMode: "default", + shadowCustomColor: "#000000", + clickThrough: false + }], onChange: "updateBarConfigs" + }, + + desktopClockEnabled: { def: false }, + desktopClockStyle: { def: "analog" }, + desktopClockTransparency: { def: 0.8, coerce: percentToUnit }, + desktopClockColorMode: { def: "primary" }, + desktopClockCustomColor: { def: "#ffffff" }, + desktopClockShowDate: { def: true }, + desktopClockShowAnalogNumbers: { def: false }, + desktopClockShowAnalogSeconds: { def: true }, + desktopClockX: { def: -1 }, + desktopClockY: { def: -1 }, + desktopClockWidth: { def: 280 }, + desktopClockHeight: { def: 180 }, + desktopClockDisplayPreferences: { def: ["all"] }, + + systemMonitorEnabled: { def: false }, + systemMonitorShowHeader: { def: true }, + systemMonitorTransparency: { def: 0.8, coerce: percentToUnit }, + systemMonitorColorMode: { def: "primary" }, + systemMonitorCustomColor: { def: "#ffffff" }, + systemMonitorShowCpu: { def: true }, + systemMonitorShowCpuGraph: { def: true }, + systemMonitorShowCpuTemp: { def: true }, + systemMonitorShowGpuTemp: { def: false }, + systemMonitorGpuPciId: { def: "" }, + systemMonitorShowMemory: { def: true }, + systemMonitorShowMemoryGraph: { def: true }, + systemMonitorShowNetwork: { def: true }, + systemMonitorShowNetworkGraph: { def: true }, + systemMonitorShowDisk: { def: true }, + systemMonitorShowTopProcesses: { def: false }, + systemMonitorTopProcessCount: { def: 3 }, + systemMonitorTopProcessSortBy: { def: "cpu" }, + systemMonitorGraphInterval: { def: 60 }, + systemMonitorLayoutMode: { def: "auto" }, + systemMonitorX: { def: -1 }, + systemMonitorY: { def: -1 }, + systemMonitorWidth: { def: 320 }, + systemMonitorHeight: { def: 480 }, + systemMonitorDisplayPreferences: { def: ["all"] }, + systemMonitorVariants: { def: [] }, + desktopWidgetPositions: { def: {} }, + desktopWidgetGridSettings: { def: {} }, + + desktopWidgetInstances: { def: [] }, + + desktopWidgetGroups: { def: [] }, + + builtInPluginSettings: { def: {} }, + clipboardEnterToPaste: { def: false }, + + launcherPluginVisibility: { def: {} }, + launcherPluginOrder: { def: [] } +}; + +function getValidKeys() { + return Object.keys(SPEC).filter(function (k) { return SPEC[k].persist !== false; }).concat(["configVersion"]); +} + +function set(root, key, value, saveFn, hooks) { + if (!(key in SPEC)) return; + root[key] = value; + var hookName = SPEC[key].onChange; + if (hookName && hooks && hooks[hookName]) { + hooks[hookName](root); + } + saveFn(); +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SettingsStore.js b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SettingsStore.js new file mode 100644 index 0000000..f88bb03 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Common/settings/SettingsStore.js @@ -0,0 +1,275 @@ +.pragma library + + .import "./SettingsSpec.js" as SpecModule + +function parse(root, jsonObj) { + var SPEC = SpecModule.SPEC; + + if (!jsonObj) return; + + for (var k in SPEC) { + if (k === "pluginSettings") continue; + // Runtime-only keys are never in the JSON; resetting them here + // would wipe values set by detection processes on every reload. + if (SPEC[k].persist === false) continue; + if (!(k in jsonObj)) { + root[k] = SPEC[k].def; + } + } + + for (var k in jsonObj) { + if (!SPEC[k]) continue; + if (k === "pluginSettings") continue; + var raw = jsonObj[k]; + var spec = SPEC[k]; + var coerce = spec.coerce; + root[k] = coerce ? (coerce(raw) !== undefined ? coerce(raw) : root[k]) : raw; + } +} + +function toJson(root) { + var SPEC = SpecModule.SPEC; + var out = {}; + for (var k in SPEC) { + if (SPEC[k].persist === false) continue; + if (k === "pluginSettings") continue; + out[k] = root[k]; + } + out.configVersion = root.settingsConfigVersion; + return out; +} + +function migrateToVersion(obj, targetVersion) { + if (!obj) return null; + + var settings = JSON.parse(JSON.stringify(obj)); + var currentVersion = settings.configVersion || 0; + + if (currentVersion >= targetVersion) { + return null; + } + + if (currentVersion < 2) { + console.info("Migrating settings from version", currentVersion, "to version 2"); + + if (settings.barConfigs === undefined) { + var position = 0; + if (settings.dankBarAtBottom !== undefined || settings.topBarAtBottom !== undefined) { + var atBottom = settings.dankBarAtBottom !== undefined ? settings.dankBarAtBottom : settings.topBarAtBottom; + position = atBottom ? 1 : 0; + } else if (settings.dankBarPosition !== undefined) { + position = settings.dankBarPosition; + } + + var defaultConfig = { + id: "default", + name: "Main Bar", + enabled: true, + position: position, + screenPreferences: ["all"], + showOnLastDisplay: true, + leftWidgets: settings.dankBarLeftWidgets || ["launcherButton", "workspaceSwitcher", "focusedWindow"], + centerWidgets: settings.dankBarCenterWidgets || ["music", "clock", "weather"], + rightWidgets: settings.dankBarRightWidgets || ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"], + spacing: settings.dankBarSpacing !== undefined ? settings.dankBarSpacing : 4, + innerPadding: settings.dankBarInnerPadding !== undefined ? settings.dankBarInnerPadding : 4, + bottomGap: settings.dankBarBottomGap !== undefined ? settings.dankBarBottomGap : 0, + transparency: settings.dankBarTransparency !== undefined ? settings.dankBarTransparency : 1.0, + widgetTransparency: settings.dankBarWidgetTransparency !== undefined ? settings.dankBarWidgetTransparency : 1.0, + squareCorners: settings.dankBarSquareCorners !== undefined ? settings.dankBarSquareCorners : false, + noBackground: settings.dankBarNoBackground !== undefined ? settings.dankBarNoBackground : false, + gothCornersEnabled: settings.dankBarGothCornersEnabled !== undefined ? settings.dankBarGothCornersEnabled : false, + gothCornerRadiusOverride: settings.dankBarGothCornerRadiusOverride !== undefined ? settings.dankBarGothCornerRadiusOverride : false, + gothCornerRadiusValue: settings.dankBarGothCornerRadiusValue !== undefined ? settings.dankBarGothCornerRadiusValue : 12, + borderEnabled: settings.dankBarBorderEnabled !== undefined ? settings.dankBarBorderEnabled : false, + borderColor: settings.dankBarBorderColor || "surfaceText", + borderOpacity: settings.dankBarBorderOpacity !== undefined ? settings.dankBarBorderOpacity : 1.0, + borderThickness: settings.dankBarBorderThickness !== undefined ? settings.dankBarBorderThickness : 1, + fontScale: settings.dankBarFontScale !== undefined ? settings.dankBarFontScale : 1.0, + autoHide: settings.dankBarAutoHide !== undefined ? settings.dankBarAutoHide : false, + autoHideDelay: settings.dankBarAutoHideDelay !== undefined ? settings.dankBarAutoHideDelay : 250, + openOnOverview: settings.dankBarOpenOnOverview !== undefined ? settings.dankBarOpenOnOverview : false, + visible: settings.dankBarVisible !== undefined ? settings.dankBarVisible : true, + popupGapsAuto: settings.popupGapsAuto !== undefined ? settings.popupGapsAuto : true, + popupGapsManual: settings.popupGapsManual !== undefined ? settings.popupGapsManual : 4 + }; + + settings.barConfigs = [defaultConfig]; + + var legacyKeys = [ + "dankBarLeftWidgets", "dankBarCenterWidgets", "dankBarRightWidgets", + "dankBarWidgetOrder", "dankBarAutoHide", "dankBarAutoHideDelay", + "dankBarOpenOnOverview", "dankBarVisible", "dankBarSpacing", + "dankBarBottomGap", "dankBarInnerPadding", "dankBarPosition", + "dankBarSquareCorners", "dankBarNoBackground", "dankBarGothCornersEnabled", + "dankBarGothCornerRadiusOverride", "dankBarGothCornerRadiusValue", + "dankBarBorderEnabled", "dankBarBorderColor", "dankBarBorderOpacity", + "dankBarBorderThickness", "popupGapsAuto", "popupGapsManual", + "dankBarAtBottom", "topBarAtBottom", "dankBarTransparency", "dankBarWidgetTransparency" + ]; + + for (var i = 0; i < legacyKeys.length; i++) { + delete settings[legacyKeys[i]]; + } + + console.info("Migrated single bar settings to barConfigs"); + } + + settings.configVersion = 2; + } + + if (currentVersion < 3) { + console.info("Migrating settings from version", currentVersion, "to version 3"); + console.info("Per-widget controlCenterButton config now supported via widgetData properties"); + settings.configVersion = 3; + } + + if (currentVersion < 4) { + console.info("Migrating settings from version", currentVersion, "to version 4"); + console.info("Migrating desktop widgets to unified desktopWidgetInstances"); + + var instances = []; + + if (settings.desktopClockEnabled) { + var clockPositions = {}; + if (settings.desktopClockX !== undefined && settings.desktopClockX >= 0) { + clockPositions["default"] = { + x: settings.desktopClockX, + y: settings.desktopClockY, + width: settings.desktopClockWidth || 280, + height: settings.desktopClockHeight || 180 + }; + } + + instances.push({ + id: "dw_clock_primary", + widgetType: "desktopClock", + name: "Desktop Clock", + enabled: true, + config: { + style: settings.desktopClockStyle || "analog", + transparency: settings.desktopClockTransparency !== undefined ? settings.desktopClockTransparency : 0.8, + colorMode: settings.desktopClockColorMode || "primary", + customColor: settings.desktopClockCustomColor || "#ffffff", + showDate: settings.desktopClockShowDate !== false, + showAnalogNumbers: settings.desktopClockShowAnalogNumbers || false, + showAnalogSeconds: settings.desktopClockShowAnalogSeconds !== false, + displayPreferences: settings.desktopClockDisplayPreferences || ["all"] + }, + positions: clockPositions + }); + } + + if (settings.systemMonitorEnabled) { + var sysmonPositions = {}; + if (settings.systemMonitorX !== undefined && settings.systemMonitorX >= 0) { + sysmonPositions["default"] = { + x: settings.systemMonitorX, + y: settings.systemMonitorY, + width: settings.systemMonitorWidth || 320, + height: settings.systemMonitorHeight || 480 + }; + } + + instances.push({ + id: "dw_sysmon_primary", + widgetType: "systemMonitor", + name: "System Monitor", + enabled: true, + config: { + showHeader: settings.systemMonitorShowHeader !== false, + transparency: settings.systemMonitorTransparency !== undefined ? settings.systemMonitorTransparency : 0.8, + colorMode: settings.systemMonitorColorMode || "primary", + customColor: settings.systemMonitorCustomColor || "#ffffff", + showCpu: settings.systemMonitorShowCpu !== false, + showCpuGraph: settings.systemMonitorShowCpuGraph !== false, + showCpuTemp: settings.systemMonitorShowCpuTemp !== false, + showGpuTemp: settings.systemMonitorShowGpuTemp || false, + gpuPciId: settings.systemMonitorGpuPciId || "", + showMemory: settings.systemMonitorShowMemory !== false, + showMemoryGraph: settings.systemMonitorShowMemoryGraph !== false, + showNetwork: settings.systemMonitorShowNetwork !== false, + showNetworkGraph: settings.systemMonitorShowNetworkGraph !== false, + showDisk: settings.systemMonitorShowDisk !== false, + showTopProcesses: settings.systemMonitorShowTopProcesses || false, + topProcessCount: settings.systemMonitorTopProcessCount || 3, + topProcessSortBy: settings.systemMonitorTopProcessSortBy || "cpu", + layoutMode: settings.systemMonitorLayoutMode || "auto", + graphInterval: settings.systemMonitorGraphInterval || 60, + displayPreferences: settings.systemMonitorDisplayPreferences || ["all"] + }, + positions: sysmonPositions + }); + } + + var variants = settings.systemMonitorVariants || []; + for (var i = 0; i < variants.length; i++) { + var v = variants[i]; + instances.push({ + id: v.id, + widgetType: "systemMonitor", + name: v.name || ("System Monitor " + (i + 2)), + enabled: true, + config: v.config || {}, + positions: v.positions || {} + }); + } + + settings.desktopWidgetInstances = instances; + settings.configVersion = 4; + } + + if (currentVersion < 5) { + console.info("Migrating settings from version", currentVersion, "to version 5"); + console.info("Moving sensitive data (weather location, coordinates) to session.json"); + + delete settings.weatherLocation; + delete settings.weatherCoordinates; + + settings.configVersion = 5; + } + + if (currentVersion < 6) { + console.info("Migrating settings from version", currentVersion, "to version 6"); + + if (settings.barElevationEnabled === undefined) { + var legacyBars = Array.isArray(settings.barConfigs) ? settings.barConfigs : []; + var hadLegacyBarShadowEnabled = false; + for (var j = 0; j < legacyBars.length; j++) { + var legacyIntensity = Number(legacyBars[j] && legacyBars[j].shadowIntensity); + if (!isNaN(legacyIntensity) && legacyIntensity > 0) { + hadLegacyBarShadowEnabled = true; + break; + } + } + settings.barElevationEnabled = hadLegacyBarShadowEnabled; + } + + settings.configVersion = 6; + } + + return settings; +} + +function cleanup(fileText) { + var getValidKeys = SpecModule.getValidKeys; + if (!fileText || !fileText.trim()) return; + + try { + var settings = JSON.parse(fileText); + var validKeys = getValidKeys(); + var needsSave = false; + + for (var key in settings) { + if (validKeys.indexOf(key) < 0) { + delete settings[key]; + needsSave = true; + } + } + + return needsSave ? JSON.stringify(settings, null, 2) : null; + } catch (e) { + console.warn("SettingsData: Failed to cleanup unused keys:", e.message); + return null; + } +} |