mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
1300 lines
46 KiB
QML
1300 lines
46 KiB
QML
pragma Singleton
|
|
|
|
pragma ComponentBehavior: Bound
|
|
|
|
import QtCore
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Common
|
|
import qs.Common.settings
|
|
import qs.Services
|
|
import "settings/SettingsSpec.js" as Spec
|
|
import "settings/SettingsStore.js" as Store
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
readonly property int settingsConfigVersion: 2
|
|
|
|
readonly property bool isGreeterMode: Quickshell.env("DMS_RUN_GREETER") === "1" || Quickshell.env("DMS_RUN_GREETER") === "true"
|
|
|
|
enum Position {
|
|
Top,
|
|
Bottom,
|
|
Left,
|
|
Right,
|
|
TopCenter,
|
|
BottomCenter,
|
|
LeftCenter,
|
|
RightCenter
|
|
}
|
|
|
|
enum AnimationSpeed {
|
|
None,
|
|
Short,
|
|
Medium,
|
|
Long,
|
|
Custom
|
|
}
|
|
|
|
enum SuspendBehavior {
|
|
Suspend,
|
|
Hibernate,
|
|
SuspendThenHibernate
|
|
}
|
|
|
|
enum WidgetColorMode {
|
|
Default,
|
|
Colorful
|
|
}
|
|
|
|
readonly property string defaultFontFamily: "Inter Variable"
|
|
readonly property string defaultMonoFontFamily: "Fira Code"
|
|
readonly property string _homeUrl: StandardPaths.writableLocation(StandardPaths.HomeLocation)
|
|
readonly property string _configUrl: StandardPaths.writableLocation(StandardPaths.ConfigLocation)
|
|
readonly property string _configDir: Paths.strip(_configUrl)
|
|
readonly property string pluginSettingsPath: _configDir + "/DankMaterialShell/plugin_settings.json"
|
|
|
|
property bool _loading: false
|
|
property bool _pluginSettingsLoading: false
|
|
property bool hasTriedDefaultSettings: false
|
|
property var pluginSettings: ({})
|
|
|
|
property alias dankBarLeftWidgetsModel: leftWidgetsModel
|
|
property alias dankBarCenterWidgetsModel: centerWidgetsModel
|
|
property alias dankBarRightWidgetsModel: rightWidgetsModel
|
|
|
|
property string currentThemeName: "blue"
|
|
property string customThemeFile: ""
|
|
property string matugenScheme: "scheme-tonal-spot"
|
|
property bool runUserMatugenTemplates: true
|
|
property string matugenTargetMonitor: ""
|
|
property real popupTransparency: 1.0
|
|
property real dockTransparency: 1
|
|
property string widgetBackgroundColor: "sch"
|
|
property string widgetColorMode: "default"
|
|
property real cornerRadius: 12
|
|
|
|
property bool use24HourClock: true
|
|
property bool showSeconds: false
|
|
property bool useFahrenheit: false
|
|
property bool nightModeEnabled: false
|
|
property int animationSpeed: SettingsData.AnimationSpeed.Short
|
|
property int customAnimationDuration: 500
|
|
property string wallpaperFillMode: "Fill"
|
|
property bool blurredWallpaperLayer: false
|
|
property bool blurWallpaperOnOverview: false
|
|
|
|
property bool showLauncherButton: true
|
|
property bool showWorkspaceSwitcher: true
|
|
property bool showFocusedWindow: true
|
|
property bool showWeather: true
|
|
property bool showMusic: true
|
|
property bool showClipboard: true
|
|
property bool showCpuUsage: true
|
|
property bool showMemUsage: true
|
|
property bool showCpuTemp: true
|
|
property bool showGpuTemp: true
|
|
property int selectedGpuIndex: 0
|
|
property var enabledGpuPciIds: []
|
|
property bool showSystemTray: true
|
|
property bool showClock: true
|
|
property bool showNotificationButton: true
|
|
property bool showBattery: true
|
|
property bool showControlCenterButton: true
|
|
property bool showCapsLockIndicator: true
|
|
|
|
property bool controlCenterShowNetworkIcon: true
|
|
property bool controlCenterShowBluetoothIcon: true
|
|
property bool controlCenterShowAudioIcon: true
|
|
property bool showPrivacyButton: true
|
|
property bool privacyShowMicIcon: false
|
|
property bool privacyShowCameraIcon: false
|
|
property bool privacyShowScreenShareIcon: false
|
|
|
|
property var controlCenterWidgets: [{
|
|
"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
|
|
}]
|
|
|
|
property bool showWorkspaceIndex: false
|
|
property bool showWorkspacePadding: false
|
|
property bool workspaceScrolling: false
|
|
property bool showWorkspaceApps: false
|
|
property int maxWorkspaceIcons: 3
|
|
property bool workspacesPerMonitor: true
|
|
property bool dwlShowAllTags: false
|
|
property var workspaceNameIcons: ({})
|
|
property bool waveProgressEnabled: true
|
|
property bool clockCompactMode: false
|
|
property bool focusedWindowCompactMode: false
|
|
property bool runningAppsCompactMode: true
|
|
property bool keyboardLayoutNameCompactMode: false
|
|
property bool runningAppsCurrentWorkspace: false
|
|
property bool runningAppsGroupByApp: false
|
|
property string clockDateFormat: ""
|
|
property string lockDateFormat: ""
|
|
property int mediaSize: 1
|
|
|
|
|
|
property string appLauncherViewMode: "list"
|
|
property string spotlightModalViewMode: "list"
|
|
property bool sortAppsAlphabetically: false
|
|
property int appLauncherGridColumns: 4
|
|
property bool spotlightCloseNiriOverview: true
|
|
|
|
property string weatherLocation: "New York, NY"
|
|
property string weatherCoordinates: "40.7128,-74.0060"
|
|
property bool useAutoLocation: false
|
|
property bool weatherEnabled: true
|
|
|
|
property string networkPreference: "auto"
|
|
property string vpnLastConnected: ""
|
|
|
|
property string iconTheme: "System Default"
|
|
property var availableIconThemes: ["System Default"]
|
|
property string systemDefaultIconTheme: ""
|
|
property bool qt5ctAvailable: false
|
|
property bool qt6ctAvailable: false
|
|
property bool gtkAvailable: false
|
|
|
|
property string launcherLogoMode: "apps"
|
|
property string launcherLogoCustomPath: ""
|
|
property string launcherLogoColorOverride: ""
|
|
property bool launcherLogoColorInvertOnMode: false
|
|
property real launcherLogoBrightness: 0.5
|
|
property real launcherLogoContrast: 1
|
|
property int launcherLogoSizeOffset: 0
|
|
|
|
property string fontFamily: "Inter Variable"
|
|
property string monoFontFamily: "Fira Code"
|
|
property int fontWeight: Font.Normal
|
|
property real fontScale: 1.0
|
|
property real dankBarFontScale: 1.0
|
|
|
|
property bool notepadUseMonospace: true
|
|
property string notepadFontFamily: ""
|
|
property real notepadFontSize: 14
|
|
property bool notepadShowLineNumbers: false
|
|
property real notepadTransparencyOverride: -1
|
|
property real notepadLastCustomTransparency: 0.7
|
|
|
|
onNotepadUseMonospaceChanged: saveSettings()
|
|
onNotepadFontFamilyChanged: saveSettings()
|
|
onNotepadFontSizeChanged: saveSettings()
|
|
onNotepadShowLineNumbersChanged: saveSettings()
|
|
onNotepadTransparencyOverrideChanged: {
|
|
if (notepadTransparencyOverride > 0) {
|
|
notepadLastCustomTransparency = notepadTransparencyOverride
|
|
}
|
|
saveSettings()
|
|
}
|
|
onNotepadLastCustomTransparencyChanged: saveSettings()
|
|
|
|
property bool soundsEnabled: true
|
|
property bool useSystemSoundTheme: false
|
|
property bool soundNewNotification: true
|
|
property bool soundVolumeChanged: true
|
|
property bool soundPluggedIn: true
|
|
|
|
property int acMonitorTimeout: 0
|
|
property int acLockTimeout: 0
|
|
property int acSuspendTimeout: 0
|
|
property int acSuspendBehavior: SettingsData.SuspendBehavior.Suspend
|
|
property int batteryMonitorTimeout: 0
|
|
property int batteryLockTimeout: 0
|
|
property int batterySuspendTimeout: 0
|
|
property int batterySuspendBehavior: SettingsData.SuspendBehavior.Suspend
|
|
property bool lockBeforeSuspend: false
|
|
property bool preventIdleForMedia: false
|
|
property bool loginctlLockIntegration: true
|
|
property string launchPrefix: ""
|
|
property var brightnessDevicePins: ({})
|
|
property var wifiNetworkPins: ({})
|
|
property var bluetoothDevicePins: ({})
|
|
property var audioInputDevicePins: ({})
|
|
property var audioOutputDevicePins: ({})
|
|
|
|
property bool gtkThemingEnabled: false
|
|
property bool qtThemingEnabled: false
|
|
property bool syncModeWithPortal: true
|
|
property bool terminalsAlwaysDark: false
|
|
|
|
property bool showDock: false
|
|
property bool dockAutoHide: false
|
|
property bool dockGroupByApp: false
|
|
property bool dockOpenOnOverview: false
|
|
property int dockPosition: SettingsData.Position.Bottom
|
|
property real dockSpacing: 4
|
|
property real dockBottomGap: 0
|
|
property real dockMargin: 0
|
|
property real dockIconSize: 40
|
|
property string dockIndicatorStyle: "circle"
|
|
|
|
property bool notificationOverlayEnabled: false
|
|
property int overviewRows: 2
|
|
property int overviewColumns: 5
|
|
property real overviewScale: 0.16
|
|
|
|
property bool modalDarkenBackground: true
|
|
|
|
property bool lockScreenShowPowerActions: true
|
|
property bool enableFprint: false
|
|
property int maxFprintTries: 3
|
|
property bool fprintdAvailable: false
|
|
property bool hideBrightnessSlider: false
|
|
|
|
property int notificationTimeoutLow: 5000
|
|
property int notificationTimeoutNormal: 5000
|
|
property int notificationTimeoutCritical: 0
|
|
property int notificationPopupPosition: SettingsData.Position.Top
|
|
|
|
property bool osdAlwaysShowValue: false
|
|
property int osdPosition: SettingsData.Position.BottomCenter
|
|
property bool osdVolumeEnabled: true
|
|
property bool osdMediaVolumeEnabled: true
|
|
property bool osdBrightnessEnabled: true
|
|
property bool osdIdleInhibitorEnabled: true
|
|
property bool osdMicMuteEnabled: true
|
|
property bool osdCapsLockEnabled: true
|
|
property bool osdPowerProfileEnabled: true
|
|
|
|
property bool powerActionConfirm: true
|
|
property var powerMenuActions: ["reboot", "logout", "poweroff", "lock", "suspend", "restart"]
|
|
property string powerMenuDefaultAction: "logout"
|
|
property bool powerMenuGridLayout: false
|
|
property string customPowerActionLock: ""
|
|
property string customPowerActionLogout: ""
|
|
property string customPowerActionSuspend: ""
|
|
property string customPowerActionHibernate: ""
|
|
property string customPowerActionReboot: ""
|
|
property string customPowerActionPowerOff: ""
|
|
|
|
property bool updaterUseCustomCommand: false
|
|
property string updaterCustomCommand: ""
|
|
property string updaterTerminalAdditionalParams: ""
|
|
|
|
property string displayNameMode: "system"
|
|
property var screenPreferences: ({})
|
|
property var showOnLastDisplay: ({})
|
|
|
|
property var barConfigs: [{
|
|
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,
|
|
gothCornersEnabled: false,
|
|
gothCornerRadiusOverride: false,
|
|
gothCornerRadiusValue: 12,
|
|
borderEnabled: false,
|
|
borderColor: "surfaceText",
|
|
borderOpacity: 1.0,
|
|
borderThickness: 1,
|
|
fontScale: 1.0,
|
|
autoHide: false,
|
|
autoHideDelay: 250,
|
|
openOnOverview: false,
|
|
visible: true,
|
|
popupGapsAuto: true,
|
|
popupGapsManual: 4
|
|
}]
|
|
|
|
signal forceDankBarLayoutRefresh
|
|
signal forceDockLayoutRefresh
|
|
signal widgetDataChanged
|
|
signal workspaceIconsUpdated
|
|
|
|
Component.onCompleted: {
|
|
if (!isGreeterMode) {
|
|
Processes.settingsRoot = root
|
|
loadSettings()
|
|
initializeListModels()
|
|
Processes.detectFprintd()
|
|
Processes.checkPluginSettings()
|
|
}
|
|
}
|
|
|
|
function applyStoredTheme() {
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.switchTheme(currentThemeName, false, false)
|
|
} else {
|
|
Qt.callLater(function() {
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.switchTheme(currentThemeName, false, false)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
function regenSystemThemes() {
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme()
|
|
}
|
|
}
|
|
|
|
function updateNiriLayout() {
|
|
if (typeof NiriService !== "undefined" && typeof CompositorService !== "undefined" && CompositorService.isNiri) {
|
|
NiriService.generateNiriLayoutConfig()
|
|
}
|
|
}
|
|
|
|
function applyStoredIconTheme() {
|
|
updateGtkIconTheme()
|
|
updateQtIconTheme()
|
|
}
|
|
|
|
function updateGtkIconTheme() {
|
|
const gtkThemeName = (iconTheme === "System Default") ? systemDefaultIconTheme : iconTheme
|
|
if (gtkThemeName === "System Default" || gtkThemeName === "") return
|
|
|
|
if (typeof DMSService !== "undefined" && DMSService.apiVersion >= 3 && typeof PortalService !== "undefined") {
|
|
PortalService.setSystemIconTheme(gtkThemeName)
|
|
}
|
|
|
|
const configScript = `mkdir -p ${_configDir}/gtk-3.0 ${_configDir}/gtk-4.0
|
|
|
|
for config_dir in ${_configDir}/gtk-3.0 ${_configDir}/gtk-4.0; do
|
|
settings_file="$config_dir/settings.ini"
|
|
if [ -f "$settings_file" ]; then
|
|
if grep -q "^gtk-icon-theme-name=" "$settings_file"; then
|
|
sed -i 's/^gtk-icon-theme-name=.*/gtk-icon-theme-name=${gtkThemeName}/' "$settings_file"
|
|
else
|
|
if grep -q "\\[Settings\\]" "$settings_file"; then
|
|
sed -i '/\\[Settings\\]/a gtk-icon-theme-name=${gtkThemeName}' "$settings_file"
|
|
else
|
|
echo -e '\\n[Settings]\\ngtk-icon-theme-name=${gtkThemeName}' >> "$settings_file"
|
|
fi
|
|
fi
|
|
else
|
|
echo -e '[Settings]\\ngtk-icon-theme-name=${gtkThemeName}' > "$settings_file"
|
|
fi
|
|
done
|
|
|
|
rm -rf ~/.cache/icon-cache ~/.cache/thumbnails 2>/dev/null || true
|
|
pkill -HUP -f 'gtk' 2>/dev/null || true`
|
|
|
|
Quickshell.execDetached(["sh", "-lc", configScript])
|
|
}
|
|
|
|
function updateQtIconTheme() {
|
|
const qtThemeName = (iconTheme === "System Default") ? "" : iconTheme
|
|
if (!qtThemeName) return
|
|
|
|
const home = _homeUrl.replace("file://", "").replace(/'/g, "'\\''")
|
|
const qtThemeNameEscaped = qtThemeName.replace(/'/g, "'\\''")
|
|
|
|
const script = `mkdir -p ${_configDir}/qt5ct ${_configDir}/qt6ct ${_configDir}/environment.d 2>/dev/null || true
|
|
update_qt_icon_theme() {
|
|
local config_file="$1"
|
|
local theme_name="$2"
|
|
if [ -f "$config_file" ]; then
|
|
if grep -q "^\\[Appearance\\]" "$config_file"; then
|
|
if grep -q "^icon_theme=" "$config_file"; then
|
|
sed -i "s/^icon_theme=.*/icon_theme=$theme_name/" "$config_file"
|
|
else
|
|
sed -i "/^\\[Appearance\\]/a icon_theme=$theme_name" "$config_file"
|
|
fi
|
|
else
|
|
printf "\\n[Appearance]\\nicon_theme=%s\\n" "$theme_name" >> "$config_file"
|
|
fi
|
|
else
|
|
printf "[Appearance]\\nicon_theme=%s\\n" "$theme_name" > "$config_file"
|
|
fi
|
|
}
|
|
update_qt_icon_theme ${_configDir}/qt5ct/qt5ct.conf '${qtThemeNameEscaped}'
|
|
update_qt_icon_theme ${_configDir}/qt6ct/qt6ct.conf '${qtThemeNameEscaped}'
|
|
rm -rf '${home}'/.cache/icon-cache '${home}'/.cache/thumbnails 2>/dev/null || true`
|
|
|
|
Quickshell.execDetached(["sh", "-lc", script])
|
|
}
|
|
|
|
readonly property var _hooks: ({
|
|
applyStoredTheme: applyStoredTheme,
|
|
regenSystemThemes: regenSystemThemes,
|
|
updateNiriLayout: updateNiriLayout,
|
|
applyStoredIconTheme: applyStoredIconTheme,
|
|
updateBarConfigs: updateBarConfigs
|
|
})
|
|
|
|
function set(key, value) {
|
|
Spec.set(root, key, value, saveSettings, _hooks)
|
|
}
|
|
|
|
function loadSettings() {
|
|
_loading = true
|
|
try {
|
|
const txt = settingsFile.text()
|
|
let obj = (txt && txt.trim()) ? JSON.parse(txt) : null
|
|
|
|
const oldVersion = obj?.configVersion ?? 0
|
|
if (oldVersion < settingsConfigVersion) {
|
|
const migrated = Store.migrateToVersion(obj, settingsConfigVersion)
|
|
if (migrated) {
|
|
settingsFile.setText(JSON.stringify(migrated, null, 2))
|
|
obj = migrated
|
|
}
|
|
}
|
|
|
|
Store.parse(root, obj)
|
|
applyStoredTheme()
|
|
applyStoredIconTheme()
|
|
Processes.detectIcons()
|
|
Processes.detectQtTools()
|
|
} catch (e) {
|
|
console.warn("SettingsData: Failed to load settings:", e.message)
|
|
applyStoredTheme()
|
|
applyStoredIconTheme()
|
|
} finally {
|
|
_loading = false
|
|
}
|
|
loadPluginSettings()
|
|
}
|
|
|
|
function loadPluginSettings() {
|
|
_pluginSettingsLoading = true
|
|
parsePluginSettings(pluginSettingsFile.text())
|
|
_pluginSettingsLoading = false
|
|
}
|
|
|
|
function parsePluginSettings(content) {
|
|
_pluginSettingsLoading = true
|
|
try {
|
|
if (content && content.trim()) {
|
|
pluginSettings = JSON.parse(content)
|
|
} else {
|
|
pluginSettings = {}
|
|
}
|
|
} catch (e) {
|
|
console.warn("SettingsData: Failed to parse plugin settings:", e.message)
|
|
pluginSettings = {}
|
|
} finally {
|
|
_pluginSettingsLoading = false
|
|
}
|
|
}
|
|
|
|
function saveSettings() {
|
|
if (_loading) return
|
|
settingsFile.setText(JSON.stringify(Store.toJson(root), null, 2))
|
|
}
|
|
|
|
function savePluginSettings() {
|
|
if (_pluginSettingsLoading) return
|
|
pluginSettingsFile.setText(JSON.stringify(pluginSettings, null, 2))
|
|
}
|
|
|
|
function detectAvailableIconThemes() {
|
|
Processes.detectIcons()
|
|
}
|
|
|
|
function getEffectiveTimeFormat() {
|
|
if (use24HourClock) {
|
|
return showSeconds ? "hh:mm:ss" : "hh:mm"
|
|
} else {
|
|
return showSeconds ? "h:mm:ss AP" : "h:mm AP"
|
|
}
|
|
}
|
|
|
|
function getEffectiveClockDateFormat() {
|
|
return clockDateFormat && clockDateFormat.length > 0 ? clockDateFormat : "ddd d"
|
|
}
|
|
|
|
function getEffectiveLockDateFormat() {
|
|
return lockDateFormat && lockDateFormat.length > 0 ? lockDateFormat : Locale.LongFormat
|
|
}
|
|
|
|
function initializeListModels() {
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
if (defaultBar) {
|
|
Lists.init(leftWidgetsModel, centerWidgetsModel, rightWidgetsModel, defaultBar.leftWidgets, defaultBar.centerWidgets, defaultBar.rightWidgets)
|
|
}
|
|
}
|
|
|
|
function updateListModel(listModel, order) {
|
|
Lists.update(listModel, order)
|
|
widgetDataChanged()
|
|
}
|
|
|
|
function hasNamedWorkspaces() {
|
|
if (typeof NiriService === "undefined" || !CompositorService.isNiri) return false
|
|
|
|
for (var i = 0; i < NiriService.allWorkspaces.length; i++) {
|
|
var ws = NiriService.allWorkspaces[i]
|
|
if (ws.name && ws.name.trim() !== "") return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
function getNamedWorkspaces() {
|
|
var namedWorkspaces = []
|
|
if (typeof NiriService === "undefined" || !CompositorService.isNiri) return namedWorkspaces
|
|
|
|
for (const ws of NiriService.allWorkspaces) {
|
|
if (ws.name && ws.name.trim() !== "") {
|
|
namedWorkspaces.push(ws.name)
|
|
}
|
|
}
|
|
return namedWorkspaces
|
|
}
|
|
|
|
function getPopupYPosition(barHeight) {
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
const gothOffset = defaultBar?.gothCornersEnabled ? Theme.cornerRadius : 0
|
|
const spacing = defaultBar?.spacing ?? 4
|
|
const bottomGap = defaultBar?.bottomGap ?? 0
|
|
return barHeight + spacing + bottomGap - gothOffset + Theme.popupDistance
|
|
}
|
|
|
|
function getPopupTriggerPosition(globalPos, screen, barThickness, widgetWidth, barSpacing, barPosition, barConfig) {
|
|
const screenX = screen ? screen.x : 0
|
|
const screenY = screen ? screen.y : 0
|
|
const relativeX = globalPos.x - screenX
|
|
const relativeY = globalPos.y - screenY
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
const spacing = barSpacing !== undefined ? barSpacing : (defaultBar?.spacing ?? 4)
|
|
const position = barPosition !== undefined ? barPosition : (defaultBar?.position ?? SettingsData.Position.Top)
|
|
const bottomGap = barConfig ? (barConfig.bottomGap !== undefined ? barConfig.bottomGap : (defaultBar?.bottomGap ?? 0)) : (defaultBar?.bottomGap ?? 0)
|
|
|
|
const useAutoGaps = (barConfig && barConfig.popupGapsAuto !== undefined) ? barConfig.popupGapsAuto : (defaultBar?.popupGapsAuto ?? true)
|
|
const manualGapValue = (barConfig && barConfig.popupGapsManual !== undefined) ? barConfig.popupGapsManual : (defaultBar?.popupGapsManual ?? 4)
|
|
const popupGap = useAutoGaps ? Math.max(4, spacing) : manualGapValue
|
|
|
|
switch (position) {
|
|
case SettingsData.Position.Left:
|
|
return {
|
|
"x": barThickness + spacing + popupGap,
|
|
"y": relativeY,
|
|
"width": widgetWidth
|
|
}
|
|
case SettingsData.Position.Right:
|
|
return {
|
|
"x": (screen?.width || 0) - (barThickness + spacing + popupGap),
|
|
"y": relativeY,
|
|
"width": widgetWidth
|
|
}
|
|
case SettingsData.Position.Bottom:
|
|
return {
|
|
"x": relativeX,
|
|
"y": (screen?.height || 0) - (barThickness + spacing + bottomGap + popupGap),
|
|
"width": widgetWidth
|
|
}
|
|
default:
|
|
return {
|
|
"x": relativeX,
|
|
"y": barThickness + spacing + bottomGap + popupGap,
|
|
"width": widgetWidth
|
|
}
|
|
}
|
|
}
|
|
|
|
function getAdjacentBarInfo(screen, barPosition, barConfig) {
|
|
if (!screen || !barConfig) {
|
|
return { "topBar": 0, "bottomBar": 0, "leftBar": 0, "rightBar": 0 }
|
|
}
|
|
|
|
if (barConfig.autoHide) {
|
|
return { "topBar": 0, "bottomBar": 0, "leftBar": 0, "rightBar": 0 }
|
|
}
|
|
|
|
const enabledBars = getEnabledBarConfigs()
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
const position = barPosition !== undefined ? barPosition : (defaultBar?.position ?? SettingsData.Position.Top)
|
|
let topBar = 0
|
|
let bottomBar = 0
|
|
let leftBar = 0
|
|
let rightBar = 0
|
|
|
|
for (let i = 0; i < enabledBars.length; i++) {
|
|
const other = enabledBars[i]
|
|
if (other.id === barConfig.id) continue
|
|
if (other.autoHide) continue
|
|
|
|
const otherScreens = other.screenPreferences || ["all"]
|
|
const barScreens = barConfig.screenPreferences || ["all"]
|
|
const onSameScreen = otherScreens.includes("all") || barScreens.includes("all") ||
|
|
otherScreens.some(s => isScreenInPreferences(screen, [s]))
|
|
|
|
if (!onSameScreen) continue
|
|
|
|
const otherSpacing = other.spacing !== undefined ? other.spacing : (defaultBar?.spacing ?? 4)
|
|
const otherPadding = other.innerPadding !== undefined ? other.innerPadding : (defaultBar?.innerPadding ?? 4)
|
|
const otherThickness = Math.max(26 + otherPadding * 0.6, Theme.barHeight - 4 - (8 - otherPadding)) + otherSpacing
|
|
|
|
const useAutoGaps = other.popupGapsAuto !== undefined ? other.popupGapsAuto : (defaultBar?.popupGapsAuto ?? true)
|
|
const manualGap = other.popupGapsManual !== undefined ? other.popupGapsManual : (defaultBar?.popupGapsManual ?? 4)
|
|
const popupGap = useAutoGaps ? Math.max(4, otherSpacing) : manualGap
|
|
|
|
switch (other.position) {
|
|
case SettingsData.Position.Top:
|
|
topBar = Math.max(topBar, otherThickness + popupGap)
|
|
break
|
|
case SettingsData.Position.Bottom:
|
|
bottomBar = Math.max(bottomBar, otherThickness + popupGap)
|
|
break
|
|
case SettingsData.Position.Left:
|
|
leftBar = Math.max(leftBar, otherThickness + popupGap)
|
|
break
|
|
case SettingsData.Position.Right:
|
|
rightBar = Math.max(rightBar, otherThickness + popupGap)
|
|
break
|
|
}
|
|
}
|
|
|
|
return { "topBar": topBar, "bottomBar": bottomBar, "leftBar": leftBar, "rightBar": rightBar }
|
|
}
|
|
|
|
function getBarBounds(screen, barThickness, barPosition, barConfig) {
|
|
if (!screen) {
|
|
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
|
|
}
|
|
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
const wingRadius = (defaultBar?.gothCornerRadiusOverride ?? false) ? (defaultBar?.gothCornerRadiusValue ?? 12) : Theme.cornerRadius
|
|
const wingSize = (defaultBar?.gothCornersEnabled ?? false) ? Math.max(0, wingRadius) : 0
|
|
const screenWidth = screen.width
|
|
const screenHeight = screen.height
|
|
const position = barPosition !== undefined ? barPosition : (defaultBar?.position ?? SettingsData.Position.Top)
|
|
const bottomGap = barConfig ? (barConfig.bottomGap !== undefined ? barConfig.bottomGap : (defaultBar?.bottomGap ?? 0)) : (defaultBar?.bottomGap ?? 0)
|
|
|
|
let topOffset = 0
|
|
let bottomOffset = 0
|
|
let leftOffset = 0
|
|
let rightOffset = 0
|
|
|
|
if (barConfig) {
|
|
const enabledBars = getEnabledBarConfigs()
|
|
for (let i = 0; i < enabledBars.length; i++) {
|
|
const other = enabledBars[i]
|
|
if (other.id === barConfig.id) continue
|
|
|
|
const otherScreens = other.screenPreferences || ["all"]
|
|
const barScreens = barConfig.screenPreferences || ["all"]
|
|
const onSameScreen = otherScreens.includes("all") || barScreens.includes("all") ||
|
|
otherScreens.some(s => isScreenInPreferences(screen, [s]))
|
|
|
|
if (!onSameScreen) continue
|
|
|
|
const otherSpacing = other.spacing !== undefined ? other.spacing : (defaultBar?.spacing ?? 4)
|
|
const otherPadding = other.innerPadding !== undefined ? other.innerPadding : (defaultBar?.innerPadding ?? 4)
|
|
const otherThickness = Math.max(26 + otherPadding * 0.6, Theme.barHeight - 4 - (8 - otherPadding)) + otherSpacing + wingSize
|
|
const otherBottomGap = other.bottomGap !== undefined ? other.bottomGap : (defaultBar?.bottomGap ?? 0)
|
|
|
|
switch (other.position) {
|
|
case SettingsData.Position.Top:
|
|
if (position === SettingsData.Position.Top && other.id < barConfig.id) {
|
|
topOffset += otherThickness // Simple stacking for same pos
|
|
} else if (position === SettingsData.Position.Left || position === SettingsData.Position.Right) {
|
|
topOffset = Math.max(topOffset, otherThickness)
|
|
}
|
|
break
|
|
case SettingsData.Position.Bottom:
|
|
if (position === SettingsData.Position.Bottom && other.id < barConfig.id) {
|
|
bottomOffset += (otherThickness + otherBottomGap)
|
|
} else if (position === SettingsData.Position.Left || position === SettingsData.Position.Right) {
|
|
bottomOffset = Math.max(bottomOffset, otherThickness + otherBottomGap)
|
|
}
|
|
break
|
|
case SettingsData.Position.Left:
|
|
if (position === SettingsData.Position.Top || position === SettingsData.Position.Bottom) {
|
|
leftOffset = Math.max(leftOffset, otherThickness)
|
|
} else if (position === SettingsData.Position.Left && other.id < barConfig.id) {
|
|
leftOffset += otherThickness
|
|
}
|
|
break
|
|
case SettingsData.Position.Right:
|
|
if (position === SettingsData.Position.Top || position === SettingsData.Position.Bottom) {
|
|
rightOffset = Math.max(rightOffset, otherThickness)
|
|
} else if (position === SettingsData.Position.Right && other.id < barConfig.id) {
|
|
rightOffset += otherThickness
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (position) {
|
|
case SettingsData.Position.Top:
|
|
return {
|
|
"x": leftOffset,
|
|
"y": topOffset + bottomGap,
|
|
"width": screenWidth - leftOffset - rightOffset,
|
|
"height": barThickness + wingSize,
|
|
"wingSize": wingSize
|
|
}
|
|
case SettingsData.Position.Bottom:
|
|
return {
|
|
"x": leftOffset,
|
|
"y": screenHeight - barThickness - wingSize - bottomGap - bottomOffset,
|
|
"width": screenWidth - leftOffset - rightOffset,
|
|
"height": barThickness + wingSize,
|
|
"wingSize": wingSize
|
|
}
|
|
case SettingsData.Position.Left:
|
|
return {
|
|
"x": 0,
|
|
"y": topOffset,
|
|
"width": barThickness + wingSize,
|
|
"height": screenHeight - topOffset - bottomOffset,
|
|
"wingSize": wingSize
|
|
}
|
|
case SettingsData.Position.Right:
|
|
return {
|
|
"x": screenWidth - barThickness - wingSize,
|
|
"y": topOffset,
|
|
"width": barThickness + wingSize,
|
|
"height": screenHeight - topOffset - bottomOffset,
|
|
"wingSize": wingSize
|
|
}
|
|
}
|
|
|
|
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
|
|
}
|
|
|
|
function updateBarConfigs() {
|
|
barConfigsChanged()
|
|
saveSettings()
|
|
}
|
|
|
|
function getBarConfig(barId) {
|
|
return barConfigs.find(cfg => cfg.id === barId) || null
|
|
}
|
|
|
|
function addBarConfig(config) {
|
|
const configs = JSON.parse(JSON.stringify(barConfigs))
|
|
configs.push(config)
|
|
barConfigs = configs
|
|
updateBarConfigs()
|
|
}
|
|
|
|
function updateBarConfig(barId, updates) {
|
|
const configs = JSON.parse(JSON.stringify(barConfigs))
|
|
const index = configs.findIndex(cfg => cfg.id === barId)
|
|
if (index === -1) return
|
|
|
|
const positionChanged = updates.position !== undefined && configs[index].position !== updates.position
|
|
|
|
Object.assign(configs[index], updates)
|
|
barConfigs = configs
|
|
updateBarConfigs()
|
|
|
|
if (positionChanged) {
|
|
NotificationService.clearAllPopups()
|
|
}
|
|
}
|
|
|
|
function checkBarCollisions(barId) {
|
|
const bar = getBarConfig(barId)
|
|
if (!bar || !bar.enabled) return []
|
|
|
|
const conflicts = []
|
|
const enabledBars = getEnabledBarConfigs()
|
|
|
|
for (let i = 0; i < enabledBars.length; i++) {
|
|
const other = enabledBars[i]
|
|
if (other.id === barId) continue
|
|
|
|
const samePosition = bar.position === other.position
|
|
if (!samePosition) continue
|
|
|
|
const barScreens = bar.screenPreferences || ["all"]
|
|
const otherScreens = other.screenPreferences || ["all"]
|
|
|
|
const hasAll = barScreens.includes("all") || otherScreens.includes("all")
|
|
if (hasAll) {
|
|
conflicts.push({
|
|
barId: other.id,
|
|
barName: other.name,
|
|
reason: "Same position on all screens"
|
|
})
|
|
continue
|
|
}
|
|
|
|
const overlapping = barScreens.some(screen => otherScreens.includes(screen))
|
|
if (overlapping) {
|
|
conflicts.push({
|
|
barId: other.id,
|
|
barName: other.name,
|
|
reason: "Same position on overlapping screens"
|
|
})
|
|
}
|
|
}
|
|
|
|
return conflicts
|
|
}
|
|
|
|
function deleteBarConfig(barId) {
|
|
if (barId === "default") return
|
|
|
|
const configs = barConfigs.filter(cfg => cfg.id !== barId)
|
|
barConfigs = configs
|
|
updateBarConfigs()
|
|
}
|
|
|
|
function getEnabledBarConfigs() {
|
|
return barConfigs.filter(cfg => cfg.enabled)
|
|
}
|
|
|
|
function getScreenDisplayName(screen) {
|
|
if (!screen) return ""
|
|
if (displayNameMode === "model" && screen.model) {
|
|
return screen.model
|
|
}
|
|
return screen.name
|
|
}
|
|
|
|
function isScreenInPreferences(screen, prefs) {
|
|
if (!screen) return false
|
|
|
|
return prefs.some(pref => {
|
|
if (typeof pref === "string") {
|
|
return pref === "all" || pref === screen.name || pref === screen.model
|
|
}
|
|
|
|
if (displayNameMode === "model") {
|
|
return pref.model && screen.model && pref.model === screen.model
|
|
}
|
|
return pref.name === screen.name
|
|
})
|
|
}
|
|
|
|
function getFilteredScreens(componentId) {
|
|
var prefs = screenPreferences && screenPreferences[componentId] || ["all"]
|
|
if (prefs.includes("all") || (typeof prefs[0] === "string" && prefs[0] === "all")) {
|
|
return Quickshell.screens
|
|
}
|
|
var filtered = Quickshell.screens.filter(screen => isScreenInPreferences(screen, prefs))
|
|
if (filtered.length === 0 && showOnLastDisplay && showOnLastDisplay[componentId] && Quickshell.screens.length === 1) {
|
|
return Quickshell.screens
|
|
}
|
|
return filtered
|
|
}
|
|
|
|
function sendTestNotifications() {
|
|
NotificationService.clearAllPopups()
|
|
sendTestNotification(0)
|
|
testNotifTimer1.start()
|
|
testNotifTimer2.start()
|
|
}
|
|
|
|
function sendTestNotification(index) {
|
|
const notifications = [["Notification Position Test", "DMS test notification 1 of 3 ~ Hi there!", "preferences-system"], ["Second Test", "DMS Notification 2 of 3 ~ Check it out!", "applications-graphics"], ["Third Test", "DMS notification 3 of 3 ~ Enjoy!", "face-smile"]]
|
|
|
|
if (index < 0 || index >= notifications.length) {
|
|
return
|
|
}
|
|
|
|
const notif = notifications[index]
|
|
testNotificationProcess.command = ["notify-send", "-h", "int:transient:1", "-a", "DMS", "-i", notif[2], notif[0], notif[1]]
|
|
testNotificationProcess.running = true
|
|
}
|
|
|
|
|
|
function setMatugenScheme(scheme) {
|
|
var normalized = scheme || "scheme-tonal-spot"
|
|
if (matugenScheme === normalized) return
|
|
set("matugenScheme", normalized)
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme()
|
|
}
|
|
}
|
|
|
|
function setRunUserMatugenTemplates(enabled) {
|
|
if (runUserMatugenTemplates === enabled) return
|
|
set("runUserMatugenTemplates", enabled)
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme()
|
|
}
|
|
}
|
|
|
|
function setMatugenTargetMonitor(monitorName) {
|
|
if (matugenTargetMonitor === monitorName) return
|
|
set("matugenTargetMonitor", monitorName)
|
|
if (typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme()
|
|
}
|
|
}
|
|
|
|
|
|
function setCornerRadius(radius) {
|
|
set("cornerRadius", radius)
|
|
NiriService.generateNiriLayoutConfig()
|
|
}
|
|
|
|
function setWeatherLocation(displayName, coordinates) {
|
|
weatherLocation = displayName
|
|
weatherCoordinates = coordinates
|
|
saveSettings()
|
|
}
|
|
|
|
function setIconTheme(themeName) {
|
|
iconTheme = themeName
|
|
updateGtkIconTheme()
|
|
updateQtIconTheme()
|
|
saveSettings()
|
|
if (typeof Theme !== "undefined" && Theme.currentTheme === Theme.dynamic) Theme.generateSystemThemesFromCurrentTheme()
|
|
}
|
|
|
|
function setGtkThemingEnabled(enabled) {
|
|
set("gtkThemingEnabled", enabled)
|
|
if (enabled && typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme()
|
|
}
|
|
}
|
|
|
|
function setQtThemingEnabled(enabled) {
|
|
set("qtThemingEnabled", enabled)
|
|
if (enabled && typeof Theme !== "undefined") {
|
|
Theme.generateSystemThemesFromCurrentTheme()
|
|
}
|
|
}
|
|
|
|
function setShowDock(enabled) {
|
|
showDock = enabled
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
const barPos = defaultBar?.position ?? SettingsData.Position.Top
|
|
if (enabled && dockPosition === barPos) {
|
|
if (barPos === SettingsData.Position.Top) {
|
|
setDockPosition(SettingsData.Position.Bottom)
|
|
return
|
|
}
|
|
if (barPos === SettingsData.Position.Bottom) {
|
|
setDockPosition(SettingsData.Position.Top)
|
|
return
|
|
}
|
|
if (barPos === SettingsData.Position.Left) {
|
|
setDockPosition(SettingsData.Position.Right)
|
|
return
|
|
}
|
|
if (barPos === SettingsData.Position.Right) {
|
|
setDockPosition(SettingsData.Position.Left)
|
|
return
|
|
}
|
|
}
|
|
saveSettings()
|
|
}
|
|
|
|
function setDockPosition(position) {
|
|
dockPosition = position
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
const barPos = defaultBar?.position ?? SettingsData.Position.Top
|
|
if (position === SettingsData.Position.Bottom && barPos === SettingsData.Position.Bottom && showDock) {
|
|
setDankBarPosition(SettingsData.Position.Top)
|
|
}
|
|
if (position === SettingsData.Position.Top && barPos === SettingsData.Position.Top && showDock) {
|
|
setDankBarPosition(SettingsData.Position.Bottom)
|
|
}
|
|
if (position === SettingsData.Position.Left && barPos === SettingsData.Position.Left && showDock) {
|
|
setDankBarPosition(SettingsData.Position.Right)
|
|
}
|
|
if (position === SettingsData.Position.Right && barPos === SettingsData.Position.Right && showDock) {
|
|
setDankBarPosition(SettingsData.Position.Left)
|
|
}
|
|
saveSettings()
|
|
Qt.callLater(() => forceDockLayoutRefresh())
|
|
}
|
|
|
|
function setDankBarSpacing(spacing) {
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
if (defaultBar) {
|
|
updateBarConfig(defaultBar.id, { spacing: spacing })
|
|
}
|
|
if (typeof NiriService !== "undefined" && CompositorService.isNiri) {
|
|
NiriService.generateNiriLayoutConfig()
|
|
}
|
|
}
|
|
|
|
function setDankBarPosition(position) {
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
if (!defaultBar) return
|
|
|
|
if (position === SettingsData.Position.Bottom && dockPosition === SettingsData.Position.Bottom && showDock) {
|
|
setDockPosition(SettingsData.Position.Top)
|
|
return
|
|
}
|
|
if (position === SettingsData.Position.Top && dockPosition === SettingsData.Position.Top && showDock) {
|
|
setDockPosition(SettingsData.Position.Bottom)
|
|
return
|
|
}
|
|
if (position === SettingsData.Position.Left && dockPosition === SettingsData.Position.Left && showDock) {
|
|
setDockPosition(SettingsData.Position.Right)
|
|
return
|
|
}
|
|
if (position === SettingsData.Position.Right && dockPosition === SettingsData.Position.Right && showDock) {
|
|
setDockPosition(SettingsData.Position.Left)
|
|
return
|
|
}
|
|
updateBarConfig(defaultBar.id, { position: position })
|
|
}
|
|
|
|
function setDankBarLeftWidgets(order) {
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
if (defaultBar) {
|
|
updateBarConfig(defaultBar.id, { leftWidgets: order })
|
|
updateListModel(leftWidgetsModel, order)
|
|
}
|
|
}
|
|
|
|
function setDankBarCenterWidgets(order) {
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
if (defaultBar) {
|
|
updateBarConfig(defaultBar.id, { centerWidgets: order })
|
|
updateListModel(centerWidgetsModel, order)
|
|
}
|
|
}
|
|
|
|
function setDankBarRightWidgets(order) {
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
if (defaultBar) {
|
|
updateBarConfig(defaultBar.id, { rightWidgets: order })
|
|
updateListModel(rightWidgetsModel, order)
|
|
}
|
|
}
|
|
|
|
function resetDankBarWidgetsToDefault() {
|
|
var defaultLeft = ["launcherButton", "workspaceSwitcher", "focusedWindow"]
|
|
var defaultCenter = ["music", "clock", "weather"]
|
|
var defaultRight = ["systemTray", "clipboard", "notificationButton", "battery", "controlCenterButton"]
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
if (defaultBar) {
|
|
updateBarConfig(defaultBar.id, {
|
|
leftWidgets: defaultLeft,
|
|
centerWidgets: defaultCenter,
|
|
rightWidgets: defaultRight
|
|
})
|
|
}
|
|
updateListModel(leftWidgetsModel, defaultLeft)
|
|
updateListModel(centerWidgetsModel, defaultCenter)
|
|
updateListModel(rightWidgetsModel, defaultRight)
|
|
showLauncherButton = true
|
|
showWorkspaceSwitcher = true
|
|
showFocusedWindow = true
|
|
showWeather = true
|
|
showMusic = true
|
|
showClipboard = true
|
|
showCpuUsage = true
|
|
showMemUsage = true
|
|
showCpuTemp = true
|
|
showGpuTemp = true
|
|
showSystemTray = true
|
|
showClock = true
|
|
showNotificationButton = true
|
|
showBattery = true
|
|
showControlCenterButton = true
|
|
showCapsLockIndicator = true
|
|
}
|
|
|
|
function setWorkspaceNameIcon(workspaceName, iconData) {
|
|
var iconMap = JSON.parse(JSON.stringify(workspaceNameIcons))
|
|
iconMap[workspaceName] = iconData
|
|
workspaceNameIcons = iconMap
|
|
saveSettings()
|
|
workspaceIconsUpdated()
|
|
}
|
|
|
|
function removeWorkspaceNameIcon(workspaceName) {
|
|
var iconMap = JSON.parse(JSON.stringify(workspaceNameIcons))
|
|
delete iconMap[workspaceName]
|
|
workspaceNameIcons = iconMap
|
|
saveSettings()
|
|
workspaceIconsUpdated()
|
|
}
|
|
|
|
function getWorkspaceNameIcon(workspaceName) {
|
|
return workspaceNameIcons[workspaceName] || null
|
|
}
|
|
|
|
function toggleDankBarVisible() {
|
|
const defaultBar = barConfigs[0] || getBarConfig("default")
|
|
if (defaultBar) {
|
|
updateBarConfig(defaultBar.id, { visible: !defaultBar.visible })
|
|
}
|
|
}
|
|
|
|
function toggleShowDock() {
|
|
setShowDock(!showDock)
|
|
}
|
|
|
|
function getPluginSetting(pluginId, key, defaultValue) {
|
|
if (!pluginSettings[pluginId]) {
|
|
return defaultValue
|
|
}
|
|
return pluginSettings[pluginId][key] !== undefined ? pluginSettings[pluginId][key] : defaultValue
|
|
}
|
|
|
|
function setPluginSetting(pluginId, key, value) {
|
|
const updated = JSON.parse(JSON.stringify(pluginSettings))
|
|
if (!updated[pluginId]) {
|
|
updated[pluginId] = {}
|
|
}
|
|
updated[pluginId][key] = value
|
|
pluginSettings = updated
|
|
savePluginSettings()
|
|
}
|
|
|
|
function removePluginSettings(pluginId) {
|
|
if (pluginSettings[pluginId]) {
|
|
delete pluginSettings[pluginId]
|
|
savePluginSettings()
|
|
}
|
|
}
|
|
|
|
function getPluginSettingsForPlugin(pluginId) {
|
|
const settings = pluginSettings[pluginId]
|
|
return settings ? JSON.parse(JSON.stringify(settings)) : {}
|
|
}
|
|
|
|
|
|
ListModel {
|
|
id: leftWidgetsModel
|
|
}
|
|
|
|
ListModel {
|
|
id: centerWidgetsModel
|
|
}
|
|
|
|
ListModel {
|
|
id: rightWidgetsModel
|
|
}
|
|
|
|
property Process testNotificationProcess
|
|
|
|
testNotificationProcess: Process {
|
|
command: []
|
|
running: false
|
|
}
|
|
|
|
property Timer testNotifTimer1
|
|
|
|
testNotifTimer1: Timer {
|
|
interval: 400
|
|
repeat: false
|
|
onTriggered: sendTestNotification(1)
|
|
}
|
|
|
|
property Timer testNotifTimer2
|
|
|
|
testNotifTimer2: Timer {
|
|
interval: 800
|
|
repeat: false
|
|
onTriggered: sendTestNotification(2)
|
|
}
|
|
|
|
property alias settingsFile: settingsFile
|
|
|
|
FileView {
|
|
id: settingsFile
|
|
|
|
path: isGreeterMode ? "" : StandardPaths.writableLocation(StandardPaths.ConfigLocation) + "/DankMaterialShell/settings.json"
|
|
blockLoading: true
|
|
blockWrites: true
|
|
atomicWrites: true
|
|
watchChanges: !isGreeterMode
|
|
onLoaded: {
|
|
if (!isGreeterMode) {
|
|
try {
|
|
const txt = settingsFile.text()
|
|
const obj = (txt && txt.trim()) ? JSON.parse(txt) : null
|
|
Store.parse(root, obj)
|
|
} catch (e) {
|
|
console.warn("SettingsData: Failed to reload settings:", e.message)
|
|
}
|
|
hasTriedDefaultSettings = false
|
|
}
|
|
}
|
|
onLoadFailed: error => {
|
|
if (!isGreeterMode && !hasTriedDefaultSettings) {
|
|
hasTriedDefaultSettings = true
|
|
Processes.checkDefaultSettings()
|
|
} else if (!isGreeterMode) {
|
|
applyStoredTheme()
|
|
}
|
|
}
|
|
}
|
|
|
|
FileView {
|
|
id: pluginSettingsFile
|
|
|
|
path: isGreeterMode ? "" : pluginSettingsPath
|
|
blockLoading: true
|
|
blockWrites: true
|
|
atomicWrites: true
|
|
watchChanges: !isGreeterMode
|
|
onLoaded: {
|
|
if (!isGreeterMode) {
|
|
parsePluginSettings(pluginSettingsFile.text())
|
|
}
|
|
}
|
|
onLoadFailed: error => {
|
|
if (!isGreeterMode) {
|
|
pluginSettings = {}
|
|
}
|
|
}
|
|
}
|
|
|
|
property bool pluginSettingsFileExists: false
|
|
|
|
IpcHandler {
|
|
function reveal(): string {
|
|
root.setShowDock(true)
|
|
return "DOCK_SHOW_SUCCESS"
|
|
}
|
|
|
|
function hide(): string {
|
|
root.setShowDock(false)
|
|
return "DOCK_HIDE_SUCCESS"
|
|
}
|
|
|
|
function toggle(): string {
|
|
root.toggleShowDock()
|
|
return root.showDock ? "DOCK_SHOW_SUCCESS" : "DOCK_HIDE_SUCCESS"
|
|
}
|
|
|
|
function status(): string {
|
|
return root.showDock ? "visible" : "hidden"
|
|
}
|
|
|
|
target: "dock"
|
|
}
|
|
}
|