mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-27 05:27:47 -04:00
Turn on do not disturb while a screen share is active so notification popups and their contents stay off the shared screen. The unread dot and the existing dnd bypasses are unaffected. Detection reuses the screen sharing privacy indicator: niri cast ipc, otherwise pipewire and xdg-desktop-portal. Neither source says when it has finished reporting, so a share reading as gone is only acted on once it stays gone for four seconds. Engaging stays immediate, and turning the setting off releases right away since that is a user action rather than a detection guess. Turning dnd off by hand during a share is remembered against the sources that were sharing at the time, so it holds for that share and across a shell reload. A share started after that one has ended gets a fresh decision. Co-authored-by: Claude Opus 5 <[email protected]>
1820 lines
57 KiB
QML
1820 lines
57 KiB
QML
pragma Singleton
|
|
pragma ComponentBehavior: Bound
|
|
|
|
import QtCore
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Common
|
|
import qs.Services
|
|
import "settings/SessionSpec.js" as Spec
|
|
import "settings/SessionStore.js" as Store
|
|
|
|
Singleton {
|
|
id: root
|
|
readonly property var log: Log.scoped("SessionData")
|
|
|
|
readonly property int sessionConfigVersion: 4
|
|
|
|
readonly property bool isGreeterMode: Quickshell.env("DMS_RUN_GREETER") === "1" || Quickshell.env("DMS_RUN_GREETER") === "true"
|
|
|
|
signal loaded
|
|
signal brightnessDisplayHintChanged(string deviceName)
|
|
signal loadErrorOccurred(string file, string message)
|
|
|
|
property bool _parseError: false
|
|
property bool _hasLoaded: false
|
|
property bool _isReadOnly: false
|
|
property bool _hasUnsavedChanges: false
|
|
property var _loadedSessionSnapshot: null
|
|
readonly property var _hooks: ({
|
|
"updateLocale": updateLocale
|
|
})
|
|
readonly property string _stateUrl: StandardPaths.writableLocation(StandardPaths.GenericStateLocation)
|
|
readonly property string _stateDir: Paths.strip(_stateUrl)
|
|
|
|
property bool isLightMode: false
|
|
property bool doNotDisturb: false
|
|
property real doNotDisturbUntil: 0
|
|
property bool doNotDisturbHeldByScreenShare: false
|
|
property bool screenShareDndDismissed: false
|
|
property var screenShareDismissedIds: []
|
|
property bool idleInhibited: false
|
|
property real idleInhibitedUntil: 0
|
|
property string terminalOverride: ""
|
|
property bool isSwitchingMode: false
|
|
property bool suppressOSD: true
|
|
|
|
readonly property var terminalOptions: ["ghostty", "kitty", "foot", "alacritty", "wezterm", "konsole", "gnome-terminal", "xterm"]
|
|
property var installedTerminals: []
|
|
|
|
function resolveTerminal() {
|
|
if (terminalOverride && terminalOverride.length > 0) {
|
|
return terminalOverride;
|
|
}
|
|
const env = Quickshell.env("TERMINAL");
|
|
if (env && env.length > 0) {
|
|
return env;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
Process {
|
|
id: terminalProbe
|
|
running: true
|
|
command: ["sh", "-c", "for t in ghostty kitty foot alacritty wezterm konsole gnome-terminal xterm; do command -v \"$t\" >/dev/null 2>&1 && echo \"$t\"; done"]
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
const found = text.trim().split("\n").filter(line => line.length > 0);
|
|
root.installedTerminals = found;
|
|
}
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
id: dndExpireTimer
|
|
repeat: false
|
|
running: false
|
|
onTriggered: root.setDoNotDisturb(false, 0, "timer")
|
|
}
|
|
|
|
Timer {
|
|
id: screenShareReleaseTimer
|
|
interval: 4000
|
|
repeat: false
|
|
running: false
|
|
onTriggered: root._endScreenShareDnd()
|
|
}
|
|
|
|
function _armDndExpireTimer() {
|
|
dndExpireTimer.stop();
|
|
if (!doNotDisturb || doNotDisturbUntil <= 0)
|
|
return;
|
|
const remaining = doNotDisturbUntil - Date.now();
|
|
if (remaining <= 0) {
|
|
setDoNotDisturb(false, 0, "timer");
|
|
return;
|
|
}
|
|
dndExpireTimer.interval = remaining;
|
|
dndExpireTimer.start();
|
|
}
|
|
|
|
onDoNotDisturbChanged: _armDndExpireTimer()
|
|
onDoNotDisturbUntilChanged: _armDndExpireTimer()
|
|
|
|
Timer {
|
|
id: osdSuppressTimer
|
|
interval: 2000
|
|
running: true
|
|
onTriggered: root.suppressOSD = false
|
|
}
|
|
|
|
function suppressOSDTemporarily() {
|
|
suppressOSD = true;
|
|
osdSuppressTimer.restart();
|
|
}
|
|
|
|
Connections {
|
|
target: SessionService
|
|
function onSessionResumed() {
|
|
root.suppressOSD = true;
|
|
osdSuppressTimer.restart();
|
|
root._applyDndExpirySanity();
|
|
Qt.callLater(root._syncScreenShareDnd);
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: (!root.isGreeterMode && typeof SettingsData !== "undefined" && SettingsData.notificationDndWhileScreenSharing && typeof PrivacyService !== "undefined") ? PrivacyService : null
|
|
function onScreensharingActiveChanged() {
|
|
root._syncScreenShareDnd();
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: typeof SettingsData !== "undefined" ? SettingsData : null
|
|
function onNotificationDndWhileScreenSharingChanged() {
|
|
root._syncScreenShareDnd();
|
|
}
|
|
}
|
|
|
|
property string wallpaperPath: ""
|
|
property bool perMonitorWallpaper: false
|
|
property var monitorWallpapers: ({})
|
|
property bool perModeWallpaper: false
|
|
property string wallpaperPathLight: ""
|
|
property string wallpaperPathDark: ""
|
|
property var monitorWallpapersLight: ({})
|
|
property var monitorWallpapersDark: ({})
|
|
property var monitorWallpaperFillModes: ({})
|
|
|
|
// Map: screenName -> { scrollX, scrollY } (0-100 range, like workspace percentage)
|
|
property var monitorScrollPositions: ({})
|
|
|
|
function setMonitorScrollPosition(screenName, scrollX, scrollY) {
|
|
var newPositions = Object.assign({}, monitorScrollPositions);
|
|
newPositions[screenName] = {
|
|
scrollX: scrollX,
|
|
scrollY: scrollY
|
|
};
|
|
monitorScrollPositions = newPositions;
|
|
}
|
|
|
|
function getMonitorScrollPosition(screenName) {
|
|
return monitorScrollPositions[screenName] || {
|
|
scrollX: 50,
|
|
scrollY: 50
|
|
};
|
|
}
|
|
|
|
function clearMonitorScrollPosition(screenName) {
|
|
var newPositions = Object.assign({}, monitorScrollPositions);
|
|
delete newPositions[screenName];
|
|
monitorScrollPositions = newPositions;
|
|
}
|
|
|
|
property string wallpaperTransition: "fade"
|
|
readonly property var availableWallpaperTransitions: ["none", "fade", "wipe", "disc", "stripes", "iris bloom", "pixelate", "portal"]
|
|
property var includedTransitions: availableWallpaperTransitions.filter(t => t !== "none")
|
|
|
|
property bool wallpaperCyclingEnabled: false
|
|
property bool wallpaperCyclingRandom: false
|
|
property string wallpaperCyclingMode: "interval"
|
|
property int wallpaperCyclingInterval: 300
|
|
property string wallpaperCyclingTime: "06:00"
|
|
property string wallpaperCyclingFolderPath: ""
|
|
property var monitorCyclingSettings: ({})
|
|
|
|
property bool nightModeEnabled: false
|
|
property int nightModeTemperature: 4500
|
|
property int nightModeHighTemperature: 6500
|
|
property bool nightModeAutoEnabled: false
|
|
property string nightModeAutoMode: "time"
|
|
property int nightModeStartHour: 18
|
|
property int nightModeStartMinute: 0
|
|
property int nightModeEndHour: 6
|
|
property int nightModeEndMinute: 0
|
|
property int nightModeTransitionMinutes: 60
|
|
property real displayGamma: 1.0
|
|
property real displayContrast: 1.0
|
|
property real latitude: 0.0
|
|
property real longitude: 0.0
|
|
property bool nightModeUseIPLocation: false
|
|
property string nightModeLocationProvider: ""
|
|
property string nightModeLocationName: ""
|
|
|
|
property bool themeModeAutoEnabled: false
|
|
property string themeModeAutoMode: "time"
|
|
property int themeModeStartHour: 18
|
|
property int themeModeStartMinute: 0
|
|
property int themeModeEndHour: 6
|
|
property int themeModeEndMinute: 0
|
|
property bool themeModeShareGammaSettings: true
|
|
property string themeModeNextTransition: ""
|
|
|
|
property var pinnedApps: []
|
|
property var barPinnedApps: []
|
|
property int dockLauncherPosition: 0
|
|
property var hiddenTrayIds: []
|
|
property var trayItemOrder: []
|
|
property var recentColors: []
|
|
property bool showThirdPartyPlugins: false
|
|
property bool pluginBrowserInstalledFirst: false
|
|
property bool pluginBrowserHideInstalled: true
|
|
property string pluginBrowserSortMode: "default"
|
|
property string launchPrefix: ""
|
|
property string lastBrightnessDevice: ""
|
|
property var brightnessExponentialDevices: ({})
|
|
property var brightnessUserSetValues: ({})
|
|
property var brightnessExponentValues: ({})
|
|
|
|
property int selectedGpuIndex: 0
|
|
property bool nvidiaGpuTempEnabled: false
|
|
property bool nonNvidiaGpuTempEnabled: false
|
|
property var enabledGpuPciIds: []
|
|
|
|
property string wifiDeviceOverride: ""
|
|
property bool weatherHourlyDetailed: true
|
|
|
|
property string weatherLocation: "New York, NY"
|
|
property string weatherCoordinates: "40.7128,-74.0060"
|
|
|
|
property var hiddenApps: []
|
|
property var appOverrides: ({})
|
|
property bool searchAppActions: true
|
|
|
|
property string vpnLastConnected: ""
|
|
|
|
property string bluetoothAdapterOverride: ""
|
|
|
|
property string lastPlayerIdentity: ""
|
|
property string pinnedPlayerIdentity: ""
|
|
|
|
property var deviceMaxVolumes: ({})
|
|
property var hiddenOutputDeviceNames: []
|
|
property var hiddenInputDeviceNames: []
|
|
|
|
property string locale: ""
|
|
property string timeLocale: ""
|
|
|
|
property string notepadLastMode: ""
|
|
|
|
property var niriOutputSettings: ({})
|
|
property var hyprlandOutputSettings: ({})
|
|
property var activeDisplayProfile: ({})
|
|
property var activeDisplayProfileModes: ({})
|
|
property var desktopWidgetGridSettings: ({})
|
|
property var desktopWidgetInstancePositions: ({})
|
|
property var builtInPluginState: ({})
|
|
property bool greeterSyncPending: false
|
|
property var greeterSyncBaseline: ({})
|
|
property string lastAppliedIconTheme: ""
|
|
|
|
property string launcherLastMode: "all"
|
|
property string launcherLastFileSearchType: "all"
|
|
property string launcherLastQuery: ""
|
|
property var launcherQueryHistory: []
|
|
property string appDrawerLastMode: "apps"
|
|
property string niriOverviewLastMode: "apps"
|
|
property string settingsSidebarExpandedIds: ","
|
|
property string settingsSidebarCollapsedIds: ","
|
|
property bool showConfigReloadToast: true
|
|
|
|
Component.onCompleted: {
|
|
loadSettings();
|
|
}
|
|
|
|
property var _pendingMigration: null
|
|
|
|
function loadSettings() {
|
|
_hasUnsavedChanges = false;
|
|
_pendingMigration = null;
|
|
|
|
if (isGreeterMode) {
|
|
parseSettings(greeterSessionFile.text());
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const txt = settingsFile.text();
|
|
let obj = (txt && txt.trim()) ? JSON.parse(txt) : null;
|
|
|
|
if (obj?.brightnessLogarithmicDevices && !obj?.brightnessExponentialDevices)
|
|
obj.brightnessExponentialDevices = obj.brightnessLogarithmicDevices;
|
|
|
|
if (obj?.nightModeStartTime !== undefined) {
|
|
const parts = obj.nightModeStartTime.split(":");
|
|
obj.nightModeStartHour = parseInt(parts[0]) || 18;
|
|
obj.nightModeStartMinute = parseInt(parts[1]) || 0;
|
|
}
|
|
if (obj?.nightModeEndTime !== undefined) {
|
|
const parts = obj.nightModeEndTime.split(":");
|
|
obj.nightModeEndHour = parseInt(parts[0]) || 6;
|
|
obj.nightModeEndMinute = parseInt(parts[1]) || 0;
|
|
}
|
|
|
|
const oldVersion = obj?.configVersion ?? 0;
|
|
if (obj && oldVersion === 0)
|
|
migrateFromUndefinedToV1(obj);
|
|
|
|
if (obj && oldVersion < sessionConfigVersion) {
|
|
const settingsDataRef = (typeof SettingsData !== "undefined") ? SettingsData : null;
|
|
const migrated = Store.migrateToVersion(obj, sessionConfigVersion, settingsDataRef);
|
|
if (migrated) {
|
|
_pendingMigration = migrated;
|
|
obj = migrated;
|
|
}
|
|
}
|
|
|
|
Store.parse(root, obj);
|
|
_applyDndExpirySanity();
|
|
_applyIdleInhibitExpirySanity();
|
|
|
|
_loadedSessionSnapshot = getCurrentSessionJson();
|
|
_hasLoaded = true;
|
|
|
|
if (!isGreeterMode && typeof Theme !== "undefined")
|
|
Theme.generateSystemThemesFromCurrentTheme();
|
|
|
|
loaded();
|
|
Qt.callLater(root._syncScreenShareDnd);
|
|
|
|
_checkSessionWritable();
|
|
} catch (e) {
|
|
_parseError = true;
|
|
const msg = e.message;
|
|
log.error("Failed to parse session.json - file will not be overwritten.");
|
|
Qt.callLater(() => loadErrorOccurred("session.json", msg));
|
|
}
|
|
}
|
|
|
|
function _checkSessionWritable() {
|
|
sessionWritableCheckProcess.running = true;
|
|
}
|
|
|
|
function _onWritableCheckComplete(writable) {
|
|
const wasReadOnly = _isReadOnly;
|
|
_isReadOnly = !writable;
|
|
if (_isReadOnly) {
|
|
_hasUnsavedChanges = _checkForUnsavedChanges();
|
|
} else {
|
|
_loadedSessionSnapshot = getCurrentSessionJson();
|
|
_hasUnsavedChanges = false;
|
|
if (wasReadOnly && _pendingMigration)
|
|
settingsFile.setText(JSON.stringify(_pendingMigration, null, 2));
|
|
}
|
|
_pendingMigration = null;
|
|
}
|
|
|
|
function _checkForUnsavedChanges() {
|
|
if (!_hasLoaded || !_loadedSessionSnapshot)
|
|
return false;
|
|
const current = getCurrentSessionJson();
|
|
return current !== _loadedSessionSnapshot;
|
|
}
|
|
|
|
function getCurrentSessionJson() {
|
|
return JSON.stringify(Store.toJson(root), null, 2);
|
|
}
|
|
|
|
function parseSettings(content) {
|
|
_parseError = false;
|
|
try {
|
|
let obj = (content && content.trim()) ? JSON.parse(content) : null;
|
|
|
|
if (obj?.brightnessLogarithmicDevices && !obj?.brightnessExponentialDevices)
|
|
obj.brightnessExponentialDevices = obj.brightnessLogarithmicDevices;
|
|
|
|
if (obj?.nightModeStartTime !== undefined) {
|
|
const parts = obj.nightModeStartTime.split(":");
|
|
obj.nightModeStartHour = parseInt(parts[0]) || 18;
|
|
obj.nightModeStartMinute = parseInt(parts[1]) || 0;
|
|
}
|
|
if (obj?.nightModeEndTime !== undefined) {
|
|
const parts = obj.nightModeEndTime.split(":");
|
|
obj.nightModeEndHour = parseInt(parts[0]) || 6;
|
|
obj.nightModeEndMinute = parseInt(parts[1]) || 0;
|
|
}
|
|
|
|
const oldVersion = obj?.configVersion ?? 0;
|
|
if (obj && oldVersion === 0)
|
|
migrateFromUndefinedToV1(obj);
|
|
|
|
if (obj && oldVersion < sessionConfigVersion) {
|
|
const settingsDataRef = (typeof SettingsData !== "undefined") ? SettingsData : null;
|
|
const migrated = Store.migrateToVersion(obj, sessionConfigVersion, settingsDataRef);
|
|
if (migrated) {
|
|
_pendingMigration = migrated;
|
|
obj = migrated;
|
|
}
|
|
}
|
|
|
|
Store.parse(root, obj);
|
|
_applyDndExpirySanity();
|
|
_applyIdleInhibitExpirySanity();
|
|
|
|
_loadedSessionSnapshot = getCurrentSessionJson();
|
|
_hasLoaded = true;
|
|
|
|
if (!isGreeterMode && typeof Theme !== "undefined")
|
|
Theme.generateSystemThemesFromCurrentTheme();
|
|
|
|
loaded();
|
|
Qt.callLater(root._syncScreenShareDnd);
|
|
} catch (e) {
|
|
_parseError = true;
|
|
const msg = e.message;
|
|
log.error("Failed to parse session.json - file will not be overwritten.");
|
|
Qt.callLater(() => loadErrorOccurred("session.json", msg));
|
|
}
|
|
}
|
|
|
|
function _applyDndExpirySanity() {
|
|
if (doNotDisturb && doNotDisturbUntil > 0 && Date.now() >= doNotDisturbUntil) {
|
|
doNotDisturb = false;
|
|
doNotDisturbUntil = 0;
|
|
} else if (!doNotDisturb && doNotDisturbUntil !== 0) {
|
|
doNotDisturbUntil = 0;
|
|
}
|
|
_armDndExpireTimer();
|
|
}
|
|
|
|
function _applyIdleInhibitExpirySanity() {
|
|
if (idleInhibited && idleInhibitedUntil > 0 && Date.now() >= idleInhibitedUntil) {
|
|
idleInhibited = false;
|
|
idleInhibitedUntil = 0;
|
|
} else if (!idleInhibited && idleInhibitedUntil !== 0) {
|
|
idleInhibitedUntil = 0;
|
|
}
|
|
}
|
|
|
|
function saveSettings() {
|
|
if (isGreeterMode || _parseError || !_hasLoaded)
|
|
return;
|
|
settingsFile.setText(getCurrentSessionJson());
|
|
if (_isReadOnly)
|
|
_checkSessionWritable();
|
|
}
|
|
|
|
function set(key, value) {
|
|
Spec.set(root, key, value, saveSettings, _hooks);
|
|
}
|
|
|
|
function importFromSettings(payload) {
|
|
if (!payload)
|
|
return;
|
|
if (!_hasLoaded)
|
|
loadSettings();
|
|
if (_parseError)
|
|
return;
|
|
|
|
let imported = false;
|
|
for (const key in payload) {
|
|
if (!(key in Spec.SPEC))
|
|
continue;
|
|
const current = root[key];
|
|
const isEmpty = current === Spec.SPEC[key].def || (typeof current === "object" && current !== null && Object.keys(current).length === 0);
|
|
if (!isEmpty)
|
|
continue;
|
|
root[key] = payload[key];
|
|
imported = true;
|
|
}
|
|
|
|
if (imported) {
|
|
log.info("Imported machine-specific state from settings.json");
|
|
saveSettings();
|
|
}
|
|
}
|
|
|
|
function getNiriOutputSetting(outputId, key, defaultValue) {
|
|
if (!niriOutputSettings[outputId])
|
|
return defaultValue;
|
|
return niriOutputSettings[outputId][key] !== undefined ? niriOutputSettings[outputId][key] : defaultValue;
|
|
}
|
|
|
|
function setNiriOutputSetting(outputId, key, value) {
|
|
const updated = JSON.parse(JSON.stringify(niriOutputSettings));
|
|
if (!updated[outputId])
|
|
updated[outputId] = {};
|
|
updated[outputId][key] = value;
|
|
niriOutputSettings = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function getNiriOutputSettings(outputId) {
|
|
const settings = niriOutputSettings[outputId];
|
|
return settings ? JSON.parse(JSON.stringify(settings)) : {};
|
|
}
|
|
|
|
function getHyprlandOutputSetting(outputId, key, defaultValue) {
|
|
if (!hyprlandOutputSettings[outputId])
|
|
return defaultValue;
|
|
return hyprlandOutputSettings[outputId][key] !== undefined ? hyprlandOutputSettings[outputId][key] : defaultValue;
|
|
}
|
|
|
|
function setHyprlandOutputSetting(outputId, key, value) {
|
|
const updated = JSON.parse(JSON.stringify(hyprlandOutputSettings));
|
|
if (!updated[outputId])
|
|
updated[outputId] = {};
|
|
updated[outputId][key] = value;
|
|
hyprlandOutputSettings = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function removeHyprlandOutputSetting(outputId, key) {
|
|
if (!hyprlandOutputSettings[outputId] || !(key in hyprlandOutputSettings[outputId]))
|
|
return;
|
|
const updated = JSON.parse(JSON.stringify(hyprlandOutputSettings));
|
|
delete updated[outputId][key];
|
|
hyprlandOutputSettings = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function getActiveDisplayProfile(compositor) {
|
|
return activeDisplayProfile[compositor] || "";
|
|
}
|
|
|
|
function setActiveDisplayProfile(compositor, profileId) {
|
|
const updated = JSON.parse(JSON.stringify(activeDisplayProfile));
|
|
updated[compositor] = profileId;
|
|
activeDisplayProfile = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function setActiveDisplayProfileModes(compositor, modes) {
|
|
if (JSON.stringify(activeDisplayProfileModes[compositor] || {}) === JSON.stringify(modes || {}))
|
|
return;
|
|
const updated = JSON.parse(JSON.stringify(activeDisplayProfileModes));
|
|
updated[compositor] = modes;
|
|
activeDisplayProfileModes = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function getDesktopWidgetGridSetting(screenKey, property, defaultValue) {
|
|
const val = desktopWidgetGridSettings?.[screenKey]?.[property];
|
|
return val !== undefined ? val : defaultValue;
|
|
}
|
|
|
|
function setDesktopWidgetGridSetting(screenKey, property, value) {
|
|
const allSettings = JSON.parse(JSON.stringify(desktopWidgetGridSettings || {}));
|
|
if (!allSettings[screenKey])
|
|
allSettings[screenKey] = {};
|
|
allSettings[screenKey][property] = value;
|
|
desktopWidgetGridSettings = allSettings;
|
|
saveSettings();
|
|
}
|
|
|
|
function updateDesktopWidgetInstancePosition(instanceId, screenKey, positionUpdates) {
|
|
const updated = JSON.parse(JSON.stringify(desktopWidgetInstancePositions));
|
|
if (!updated[instanceId])
|
|
updated[instanceId] = {};
|
|
updated[instanceId][screenKey] = Object.assign({}, updated[instanceId][screenKey] || {}, positionUpdates);
|
|
desktopWidgetInstancePositions = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function syncDesktopWidgetPositionToAllScreens(instanceId) {
|
|
const positions = desktopWidgetInstancePositions[instanceId] || {};
|
|
const screenKeys = Object.keys(positions).filter(k => k !== "_synced");
|
|
if (screenKeys.length === 0)
|
|
return;
|
|
const sourcePos = positions[screenKeys[0]];
|
|
if (!sourcePos)
|
|
return;
|
|
const screen = Array.from(Quickshell.screens.values()).find(s => SettingsData.getScreenDisplayName(s) === screenKeys[0]);
|
|
if (!screen)
|
|
return;
|
|
const synced = {};
|
|
if (sourcePos.x !== undefined)
|
|
synced.x = sourcePos.x / screen.width;
|
|
if (sourcePos.y !== undefined)
|
|
synced.y = sourcePos.y / screen.height;
|
|
if (sourcePos.width !== undefined)
|
|
synced.width = sourcePos.width;
|
|
if (sourcePos.height !== undefined)
|
|
synced.height = sourcePos.height;
|
|
const updated = JSON.parse(JSON.stringify(desktopWidgetInstancePositions));
|
|
updated[instanceId]["_synced"] = synced;
|
|
desktopWidgetInstancePositions = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function removeDesktopWidgetInstancePositions(instanceId) {
|
|
if (!(instanceId in desktopWidgetInstancePositions))
|
|
return;
|
|
const updated = JSON.parse(JSON.stringify(desktopWidgetInstancePositions));
|
|
delete updated[instanceId];
|
|
desktopWidgetInstancePositions = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function setBuiltInPluginState(pluginId, state) {
|
|
const updated = JSON.parse(JSON.stringify(builtInPluginState));
|
|
updated[pluginId] = state;
|
|
builtInPluginState = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function migrateFromUndefinedToV1(settings) {
|
|
if (typeof SettingsData !== "undefined") {
|
|
if (settings.acMonitorTimeout !== undefined) {
|
|
SettingsData.set("acMonitorTimeout", settings.acMonitorTimeout);
|
|
}
|
|
if (settings.acLockTimeout !== undefined) {
|
|
SettingsData.set("acLockTimeout", settings.acLockTimeout);
|
|
}
|
|
if (settings.acSuspendTimeout !== undefined) {
|
|
SettingsData.set("acSuspendTimeout", settings.acSuspendTimeout);
|
|
}
|
|
if (settings.acHibernateTimeout !== undefined) {
|
|
SettingsData.set("acHibernateTimeout", settings.acHibernateTimeout);
|
|
}
|
|
if (settings.batteryMonitorTimeout !== undefined) {
|
|
SettingsData.set("batteryMonitorTimeout", settings.batteryMonitorTimeout);
|
|
}
|
|
if (settings.batteryLockTimeout !== undefined) {
|
|
SettingsData.set("batteryLockTimeout", settings.batteryLockTimeout);
|
|
}
|
|
if (settings.batterySuspendTimeout !== undefined) {
|
|
SettingsData.set("batterySuspendTimeout", settings.batterySuspendTimeout);
|
|
}
|
|
if (settings.batteryHibernateTimeout !== undefined) {
|
|
SettingsData.set("batteryHibernateTimeout", settings.batteryHibernateTimeout);
|
|
}
|
|
if (settings.lockBeforeSuspend !== undefined) {
|
|
SettingsData.set("lockBeforeSuspend", settings.lockBeforeSuspend);
|
|
}
|
|
if (settings.loginctlLockIntegration !== undefined) {
|
|
SettingsData.set("loginctlLockIntegration", settings.loginctlLockIntegration);
|
|
}
|
|
if (settings.launchPrefix !== undefined) {
|
|
SettingsData.set("launchPrefix", settings.launchPrefix);
|
|
}
|
|
}
|
|
if (typeof CacheData !== "undefined") {
|
|
if (settings.wallpaperLastPath !== undefined) {
|
|
CacheData.wallpaperLastPath = settings.wallpaperLastPath;
|
|
}
|
|
if (settings.profileLastPath !== undefined) {
|
|
CacheData.profileLastPath = settings.profileLastPath;
|
|
}
|
|
CacheData.saveCache();
|
|
}
|
|
}
|
|
|
|
function setLightMode(lightMode, skipWallpaperSync) {
|
|
isSwitchingMode = true;
|
|
if (!skipWallpaperSync)
|
|
syncWallpaperForCurrentMode(lightMode);
|
|
isLightMode = lightMode;
|
|
saveSettings();
|
|
Qt.callLater(() => {
|
|
isSwitchingMode = false;
|
|
});
|
|
}
|
|
|
|
function setDoNotDisturb(enabled, durationMinutes, origin) {
|
|
const src = origin || "user";
|
|
if (src === "user") {
|
|
if (!enabled && _screenShareShouldHold()) {
|
|
screenShareDndDismissed = true;
|
|
screenShareDismissedIds = _screencastIds();
|
|
}
|
|
if (doNotDisturbHeldByScreenShare)
|
|
doNotDisturbHeldByScreenShare = false;
|
|
}
|
|
|
|
const minutes = Number(durationMinutes) || 0;
|
|
doNotDisturb = enabled;
|
|
doNotDisturbUntil = (enabled && minutes > 0) ? Date.now() + minutes * 60 * 1000 : 0;
|
|
saveSettings();
|
|
|
|
if (src !== "screenshare")
|
|
Qt.callLater(_syncScreenShareDnd);
|
|
}
|
|
|
|
function setIdleInhibited(enabled, durationMinutes) {
|
|
const next = !!enabled;
|
|
const minutes = Number(durationMinutes) || 0;
|
|
const nextUntil = (next && minutes > 0) ? Date.now() + minutes * 60 * 1000 : 0;
|
|
if (idleInhibited === next && idleInhibitedUntil === nextUntil)
|
|
return;
|
|
idleInhibited = next;
|
|
idleInhibitedUntil = nextUntil;
|
|
saveSettings();
|
|
}
|
|
|
|
function setDoNotDisturbUntilTimestamp(timestampMs) {
|
|
const target = Number(timestampMs) || 0;
|
|
if (target <= Date.now()) {
|
|
setDoNotDisturb(false);
|
|
return;
|
|
}
|
|
if (doNotDisturbHeldByScreenShare)
|
|
doNotDisturbHeldByScreenShare = false;
|
|
doNotDisturb = true;
|
|
doNotDisturbUntil = target;
|
|
saveSettings();
|
|
}
|
|
|
|
function _screenShareShouldHold() {
|
|
if (isGreeterMode)
|
|
return false;
|
|
if (typeof SettingsData === "undefined" || !SettingsData.notificationDndWhileScreenSharing)
|
|
return false;
|
|
if (typeof PrivacyService === "undefined" || !PrivacyService.screensharingActive)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
function _screencastIds() {
|
|
return (typeof PrivacyService !== "undefined") ? PrivacyService.screencastSourceIds() : [];
|
|
}
|
|
|
|
function _dismissalApplies() {
|
|
if (!screenShareDndDismissed)
|
|
return false;
|
|
const dismissed = screenShareDismissedIds || [];
|
|
if (!dismissed.length)
|
|
return true;
|
|
const current = _screencastIds();
|
|
if (!current.length)
|
|
return true;
|
|
return current.some(id => dismissed.indexOf(id) !== -1);
|
|
}
|
|
|
|
function _releaseScreenShareDndHold() {
|
|
if (!doNotDisturbHeldByScreenShare)
|
|
return;
|
|
doNotDisturbHeldByScreenShare = false;
|
|
if (!doNotDisturb || doNotDisturbUntil > 0) {
|
|
saveSettings();
|
|
return;
|
|
}
|
|
setDoNotDisturb(false, 0, "screenshare");
|
|
}
|
|
|
|
function _endScreenShareDnd() {
|
|
_clearScreenShareDismissal();
|
|
_releaseScreenShareDndHold();
|
|
}
|
|
|
|
function _clearScreenShareDismissal() {
|
|
if (!screenShareDndDismissed)
|
|
return;
|
|
screenShareDndDismissed = false;
|
|
screenShareDismissedIds = [];
|
|
saveSettings();
|
|
}
|
|
|
|
function _syncScreenShareDnd() {
|
|
if (isGreeterMode)
|
|
return;
|
|
|
|
if (!_screenShareShouldHold()) {
|
|
if (!doNotDisturbHeldByScreenShare && !screenShareDndDismissed)
|
|
return;
|
|
const settingOn = typeof SettingsData !== "undefined" && SettingsData.notificationDndWhileScreenSharing;
|
|
if (!settingOn) {
|
|
screenShareReleaseTimer.stop();
|
|
_endScreenShareDnd();
|
|
return;
|
|
}
|
|
screenShareReleaseTimer.restart();
|
|
return;
|
|
}
|
|
|
|
screenShareReleaseTimer.stop();
|
|
|
|
if (!_dismissalApplies())
|
|
_clearScreenShareDismissal();
|
|
|
|
if (screenShareDndDismissed || doNotDisturb)
|
|
return;
|
|
|
|
doNotDisturbHeldByScreenShare = true;
|
|
setDoNotDisturb(true, 0, "screenshare");
|
|
}
|
|
|
|
function setWallpaper(imagePath) {
|
|
wallpaperPath = imagePath;
|
|
if (perModeWallpaper) {
|
|
if (isLightMode) {
|
|
wallpaperPathLight = imagePath;
|
|
} else {
|
|
wallpaperPathDark = imagePath;
|
|
}
|
|
}
|
|
saveSettings();
|
|
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme();
|
|
}
|
|
}
|
|
|
|
function setWallpaperColor(color) {
|
|
wallpaperPath = color;
|
|
if (perModeWallpaper) {
|
|
if (isLightMode) {
|
|
wallpaperPathLight = color;
|
|
} else {
|
|
wallpaperPathDark = color;
|
|
}
|
|
}
|
|
saveSettings();
|
|
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme();
|
|
}
|
|
}
|
|
|
|
function clearWallpaper() {
|
|
wallpaperPath = "";
|
|
saveSettings();
|
|
|
|
if (typeof Theme !== "undefined") {
|
|
if (typeof SettingsData !== "undefined" && SettingsData.theme) {
|
|
Theme.switchTheme(SettingsData.theme);
|
|
} else {
|
|
Theme.switchTheme("purple");
|
|
}
|
|
}
|
|
}
|
|
|
|
function setPerMonitorWallpaper(enabled) {
|
|
perMonitorWallpaper = enabled;
|
|
if (enabled && perModeWallpaper) {
|
|
syncWallpaperForCurrentMode();
|
|
}
|
|
saveSettings();
|
|
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme();
|
|
}
|
|
}
|
|
|
|
function setPerModeWallpaper(enabled) {
|
|
if (enabled && wallpaperCyclingEnabled) {
|
|
setWallpaperCyclingEnabled(false);
|
|
}
|
|
if (enabled && perMonitorWallpaper) {
|
|
var monitorCyclingAny = false;
|
|
for (var key in monitorCyclingSettings) {
|
|
if (monitorCyclingSettings[key].enabled) {
|
|
monitorCyclingAny = true;
|
|
break;
|
|
}
|
|
}
|
|
if (monitorCyclingAny) {
|
|
var newSettings = Object.assign({}, monitorCyclingSettings);
|
|
for (var screenName in newSettings) {
|
|
newSettings[screenName].enabled = false;
|
|
}
|
|
monitorCyclingSettings = newSettings;
|
|
}
|
|
}
|
|
|
|
perModeWallpaper = enabled;
|
|
if (enabled) {
|
|
if (perMonitorWallpaper) {
|
|
monitorWallpapersLight = Object.assign({}, monitorWallpapers);
|
|
monitorWallpapersDark = Object.assign({}, monitorWallpapers);
|
|
} else {
|
|
wallpaperPathLight = wallpaperPath;
|
|
wallpaperPathDark = wallpaperPath;
|
|
}
|
|
} else {
|
|
syncWallpaperForCurrentMode();
|
|
}
|
|
saveSettings();
|
|
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme();
|
|
}
|
|
}
|
|
|
|
function setMonitorWallpaper(screenName, path) {
|
|
var screen = null;
|
|
var screens = Quickshell.screens;
|
|
for (var i = 0; i < screens.length; i++) {
|
|
if (screens[i].name === screenName) {
|
|
screen = screens[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!screen) {
|
|
log.warn("Screen not found");
|
|
return;
|
|
}
|
|
|
|
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name;
|
|
|
|
var newMonitorWallpapers = {};
|
|
for (var key in monitorWallpapers) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen) {
|
|
newMonitorWallpapers[key] = monitorWallpapers[key];
|
|
}
|
|
}
|
|
|
|
if (path && path !== "") {
|
|
newMonitorWallpapers[identifier] = path;
|
|
}
|
|
|
|
monitorWallpapers = newMonitorWallpapers;
|
|
|
|
if (perModeWallpaper) {
|
|
if (isLightMode) {
|
|
var newLight = {};
|
|
for (var key in monitorWallpapersLight) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen) {
|
|
newLight[key] = monitorWallpapersLight[key];
|
|
}
|
|
}
|
|
if (path && path !== "") {
|
|
newLight[identifier] = path;
|
|
}
|
|
monitorWallpapersLight = newLight;
|
|
} else {
|
|
var newDark = {};
|
|
for (var key in monitorWallpapersDark) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen) {
|
|
newDark[key] = monitorWallpapersDark[key];
|
|
}
|
|
}
|
|
if (path && path !== "") {
|
|
newDark[identifier] = path;
|
|
}
|
|
monitorWallpapersDark = newDark;
|
|
}
|
|
}
|
|
|
|
saveSettings();
|
|
|
|
if (typeof Theme !== "undefined" && typeof Quickshell !== "undefined" && typeof SettingsData !== "undefined") {
|
|
var screens = Quickshell.screens;
|
|
if (screens.length > 0) {
|
|
var targetMonitor = (SettingsData.matugenTargetMonitor && SettingsData.matugenTargetMonitor !== "") ? SettingsData.matugenTargetMonitor : screens[0].name;
|
|
if (screenName === targetMonitor) {
|
|
Theme.generateSystemThemesFromCurrentTheme();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function setWallpaperTransition(transition) {
|
|
wallpaperTransition = transition;
|
|
saveSettings();
|
|
}
|
|
|
|
function setWallpaperCyclingEnabled(enabled) {
|
|
wallpaperCyclingEnabled = enabled;
|
|
saveSettings();
|
|
}
|
|
|
|
function setWallpaperCyclingRandom(random) {
|
|
wallpaperCyclingRandom = random;
|
|
saveSettings();
|
|
}
|
|
|
|
function setWallpaperCyclingMode(mode) {
|
|
wallpaperCyclingMode = mode;
|
|
saveSettings();
|
|
}
|
|
|
|
function setWallpaperCyclingInterval(interval) {
|
|
wallpaperCyclingInterval = interval;
|
|
saveSettings();
|
|
}
|
|
|
|
function setWallpaperCyclingTime(time) {
|
|
wallpaperCyclingTime = time;
|
|
saveSettings();
|
|
}
|
|
|
|
function setMonitorCyclingEnabled(screenName, enabled) {
|
|
var screen = null;
|
|
var screens = Quickshell.screens;
|
|
for (var i = 0; i < screens.length; i++) {
|
|
if (screens[i].name === screenName) {
|
|
screen = screens[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!screen) {
|
|
log.warn("Screen not found");
|
|
return;
|
|
}
|
|
|
|
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name;
|
|
|
|
var newSettings = {};
|
|
for (var key in monitorCyclingSettings) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen) {
|
|
newSettings[key] = monitorCyclingSettings[key];
|
|
}
|
|
}
|
|
|
|
newSettings[identifier] = getMonitorCyclingSettings(screenName);
|
|
newSettings[identifier].enabled = enabled;
|
|
monitorCyclingSettings = newSettings;
|
|
saveSettings();
|
|
}
|
|
|
|
function setMonitorCyclingRandom(screenName, random) {
|
|
var screen = null;
|
|
var screens = Quickshell.screens;
|
|
for (var i = 0; i < screens.length; i++) {
|
|
if (screens[i].name === screenName) {
|
|
screen = screens[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!screen) {
|
|
log.warn("Screen not found");
|
|
return;
|
|
}
|
|
|
|
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name;
|
|
|
|
var newSettings = {};
|
|
for (var key in monitorCyclingSettings) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen) {
|
|
newSettings[key] = monitorCyclingSettings[key];
|
|
}
|
|
}
|
|
|
|
newSettings[identifier] = getMonitorCyclingSettings(screenName);
|
|
newSettings[identifier].random = random;
|
|
monitorCyclingSettings = newSettings;
|
|
saveSettings();
|
|
}
|
|
|
|
function setMonitorCyclingMode(screenName, mode) {
|
|
var screen = null;
|
|
var screens = Quickshell.screens;
|
|
for (var i = 0; i < screens.length; i++) {
|
|
if (screens[i].name === screenName) {
|
|
screen = screens[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!screen) {
|
|
log.warn("Screen not found");
|
|
return;
|
|
}
|
|
|
|
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name;
|
|
|
|
var newSettings = {};
|
|
for (var key in monitorCyclingSettings) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen) {
|
|
newSettings[key] = monitorCyclingSettings[key];
|
|
}
|
|
}
|
|
|
|
newSettings[identifier] = getMonitorCyclingSettings(screenName);
|
|
newSettings[identifier].mode = mode;
|
|
monitorCyclingSettings = newSettings;
|
|
saveSettings();
|
|
}
|
|
|
|
function setMonitorCyclingInterval(screenName, interval) {
|
|
var screen = null;
|
|
var screens = Quickshell.screens;
|
|
for (var i = 0; i < screens.length; i++) {
|
|
if (screens[i].name === screenName) {
|
|
screen = screens[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!screen) {
|
|
log.warn("Screen not found");
|
|
return;
|
|
}
|
|
|
|
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name;
|
|
|
|
var newSettings = {};
|
|
for (var key in monitorCyclingSettings) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen) {
|
|
newSettings[key] = monitorCyclingSettings[key];
|
|
}
|
|
}
|
|
|
|
newSettings[identifier] = getMonitorCyclingSettings(screenName);
|
|
newSettings[identifier].interval = interval;
|
|
monitorCyclingSettings = newSettings;
|
|
saveSettings();
|
|
}
|
|
|
|
function setMonitorCyclingTime(screenName, time) {
|
|
var screen = null;
|
|
var screens = Quickshell.screens;
|
|
for (var i = 0; i < screens.length; i++) {
|
|
if (screens[i].name === screenName) {
|
|
screen = screens[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!screen) {
|
|
log.warn("Screen not found");
|
|
return;
|
|
}
|
|
|
|
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name;
|
|
|
|
var newSettings = {};
|
|
for (var key in monitorCyclingSettings) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen) {
|
|
newSettings[key] = monitorCyclingSettings[key];
|
|
}
|
|
}
|
|
|
|
newSettings[identifier] = getMonitorCyclingSettings(screenName);
|
|
newSettings[identifier].time = time;
|
|
monitorCyclingSettings = newSettings;
|
|
saveSettings();
|
|
}
|
|
|
|
function setMonitorCyclingFolderPath(screenName, folderPath) {
|
|
var screen = null;
|
|
var screens = Quickshell.screens;
|
|
for (var i = 0; i < screens.length; i++) {
|
|
if (screens[i].name === screenName) {
|
|
screen = screens[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!screen) {
|
|
log.warn("Screen not found");
|
|
return;
|
|
}
|
|
|
|
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name;
|
|
|
|
var newSettings = {};
|
|
for (var key in monitorCyclingSettings) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen) {
|
|
newSettings[key] = monitorCyclingSettings[key];
|
|
}
|
|
}
|
|
|
|
newSettings[identifier] = getMonitorCyclingSettings(screenName);
|
|
newSettings[identifier].folderPath = folderPath;
|
|
monitorCyclingSettings = newSettings;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeEnabled(enabled) {
|
|
nightModeEnabled = enabled;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeTemperature(temperature) {
|
|
nightModeTemperature = temperature;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeHighTemperature(temperature) {
|
|
nightModeHighTemperature = temperature;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeAutoEnabled(enabled) {
|
|
nightModeAutoEnabled = enabled;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeAutoMode(mode) {
|
|
nightModeAutoMode = mode;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeStartHour(hour) {
|
|
nightModeStartHour = hour;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeStartMinute(minute) {
|
|
nightModeStartMinute = minute;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeEndHour(hour) {
|
|
nightModeEndHour = hour;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeEndMinute(minute) {
|
|
nightModeEndMinute = minute;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeTransitionMinutes(minutes) {
|
|
nightModeTransitionMinutes = minutes;
|
|
saveSettings();
|
|
}
|
|
|
|
function setDisplayGamma(gamma) {
|
|
displayGamma = gamma;
|
|
saveSettings();
|
|
}
|
|
|
|
function setDisplayContrast(contrast) {
|
|
displayContrast = contrast;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeUseIPLocation(use) {
|
|
nightModeUseIPLocation = use;
|
|
saveSettings();
|
|
}
|
|
|
|
function setLatitude(lat) {
|
|
latitude = lat;
|
|
saveSettings();
|
|
}
|
|
|
|
function setLongitude(lng) {
|
|
longitude = lng;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNightModeLocationName(name) {
|
|
nightModeLocationName = name;
|
|
saveSettings();
|
|
}
|
|
|
|
function setThemeModeAutoEnabled(enabled) {
|
|
themeModeAutoEnabled = enabled;
|
|
saveSettings();
|
|
}
|
|
|
|
function setThemeModeAutoMode(mode) {
|
|
themeModeAutoMode = mode;
|
|
saveSettings();
|
|
}
|
|
|
|
function setThemeModeStartHour(hour) {
|
|
themeModeStartHour = hour;
|
|
saveSettings();
|
|
}
|
|
|
|
function setThemeModeStartMinute(minute) {
|
|
themeModeStartMinute = minute;
|
|
saveSettings();
|
|
}
|
|
|
|
function setThemeModeEndHour(hour) {
|
|
themeModeEndHour = hour;
|
|
saveSettings();
|
|
}
|
|
|
|
function setThemeModeEndMinute(minute) {
|
|
themeModeEndMinute = minute;
|
|
saveSettings();
|
|
}
|
|
|
|
function setThemeModeShareGammaSettings(share) {
|
|
themeModeShareGammaSettings = share;
|
|
saveSettings();
|
|
}
|
|
|
|
function setPinnedApps(apps) {
|
|
pinnedApps = apps;
|
|
saveSettings();
|
|
}
|
|
|
|
function setDockLauncherPosition(position) {
|
|
dockLauncherPosition = position;
|
|
saveSettings();
|
|
}
|
|
|
|
function addPinnedApp(appId) {
|
|
if (!appId)
|
|
return;
|
|
var currentPinned = [...pinnedApps];
|
|
if (currentPinned.indexOf(appId) === -1) {
|
|
currentPinned.push(appId);
|
|
setPinnedApps(currentPinned);
|
|
}
|
|
}
|
|
|
|
function removePinnedApp(appId) {
|
|
if (!appId)
|
|
return;
|
|
var currentPinned = pinnedApps.filter(id => id !== appId);
|
|
setPinnedApps(currentPinned);
|
|
}
|
|
|
|
function isPinnedApp(appId) {
|
|
return appId && pinnedApps.indexOf(appId) !== -1;
|
|
}
|
|
|
|
function setBarPinnedApps(apps) {
|
|
barPinnedApps = apps;
|
|
saveSettings();
|
|
}
|
|
|
|
function addBarPinnedApp(appId) {
|
|
if (!appId)
|
|
return;
|
|
var currentPinned = [...barPinnedApps];
|
|
if (currentPinned.indexOf(appId) === -1) {
|
|
currentPinned.push(appId);
|
|
setBarPinnedApps(currentPinned);
|
|
}
|
|
}
|
|
|
|
function removeBarPinnedApp(appId) {
|
|
if (!appId)
|
|
return;
|
|
var currentPinned = barPinnedApps.filter(id => id !== appId);
|
|
setBarPinnedApps(currentPinned);
|
|
}
|
|
|
|
function hideTrayId(trayId) {
|
|
if (!trayId)
|
|
return;
|
|
const current = [...hiddenTrayIds];
|
|
if (current.indexOf(trayId) === -1) {
|
|
current.push(trayId);
|
|
hiddenTrayIds = current;
|
|
saveSettings();
|
|
}
|
|
}
|
|
|
|
function showTrayId(trayId) {
|
|
if (!trayId)
|
|
return;
|
|
hiddenTrayIds = hiddenTrayIds.filter(id => id !== trayId);
|
|
saveSettings();
|
|
}
|
|
|
|
function isHiddenTrayId(trayId) {
|
|
return trayId && hiddenTrayIds.indexOf(trayId) !== -1;
|
|
}
|
|
|
|
function setTrayItemOrder(order) {
|
|
trayItemOrder = order;
|
|
saveSettings();
|
|
}
|
|
|
|
function addRecentColor(color) {
|
|
const colorStr = color.toString();
|
|
let recent = recentColors.slice();
|
|
recent = recent.filter(c => c !== colorStr);
|
|
recent.unshift(colorStr);
|
|
if (recent.length > 5)
|
|
recent = recent.slice(0, 5);
|
|
recentColors = recent;
|
|
saveSettings();
|
|
}
|
|
|
|
function setShowThirdPartyPlugins(enabled) {
|
|
showThirdPartyPlugins = enabled;
|
|
saveSettings();
|
|
}
|
|
|
|
function setPluginBrowserInstalledFirst(enabled) {
|
|
pluginBrowserInstalledFirst = enabled;
|
|
saveSettings();
|
|
}
|
|
|
|
function setPluginBrowserHideInstalled(enabled) {
|
|
pluginBrowserHideInstalled = enabled;
|
|
saveSettings();
|
|
}
|
|
|
|
function setPluginBrowserSortMode(mode) {
|
|
if (mode === "type" || mode === "contributor")
|
|
mode = "author";
|
|
if (mode !== "default" && mode !== "name" && mode !== "author" && mode !== "category")
|
|
mode = "default";
|
|
pluginBrowserSortMode = mode;
|
|
saveSettings();
|
|
}
|
|
|
|
function setLastBrightnessDevice(device) {
|
|
lastBrightnessDevice = device;
|
|
saveSettings();
|
|
}
|
|
|
|
function setBrightnessExponential(deviceName, enabled) {
|
|
var newSettings = Object.assign({}, brightnessExponentialDevices);
|
|
if (enabled) {
|
|
newSettings[deviceName] = true;
|
|
} else {
|
|
delete newSettings[deviceName];
|
|
}
|
|
brightnessExponentialDevices = newSettings;
|
|
saveSettings();
|
|
brightnessDisplayHintChanged(deviceName);
|
|
}
|
|
|
|
function getBrightnessExponential(deviceName) {
|
|
return brightnessExponentialDevices[deviceName] === true;
|
|
}
|
|
|
|
function setBrightnessUserSetValue(deviceName, value) {
|
|
var newValues = Object.assign({}, brightnessUserSetValues);
|
|
newValues[deviceName] = value;
|
|
brightnessUserSetValues = newValues;
|
|
saveSettings();
|
|
}
|
|
|
|
function clearBrightnessUserSetValue(deviceName) {
|
|
var newValues = Object.assign({}, brightnessUserSetValues);
|
|
delete newValues[deviceName];
|
|
brightnessUserSetValues = newValues;
|
|
saveSettings();
|
|
}
|
|
|
|
function setBrightnessExponent(deviceName, exponent) {
|
|
var newValues = Object.assign({}, brightnessExponentValues);
|
|
if (exponent !== undefined && exponent !== null) {
|
|
newValues[deviceName] = exponent;
|
|
} else {
|
|
delete newValues[deviceName];
|
|
}
|
|
brightnessExponentValues = newValues;
|
|
saveSettings();
|
|
}
|
|
|
|
function getBrightnessExponent(deviceName) {
|
|
const value = brightnessExponentValues[deviceName];
|
|
return value !== undefined ? value : 1.2;
|
|
}
|
|
|
|
function setEnabledGpuPciIds(pciIds) {
|
|
enabledGpuPciIds = pciIds;
|
|
saveSettings();
|
|
}
|
|
|
|
function setWifiDeviceOverride(device) {
|
|
wifiDeviceOverride = device || "";
|
|
saveSettings();
|
|
}
|
|
|
|
function setWeatherHourlyDetailed(detailed) {
|
|
weatherHourlyDetailed = detailed;
|
|
saveSettings();
|
|
}
|
|
|
|
function setWeatherLocation(displayName, coordinates) {
|
|
weatherLocation = displayName;
|
|
weatherCoordinates = coordinates;
|
|
saveSettings();
|
|
}
|
|
|
|
function hideApp(appId) {
|
|
if (!appId)
|
|
return;
|
|
const current = [...hiddenApps];
|
|
if (current.indexOf(appId) === -1) {
|
|
current.push(appId);
|
|
hiddenApps = current;
|
|
saveSettings();
|
|
}
|
|
}
|
|
|
|
function showApp(appId) {
|
|
if (!appId)
|
|
return;
|
|
hiddenApps = hiddenApps.filter(id => id !== appId);
|
|
saveSettings();
|
|
}
|
|
|
|
function isAppHidden(appId) {
|
|
return appId && hiddenApps.indexOf(appId) !== -1;
|
|
}
|
|
|
|
function setAppOverride(appId, overrides) {
|
|
if (!appId)
|
|
return;
|
|
const newOverrides = Object.assign({}, appOverrides);
|
|
if (!overrides || Object.keys(overrides).length === 0) {
|
|
delete newOverrides[appId];
|
|
} else {
|
|
newOverrides[appId] = overrides;
|
|
}
|
|
appOverrides = newOverrides;
|
|
saveSettings();
|
|
}
|
|
|
|
function getAppOverride(appId) {
|
|
if (!appId)
|
|
return null;
|
|
return appOverrides[appId] || null;
|
|
}
|
|
|
|
function clearAppOverride(appId) {
|
|
if (!appId)
|
|
return;
|
|
const newOverrides = Object.assign({}, appOverrides);
|
|
delete newOverrides[appId];
|
|
appOverrides = newOverrides;
|
|
saveSettings();
|
|
}
|
|
|
|
function setSearchAppActions(enabled) {
|
|
searchAppActions = enabled;
|
|
saveSettings();
|
|
}
|
|
|
|
function setVpnLastConnected(uuid) {
|
|
vpnLastConnected = uuid || "";
|
|
saveSettings();
|
|
}
|
|
|
|
function setDeviceMaxVolume(nodeName, maxPercent) {
|
|
if (!nodeName)
|
|
return;
|
|
const updated = Object.assign({}, deviceMaxVolumes);
|
|
const clamped = Math.max(100, Math.min(200, Math.round(maxPercent)));
|
|
if (clamped === 100) {
|
|
delete updated[nodeName];
|
|
} else {
|
|
updated[nodeName] = clamped;
|
|
}
|
|
deviceMaxVolumes = updated;
|
|
saveSettings();
|
|
}
|
|
|
|
function setHiddenOutputDeviceNames(deviceNames) {
|
|
if (!Array.isArray(deviceNames))
|
|
return;
|
|
hiddenOutputDeviceNames = deviceNames;
|
|
saveSettings();
|
|
}
|
|
|
|
function setHiddenInputDeviceNames(deviceNames) {
|
|
if (!Array.isArray(deviceNames))
|
|
return;
|
|
hiddenInputDeviceNames = deviceNames;
|
|
saveSettings();
|
|
}
|
|
|
|
function getDeviceMaxVolume(nodeName) {
|
|
if (!nodeName)
|
|
return 100;
|
|
return deviceMaxVolumes[nodeName] ?? 100;
|
|
}
|
|
|
|
function updateLocale() {
|
|
if (!locale) {
|
|
I18n._pickTranslation();
|
|
return;
|
|
}
|
|
I18n.useLocale(locale, locale.startsWith("en") ? "" : I18n.folder + "/" + locale + ".json");
|
|
}
|
|
|
|
function setNotepadLastMode(mode) {
|
|
if (notepadLastMode === mode)
|
|
return;
|
|
notepadLastMode = mode;
|
|
saveSettings();
|
|
}
|
|
|
|
function setLauncherLastMode(mode) {
|
|
launcherLastMode = mode;
|
|
saveSettings();
|
|
}
|
|
|
|
function getLauncherRestoreMode() {
|
|
if (!SettingsData.rememberLastMode)
|
|
return "all";
|
|
return launcherLastMode || "all";
|
|
}
|
|
|
|
function setLauncherLastFileSearchType(type) {
|
|
launcherLastFileSearchType = type;
|
|
saveSettings();
|
|
}
|
|
|
|
function setLauncherLastQuery(query) {
|
|
launcherLastQuery = query;
|
|
saveSettings();
|
|
}
|
|
|
|
function addLauncherHistory(query, skipLastQuery) {
|
|
let q = query.trim();
|
|
|
|
if (!skipLastQuery)
|
|
setLauncherLastQuery(q);
|
|
|
|
if (!q)
|
|
return;
|
|
|
|
if (launcherQueryHistory.length > 0 && launcherQueryHistory[0] === q) {
|
|
return;
|
|
}
|
|
|
|
let history = [...launcherQueryHistory];
|
|
|
|
let idx = history.indexOf(q);
|
|
if (idx !== -1)
|
|
history.splice(idx, 1);
|
|
|
|
history.unshift(q);
|
|
if (history.length > 50)
|
|
history = history.slice(0, 50);
|
|
|
|
launcherQueryHistory = history;
|
|
saveSettings();
|
|
}
|
|
|
|
function setAppDrawerLastMode(mode) {
|
|
appDrawerLastMode = mode;
|
|
saveSettings();
|
|
}
|
|
|
|
function setNiriOverviewLastMode(mode) {
|
|
niriOverviewLastMode = mode;
|
|
saveSettings();
|
|
}
|
|
|
|
function setSettingsSidebarState(expandedIds, collapsedIds) {
|
|
settingsSidebarExpandedIds = expandedIds;
|
|
settingsSidebarCollapsedIds = collapsedIds;
|
|
saveSettings();
|
|
}
|
|
|
|
function syncWallpaperForCurrentMode(mode) {
|
|
if (!perModeWallpaper)
|
|
return;
|
|
var light = (mode !== undefined) ? mode : isLightMode;
|
|
if (perMonitorWallpaper) {
|
|
monitorWallpapers = light ? Object.assign({}, monitorWallpapersLight) : Object.assign({}, monitorWallpapersDark);
|
|
return;
|
|
}
|
|
|
|
wallpaperPath = light ? wallpaperPathLight : wallpaperPathDark;
|
|
}
|
|
|
|
function _findMonitorValue(map, screenName) {
|
|
var screen = null;
|
|
var screens = Quickshell.screens;
|
|
for (var i = 0; i < screens.length; i++) {
|
|
if (screens[i].name === screenName) {
|
|
screen = screens[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!screen)
|
|
return map[screenName];
|
|
|
|
if (map[screen.name] !== undefined)
|
|
return map[screen.name];
|
|
if (screen.model && map[screen.model] !== undefined)
|
|
return map[screen.model];
|
|
if (typeof SettingsData !== "undefined") {
|
|
var displayName = SettingsData.getScreenDisplayName(screen);
|
|
if (displayName && map[displayName] !== undefined)
|
|
return map[displayName];
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
function getMonitorWallpaper(screenName) {
|
|
if (!perMonitorWallpaper)
|
|
return wallpaperPath;
|
|
var value = _findMonitorValue(monitorWallpapers, screenName);
|
|
return value !== undefined ? value : wallpaperPath;
|
|
}
|
|
|
|
function getMonitorWallpaperFillMode(screenName) {
|
|
var globalFillMode = (typeof SettingsData !== "undefined") ? SettingsData.wallpaperFillMode : "Fill";
|
|
if (!perMonitorWallpaper)
|
|
return globalFillMode;
|
|
var value = _findMonitorValue(monitorWallpaperFillModes, screenName);
|
|
return value !== undefined ? value : globalFillMode;
|
|
}
|
|
|
|
function setMonitorWallpaperFillMode(screenName, mode) {
|
|
var screen = null;
|
|
var screens = Quickshell.screens;
|
|
for (var i = 0; i < screens.length; i++) {
|
|
if (screens[i].name === screenName) {
|
|
screen = screens[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!screen)
|
|
return;
|
|
|
|
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name;
|
|
|
|
var newModes = {};
|
|
for (var key in monitorWallpaperFillModes) {
|
|
var isThisScreen = key === screen.name || (screen.model && key === screen.model);
|
|
if (!isThisScreen)
|
|
newModes[key] = monitorWallpaperFillModes[key];
|
|
}
|
|
|
|
newModes[identifier] = mode;
|
|
monitorWallpaperFillModes = newModes;
|
|
saveSettings();
|
|
}
|
|
|
|
function getMonitorCyclingSettings(screenName) {
|
|
var defaults = {
|
|
"enabled": false,
|
|
"random": false,
|
|
"mode": "interval",
|
|
"interval": 300,
|
|
"time": "06:00",
|
|
"folderPath": ""
|
|
};
|
|
var value = _findMonitorValue(monitorCyclingSettings, screenName);
|
|
return Object.assign({}, defaults, value !== undefined ? value : {});
|
|
}
|
|
|
|
FileView {
|
|
id: settingsFile
|
|
|
|
path: isGreeterMode ? "" : StandardPaths.writableLocation(StandardPaths.GenericStateLocation) + "/DankMaterialShell/session.json"
|
|
blockLoading: true
|
|
blockWrites: true
|
|
atomicWrites: true
|
|
watchChanges: !isGreeterMode
|
|
onLoaded: {
|
|
if (isGreeterMode)
|
|
return;
|
|
_hasUnsavedChanges = false;
|
|
parseSettings(settingsFile.text());
|
|
}
|
|
onSaveFailed: error => {
|
|
root._isReadOnly = true;
|
|
root._hasUnsavedChanges = root._checkForUnsavedChanges();
|
|
}
|
|
}
|
|
|
|
readonly property string _greeterCacheDir: Quickshell.env("DMS_GREET_CFG_DIR") || "/var/cache/dms-greeter"
|
|
|
|
property string greeterSessionBaseDir: root._greeterCacheDir
|
|
|
|
function setGreeterSessionBaseDir(dir) {
|
|
const next = dir || root._greeterCacheDir;
|
|
if (greeterSessionBaseDir === next)
|
|
return;
|
|
greeterSessionBaseDir = next;
|
|
if (isGreeterMode)
|
|
greeterSessionFile.reload();
|
|
}
|
|
|
|
function resetGreeterSessionBaseDir() {
|
|
setGreeterSessionBaseDir(root._greeterCacheDir);
|
|
}
|
|
|
|
FileView {
|
|
id: greeterSessionFile
|
|
|
|
path: root.greeterSessionBaseDir ? (root.greeterSessionBaseDir + "/session.json") : ""
|
|
preload: isGreeterMode
|
|
blockLoading: false
|
|
blockWrites: true
|
|
watchChanges: false
|
|
printErrors: true
|
|
onLoaded: {
|
|
if (isGreeterMode) {
|
|
parseSettings(greeterSessionFile.text());
|
|
}
|
|
}
|
|
}
|
|
|
|
Process {
|
|
id: sessionWritableCheckProcess
|
|
|
|
property string sessionPath: Paths.strip(settingsFile.path)
|
|
|
|
command: ["sh", "-c", "[ ! -f \"" + sessionPath + "\" ] || [ -w \"" + sessionPath + "\" ] && echo 'writable' || echo 'readonly'"]
|
|
running: false
|
|
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
const result = text.trim();
|
|
root._onWritableCheckComplete(result === "writable");
|
|
}
|
|
}
|
|
}
|
|
}
|