diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 676c4575..6979aecb 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -375,6 +375,23 @@ Singleton { } } + // ----------------------------------------------------- + // Function to preprocess paths by expanding "~" to user's home directory + function preprocessPath(path) { + if (typeof path !== "string" || path === "") { + return path + } + + // Expand "~" to user's home directory + if (path.startsWith("~/")) { + return Quickshell.env("HOME") + path.substring(1) + } else if (path === "~") { + return Quickshell.env("HOME") + } + + return path + } + // ----------------------------------------------------- // Public function to trigger immediate settings saving function saveImmediate() { diff --git a/Modules/ControlCenter/Cards/ProfileCard.qml b/Modules/ControlCenter/Cards/ProfileCard.qml index c36d57dc..79759089 100644 --- a/Modules/ControlCenter/Cards/ProfileCard.qml +++ b/Modules/ControlCenter/Cards/ProfileCard.qml @@ -28,7 +28,7 @@ NBox { NImageCircled { width: Style.baseWidgetSize * 1.25 * scaling height: Style.baseWidgetSize * 1.25 * scaling - imagePath: Settings.data.general.avatarImage + imagePath: Settings.preprocessPath(Settings.data.general.avatarImage) fallbackIcon: "person" borderColor: Color.mPrimary borderWidth: Math.max(1, Style.borderM * scaling) diff --git a/Modules/ControlCenter/Cards/TopCard.qml b/Modules/ControlCenter/Cards/TopCard.qml index 21b68eca..abda1cd7 100644 --- a/Modules/ControlCenter/Cards/TopCard.qml +++ b/Modules/ControlCenter/Cards/TopCard.qml @@ -32,7 +32,7 @@ NBox { NImageCircled { width: Style.baseWidgetSize * 1.25 * scaling height: width - imagePath: Settings.data.general.avatarImage + imagePath: Settings.preprocessPath(Settings.data.general.avatarImage) fallbackIcon: "person" borderColor: Color.mPrimary borderWidth: Math.max(1, Style.borderM * scaling) diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 631fd56b..225c1529 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -299,7 +299,7 @@ Loader { anchors.centerIn: parent width: 66 * scaling height: 66 * scaling - imagePath: Settings.data.general.avatarImage + imagePath: Settings.preprocessPath(Settings.data.general.avatarImage) fallbackIcon: "person" SequentialAnimation on scale { diff --git a/Modules/Settings/Tabs/GeneralTab.qml b/Modules/Settings/Tabs/GeneralTab.qml index 558a8860..b665c58e 100644 --- a/Modules/Settings/Tabs/GeneralTab.qml +++ b/Modules/Settings/Tabs/GeneralTab.qml @@ -23,7 +23,7 @@ ColumnLayout { NImageCircled { width: 108 * scaling height: 108 * scaling - imagePath: Settings.data.general.avatarImage + imagePath: Settings.preprocessPath(Settings.data.general.avatarImage) fallbackIcon: "person" borderColor: Color.mPrimary borderWidth: Math.max(1, Style.borderM * scaling) @@ -50,7 +50,7 @@ ColumnLayout { id: avatarPicker title: I18n.tr("settings.general.profile.select-avatar") selectionMode: "files" - initialPath: Settings.data.general.avatarImage.substr(0, Settings.data.general.avatarImage.lastIndexOf("/")) || Quickshell.env("HOME") + initialPath: Settings.preprocessPath(Settings.data.general.avatarImage).substr(0, Settings.preprocessPath(Settings.data.general.avatarImage).lastIndexOf("/")) || Quickshell.env("HOME") nameFilters: ["*.jpg", "*.jpeg", "*.png", "*.gif", "*.pnm", "*.bmp"] onAccepted: paths => { if (paths.length > 0) { diff --git a/Services/ScreenRecorderService.qml b/Services/ScreenRecorderService.qml index 7e57ce75..57fc578a 100644 --- a/Services/ScreenRecorderService.qml +++ b/Services/ScreenRecorderService.qml @@ -49,7 +49,7 @@ Singleton { function launchRecorder() { var filename = Time.getFormattedTimestamp() + ".mp4" - var videoDir = settings.directory + var videoDir = Settings.preprocessPath(settings.directory) if (videoDir && !videoDir.endsWith("/")) { videoDir += "/" } diff --git a/Services/WallpaperService.qml b/Services/WallpaperService.qml index c60f2eba..2046f6cc 100644 --- a/Services/WallpaperService.qml +++ b/Services/WallpaperService.qml @@ -10,6 +10,7 @@ Singleton { id: root readonly property ListModel fillModeModel: ListModel {} + readonly property string defaultDirectory: Settings.preprocessPath(Settings.data.wallpaper.directory) // All available wallpaper transitions readonly property ListModel transitionsModel: ListModel {} @@ -44,7 +45,7 @@ Singleton { if (!Settings.data.wallpaper.enableMultiMonitorDirectories) { // All monitors use the main directory for (var i = 0; i < Quickshell.screens.length; i++) { - root.wallpaperDirectoryChanged(Quickshell.screens[i].name, Settings.data.wallpaper.directory) + root.wallpaperDirectoryChanged(Quickshell.screens[i].name, root.defaultDirectory) } } else { // Only monitors without custom directories are affected @@ -52,7 +53,7 @@ Singleton { var screenName = Quickshell.screens[i].name var monitor = root.getMonitorConfig(screenName) if (!monitor || !monitor.directory) { - root.wallpaperDirectoryChanged(screenName, Settings.data.wallpaper.directory) + root.wallpaperDirectoryChanged(screenName, root.defaultDirectory) } } } @@ -177,16 +178,16 @@ Singleton { // Get specific monitor directory function getMonitorDirectory(screenName) { if (!Settings.data.wallpaper.enableMultiMonitorDirectories) { - return Settings.data.wallpaper.directory + return root.defaultDirectory } var monitor = getMonitorConfig(screenName) if (monitor !== undefined && monitor.directory !== undefined) { - return monitor.directory + return Settings.preprocessPath(monitor.directory) } // Fall back to the main/single directory - return Settings.data.wallpaper.directory + return root.defaultDirectory } // ------------------------------------------------------------------- @@ -218,7 +219,7 @@ Singleton { // Update Settings with new array to ensure proper persistence Settings.data.wallpaper.monitors = newMonitors.slice() - root.wallpaperDirectoryChanged(screenName, directory) + root.wallpaperDirectoryChanged(screenName, Settings.preprocessPath(directory)) } // ------------------------------------------------------------------- @@ -274,7 +275,7 @@ Singleton { found = true return { "name": screenName, - "directory": monitor.directory || getMonitorDirectory(screenName), + "directory": Settings.preprocessPath(monitor.directory) || getMonitorDirectory(screenName), "wallpaper": path } }