Files
DankMaterialShell/quickshell/Common/settings/SessionSpec.js
T
Marco MacrìandMark2Mac 521b56f1e1 fix(session): persist the idle inhibitor across shell restarts (#3123)
The idle inhibitor ("Keep Awake") lives only in memory: SessionService holds it
as a plain `property bool idleInhibited: false` and nothing ever writes it out.
Every restart of the shell silently clears it — the user's explicit choice is
dropped with no message and no trace, and the pill just disappears from the bar.

Restarting is not an edge case. `dms restart` is a first-class CLI command, and
the unit shipped in this repo (assets/systemd/dms.service) sets
`Restart=on-failure` with `TimeoutStopSec=10`, so a shell that is slow to stop
is killed and brought back automatically. Each of those paths turns Keep Awake
off without saying so.

Every other Control Center toggle already survives a restart. Measured on
upstream master, over the state read by Modules/ControlCenter/Components/
DragDropGrid.qml and its neighbours:

  doNotDisturb             in SessionSpec: yes
  isLightMode              in SessionSpec: yes
  nightModeEnabled         in SessionSpec: yes
  wallpaperCyclingEnabled  in SessionSpec: yes
  idleInhibited            in SessionSpec: NO

So this follows the doNotDisturb idiom exactly rather than inventing a
mechanism: one spec entry, one property, one setter that saves.

Restore happens through two entry points because the singletons are lazily
created and their order is not fixed: `onLoaded` covers "service instantiated
before the session file is read", `Component.onCompleted` covers the opposite.
enableIdleInhibit() is idempotent, so whichever runs second is a no-op.

The default stays false and SessionStore.toJson omits defaults, so an untouched
session.json gains no new key.

Related: #1483 asks for a configurable timer. The field added here is the same
shape doNotDisturb uses with doNotDisturbUntil, so a later `idleInhibitedUntil`
slots in beside it without another migration.

Co-authored-by: Mark2Mac <[email protected]>
2026-08-20 13:06:26 -04:00

134 lines
4.1 KiB
JavaScript

.pragma library
var SPEC = {
isLightMode: { def: false },
doNotDisturb: { def: false },
doNotDisturbUntil: { def: 0 },
idleInhibited: { def: false },
terminalOverride: { def: "" },
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 },
wallpaperCyclingRandom: { 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: "" },
nightModeLocationName: { 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 },
pluginBrowserInstalledFirst: { def: false },
pluginBrowserSortMode: { def: "default" },
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: "" },
bluetoothAdapterOverride: { def: "" },
lastPlayerIdentity: { def: "" },
deviceMaxVolumes: { def: {} },
hiddenOutputDeviceNames: { def: [] },
hiddenInputDeviceNames: { def: [] },
locale: { def: "", onChange: "updateLocale" },
timeLocale: { def: "" },
notepadLastMode: { def: "" },
niriOutputSettings: { def: {} },
hyprlandOutputSettings: { def: {} },
activeDisplayProfile: { def: {} },
activeDisplayProfileModes: { def: {} },
desktopWidgetGridSettings: { def: {} },
desktopWidgetInstancePositions: { def: {} },
builtInPluginState: { def: {} },
greeterSyncPending: { def: false },
greeterSyncBaseline: { def: {} },
lastAppliedIconTheme: { def: "" },
launcherLastMode: { def: "all" },
launcherLastFileSearchType: { def: "all" },
launcherLastQuery: { def: "" },
launcherQueryHistory: { def: [] },
appDrawerLastMode: { def: "apps" },
niriOverviewLastMode: { def: "apps" },
settingsSidebarExpandedIds: { def: "," },
settingsSidebarCollapsedIds: { def: "," },
showConfigReloadToast: { def: true }
};
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();
}