mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-17 00:34:01 -04:00
feat(wallpaper): add folder-based wallpaper selection and shuffle (#2990)
* feat(wallpaper): add folder-based wallpaper selection and shuffle * fix(wallpaper): bump 'dank-qml-common' and handle single-wallpaper folders * fix(wallpaper): address review feedback for folder selection * fix(wallpaper): persist folder selection across restarts * fix(wallpaper): pick first wallpaper on folder select and persist folder path * fix: resolve wallpaper cycling folder persistence issues
This commit is contained in:
@@ -153,6 +153,7 @@ Singleton {
|
||||
property string wallpaperCyclingMode: "interval"
|
||||
property int wallpaperCyclingInterval: 300
|
||||
property string wallpaperCyclingTime: "06:00"
|
||||
property string wallpaperCyclingFolderPath: ""
|
||||
property var monitorCyclingSettings: ({})
|
||||
|
||||
property bool nightModeEnabled: false
|
||||
@@ -1000,6 +1001,37 @@ Singleton {
|
||||
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();
|
||||
@@ -1545,7 +1577,8 @@ Singleton {
|
||||
"random": false,
|
||||
"mode": "interval",
|
||||
"interval": 300,
|
||||
"time": "06:00"
|
||||
"time": "06:00",
|
||||
"folderPath": ""
|
||||
};
|
||||
var value = _findMonitorValue(monitorCyclingSettings, screenName);
|
||||
return Object.assign({}, defaults, value !== undefined ? value : {});
|
||||
|
||||
@@ -24,6 +24,7 @@ var SPEC = {
|
||||
wallpaperCyclingMode: { def: "interval" },
|
||||
wallpaperCyclingInterval: { def: 300 },
|
||||
wallpaperCyclingTime: { def: "06:00" },
|
||||
wallpaperCyclingFolderPath: { def: "" },
|
||||
monitorCyclingSettings: { def: {} },
|
||||
|
||||
nightModeEnabled: { def: false },
|
||||
|
||||
@@ -177,6 +177,8 @@ DankFloatingWindow {
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp", "*.jxl", "*.avif", "*.heif", "*.exr"]
|
||||
onFileSelected: path => {
|
||||
SessionData.setWallpaper(path);
|
||||
SessionData.wallpaperCyclingFolderPath = "";
|
||||
SessionData.saveSettings();
|
||||
close();
|
||||
}
|
||||
onDialogClosed: () => {
|
||||
|
||||
@@ -159,8 +159,11 @@ Item {
|
||||
function setCurrentWallpaper(path) {
|
||||
if (SessionData.perMonitorWallpaper && targetScreenName) {
|
||||
SessionData.setMonitorWallpaper(targetScreenName, path);
|
||||
SessionData.setMonitorCyclingFolderPath(targetScreenName, "");
|
||||
} else {
|
||||
SessionData.setWallpaper(path);
|
||||
SessionData.wallpaperCyclingFolderPath = "";
|
||||
SessionData.saveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,6 +146,26 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 32
|
||||
height: 32
|
||||
radius: 16
|
||||
color: Qt.rgba(255, 255, 255, 0.9)
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: "create_new_folder"
|
||||
size: 18
|
||||
color: "black"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.openFolderWallpaperBrowser()
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 32
|
||||
height: 32
|
||||
@@ -199,10 +219,13 @@ Item {
|
||||
onClicked: {
|
||||
if (SessionData.perMonitorWallpaper) {
|
||||
SessionData.setMonitorWallpaper(selectedMonitorName, "");
|
||||
SessionData.setMonitorCyclingFolderPath(selectedMonitorName, "");
|
||||
} else {
|
||||
if (Theme.currentTheme === Theme.dynamic)
|
||||
Theme.switchTheme("blue");
|
||||
SessionData.clearWallpaper();
|
||||
SessionData.wallpaperCyclingFolderPath = "";
|
||||
SessionData.saveSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1308,6 +1331,12 @@ Item {
|
||||
mainWallpaperBrowserLoader.item.open();
|
||||
}
|
||||
|
||||
function openFolderWallpaperBrowser() {
|
||||
folderWallpaperBrowserLoader.active = true;
|
||||
if (folderWallpaperBrowserLoader.item)
|
||||
folderWallpaperBrowserLoader.item.open();
|
||||
}
|
||||
|
||||
function openLightWallpaperBrowser() {
|
||||
lightWallpaperBrowserLoader.active = true;
|
||||
if (lightWallpaperBrowserLoader.item)
|
||||
@@ -1334,14 +1363,36 @@ Item {
|
||||
onFileSelected: path => {
|
||||
if (SessionData.perMonitorWallpaper) {
|
||||
SessionData.setMonitorWallpaper(selectedMonitorName, path);
|
||||
SessionData.setMonitorCyclingFolderPath(selectedMonitorName, "");
|
||||
} else {
|
||||
SessionData.setWallpaper(path);
|
||||
SessionData.wallpaperCyclingFolderPath = "";
|
||||
SessionData.saveSettings();
|
||||
}
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: folderWallpaperBrowserLoader
|
||||
active: false
|
||||
|
||||
FileBrowserModal {
|
||||
parentModal: root.parentModal
|
||||
browserTitle: I18n.tr("Choose wallpaper folder", "wallpaper folder file browser title")
|
||||
browserIcon: "folder"
|
||||
browserType: "wallpaper"
|
||||
folderMode: true
|
||||
showHiddenFiles: true
|
||||
onFileSelected: path => {
|
||||
var targetMonitor = SessionData.perMonitorWallpaper ? selectedMonitorName : "";
|
||||
WallpaperCyclingService.cycleFromFolder(targetMonitor, path);
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: lightWallpaperBrowserLoader
|
||||
active: false
|
||||
|
||||
@@ -148,12 +148,26 @@ Singleton {
|
||||
monitorProcesses = newProcesses;
|
||||
return process;
|
||||
}
|
||||
|
||||
function cycle(screenName, wallpaperPath, goToPrevious) {
|
||||
const currentWallpaper = wallpaperPath || SessionData.wallpaperPath;
|
||||
const currentWallpaper = wallpaperPath || (screenName ? SessionData.getMonitorWallpaper(screenName) : SessionData.wallpaperPath);
|
||||
if (!currentWallpaper)
|
||||
return;
|
||||
const wallpaperDir = currentWallpaper.substring(0, currentWallpaper.lastIndexOf('/'));
|
||||
let wallpaperDir;
|
||||
|
||||
if (screenName) {
|
||||
const monitorSettings = SessionData.getMonitorCyclingSettings(screenName);
|
||||
if (monitorSettings.folderPath && currentWallpaper.startsWith(monitorSettings.folderPath + "/")) {
|
||||
wallpaperDir = monitorSettings.folderPath;
|
||||
} else {
|
||||
wallpaperDir = currentWallpaper.substring(0, currentWallpaper.lastIndexOf('/'));
|
||||
}
|
||||
} else {
|
||||
if (SessionData.wallpaperCyclingFolderPath && currentWallpaper.startsWith(SessionData.wallpaperCyclingFolderPath + "/")) {
|
||||
wallpaperDir = SessionData.wallpaperCyclingFolderPath;
|
||||
} else {
|
||||
wallpaperDir = currentWallpaper.substring(0, currentWallpaper.lastIndexOf('/'));
|
||||
}
|
||||
}
|
||||
|
||||
if (screenName && monitorProcessComponent.status === Component.Ready) {
|
||||
var process = monitorProcessFor(screenName);
|
||||
@@ -180,6 +194,35 @@ Singleton {
|
||||
cycle(screenName, wallpaperPath, true);
|
||||
}
|
||||
|
||||
function cycleFromFolder(screenName, folderPath) {
|
||||
if (!folderPath)
|
||||
return;
|
||||
|
||||
if (screenName) {
|
||||
SessionData.setMonitorCyclingFolderPath(screenName, folderPath);
|
||||
} else {
|
||||
SessionData.wallpaperCyclingFolderPath = folderPath;
|
||||
SessionData.saveSettings();
|
||||
}
|
||||
|
||||
if (screenName && monitorProcessComponent.status === Component.Ready) {
|
||||
var process = monitorProcessFor(screenName);
|
||||
process.command = findCommand(folderPath);
|
||||
process.targetScreenName = screenName;
|
||||
process.currentWallpaper = "";
|
||||
process.goToPrevious = false;
|
||||
process.running = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var globalProcess = cyclingProcess;
|
||||
globalProcess.command = findCommand(folderPath);
|
||||
globalProcess.targetScreenName = screenName || "";
|
||||
globalProcess.currentWallpaper = "";
|
||||
globalProcess.goToPrevious = false;
|
||||
globalProcess.running = true;
|
||||
}
|
||||
|
||||
function resetScheduleAfterManual() {
|
||||
if (!serverSchedulingAvailable)
|
||||
return;
|
||||
@@ -224,10 +267,14 @@ Singleton {
|
||||
if (!text || !text.trim())
|
||||
return;
|
||||
const files = text.trim().split('\n').filter(file => file.length > 0);
|
||||
if (files.length <= 1)
|
||||
if (files.length < 1)
|
||||
return;
|
||||
const wallpaperList = files.sort();
|
||||
let currentIndex = wallpaperList.findIndex(path => path === currentPath);
|
||||
const isInitialFolderSelect = currentPath === "";
|
||||
let currentIndex = -1;
|
||||
if (!isInitialFolderSelect) {
|
||||
currentIndex = wallpaperList.findIndex(path => path === currentPath);
|
||||
}
|
||||
if (currentIndex === -1)
|
||||
currentIndex = 0;
|
||||
|
||||
@@ -239,7 +286,9 @@ Singleton {
|
||||
}
|
||||
|
||||
let targetIndex;
|
||||
if (isRandom) {
|
||||
if (isInitialFolderSelect) {
|
||||
targetIndex = 0;
|
||||
} else if (isRandom) {
|
||||
if (wallpaperList.length > 1) {
|
||||
do {
|
||||
targetIndex = Math.floor(Math.random() * wallpaperList.length);
|
||||
@@ -331,6 +380,8 @@ Singleton {
|
||||
|
||||
try {
|
||||
SessionData.setWallpaper(absolutePath);
|
||||
SessionData.wallpaperCyclingFolderPath = "";
|
||||
SessionData.saveSettings();
|
||||
return "SUCCESS: Wallpaper set to " + absolutePath;
|
||||
} catch (e) {
|
||||
return "ERROR: Failed to set wallpaper: " + e.toString();
|
||||
@@ -341,6 +392,7 @@ Singleton {
|
||||
SessionData.setWallpaper("");
|
||||
SessionData.setPerMonitorWallpaper(false);
|
||||
SessionData.monitorWallpapers = {};
|
||||
SessionData.wallpaperCyclingFolderPath = "";
|
||||
SessionData.saveSettings();
|
||||
return "SUCCESS: All wallpapers cleared";
|
||||
}
|
||||
@@ -402,6 +454,7 @@ Singleton {
|
||||
SessionData.setPerMonitorWallpaper(true);
|
||||
}
|
||||
SessionData.setMonitorWallpaper(screenName, absolutePath);
|
||||
SessionData.setMonitorCyclingFolderPath(screenName, "");
|
||||
return "SUCCESS: Wallpaper set for " + screenName + " to " + absolutePath;
|
||||
} catch (e) {
|
||||
return "ERROR: Failed to set wallpaper for " + screenName + ": " + e.toString();
|
||||
|
||||
Reference in New Issue
Block a user