1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 13:32:50 -05:00

wallpaper: encode image URIs

fixes #1306
This commit is contained in:
bbedward
2026-01-08 14:31:48 -05:00
parent f5f21e738a
commit a21a846bf5
11 changed files with 131 additions and 117 deletions

View File

@@ -52,6 +52,12 @@ FocusScope {
signal fileSelected(string path) signal fileSelected(string path)
signal closeRequested signal closeRequested
function encodeFileUrl(path) {
if (!path)
return "";
return "file://" + path.split('/').map(s => encodeURIComponent(s)).join('/');
}
function initialize() { function initialize() {
loadSettings(); loadSettings();
currentPath = getLastPath(); currentPath = getLastPath();
@@ -188,7 +194,7 @@ FocusScope {
function handleSaveFile(filePath) { function handleSaveFile(filePath) {
var normalizedPath = filePath; var normalizedPath = filePath;
if (!normalizedPath.startsWith("file://")) { if (!normalizedPath.startsWith("file://")) {
normalizedPath = "file://" + filePath; normalizedPath = encodeFileUrl(filePath);
} }
var exists = false; var exists = false;
@@ -274,7 +280,7 @@ FocusScope {
nameFilters: fileExtensions nameFilters: fileExtensions
showFiles: true showFiles: true
showDirs: true showDirs: true
folder: currentPath ? "file://" + currentPath : "file://" + homeDir folder: encodeFileUrl(currentPath || homeDir)
sortField: { sortField: {
switch (sortBy) { switch (sortBy) {
case "name": case "name":

View File

@@ -21,67 +21,67 @@ StyledRect {
signal itemSelected(int index, string path, string name, bool isDir) signal itemSelected(int index, string path, string name, bool isDir)
function getFileExtension(fileName) { function getFileExtension(fileName) {
const parts = fileName.split('.') const parts = fileName.split('.');
if (parts.length > 1) { if (parts.length > 1) {
return parts[parts.length - 1].toLowerCase() return parts[parts.length - 1].toLowerCase();
} }
return "" return "";
} }
function determineFileType(fileName) { function determineFileType(fileName) {
const ext = getFileExtension(fileName) const ext = getFileExtension(fileName);
const imageExts = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "ico"] const imageExts = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "ico"];
if (imageExts.includes(ext)) { if (imageExts.includes(ext)) {
return "image" return "image";
} }
const videoExts = ["mp4", "mkv", "avi", "mov", "webm", "flv", "wmv", "m4v"] const videoExts = ["mp4", "mkv", "avi", "mov", "webm", "flv", "wmv", "m4v"];
if (videoExts.includes(ext)) { if (videoExts.includes(ext)) {
return "video" return "video";
} }
const audioExts = ["mp3", "wav", "flac", "ogg", "m4a", "aac", "wma"] const audioExts = ["mp3", "wav", "flac", "ogg", "m4a", "aac", "wma"];
if (audioExts.includes(ext)) { if (audioExts.includes(ext)) {
return "audio" return "audio";
} }
const codeExts = ["js", "ts", "jsx", "tsx", "py", "go", "rs", "c", "cpp", "h", "java", "kt", "swift", "rb", "php", "html", "css", "scss", "json", "xml", "yaml", "yml", "toml", "sh", "bash", "zsh", "fish", "qml", "vue", "svelte"] const codeExts = ["js", "ts", "jsx", "tsx", "py", "go", "rs", "c", "cpp", "h", "java", "kt", "swift", "rb", "php", "html", "css", "scss", "json", "xml", "yaml", "yml", "toml", "sh", "bash", "zsh", "fish", "qml", "vue", "svelte"];
if (codeExts.includes(ext)) { if (codeExts.includes(ext)) {
return "code" return "code";
} }
const docExts = ["txt", "md", "pdf", "doc", "docx", "odt", "rtf"] const docExts = ["txt", "md", "pdf", "doc", "docx", "odt", "rtf"];
if (docExts.includes(ext)) { if (docExts.includes(ext)) {
return "document" return "document";
} }
const archiveExts = ["zip", "tar", "gz", "bz2", "xz", "7z", "rar"] const archiveExts = ["zip", "tar", "gz", "bz2", "xz", "7z", "rar"];
if (archiveExts.includes(ext)) { if (archiveExts.includes(ext)) {
return "archive" return "archive";
} }
if (!ext || fileName.indexOf('.') === -1) { if (!ext || fileName.indexOf('.') === -1) {
return "binary" return "binary";
} }
return "file" return "file";
} }
function isImageFile(fileName) { function isImageFile(fileName) {
if (!fileName) { if (!fileName) {
return false return false;
} }
return determineFileType(fileName) === "image" return determineFileType(fileName) === "image";
} }
function getIconForFile(fileName) { function getIconForFile(fileName) {
const lowerName = fileName.toLowerCase() const lowerName = fileName.toLowerCase();
if (lowerName.startsWith("dockerfile")) { if (lowerName.startsWith("dockerfile")) {
return "docker" return "docker";
} }
const ext = fileName.split('.').pop() const ext = fileName.split('.').pop();
return ext || "" return ext || "";
} }
width: weMode ? 245 : iconSizes[iconSizeIndex] + 16 width: weMode ? 245 : iconSizes[iconSizeIndex] + 16
@@ -89,21 +89,21 @@ StyledRect {
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: { color: {
if (keyboardNavigationActive && delegateRoot.index === selectedIndex) if (keyboardNavigationActive && delegateRoot.index === selectedIndex)
return Theme.surfacePressed return Theme.surfacePressed;
return mouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent" return mouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent";
} }
border.color: keyboardNavigationActive && delegateRoot.index === selectedIndex ? Theme.primary : "transparent" border.color: keyboardNavigationActive && delegateRoot.index === selectedIndex ? Theme.primary : "transparent"
border.width: (keyboardNavigationActive && delegateRoot.index === selectedIndex) ? 2 : 0 border.width: (keyboardNavigationActive && delegateRoot.index === selectedIndex) ? 2 : 0
Component.onCompleted: { Component.onCompleted: {
if (keyboardNavigationActive && delegateRoot.index === selectedIndex) if (keyboardNavigationActive && delegateRoot.index === selectedIndex)
itemSelected(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir) itemSelected(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir);
} }
onSelectedIndexChanged: { onSelectedIndexChanged: {
if (keyboardNavigationActive && selectedIndex === delegateRoot.index) if (keyboardNavigationActive && selectedIndex === delegateRoot.index)
itemSelected(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir) itemSelected(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir);
} }
Column { Column {
@@ -121,19 +121,17 @@ StyledRect {
anchors.margins: 2 anchors.margins: 2
property var weExtensions: [".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp", ".tga"] property var weExtensions: [".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp", ".tga"]
property int weExtIndex: 0 property int weExtIndex: 0
source: { imagePath: {
if (weMode && delegateRoot.fileIsDir) { if (weMode && delegateRoot.fileIsDir)
return "file://" + delegateRoot.filePath + "/preview" + weExtensions[weExtIndex] return delegateRoot.filePath + "/preview" + weExtensions[weExtIndex];
} return (!delegateRoot.fileIsDir && isImageFile(delegateRoot.fileName)) ? delegateRoot.filePath : "";
return (!delegateRoot.fileIsDir && isImageFile(delegateRoot.fileName)) ? ("file://" + delegateRoot.filePath) : ""
} }
onStatusChanged: { onStatusChanged: {
if (weMode && delegateRoot.fileIsDir && status === Image.Error) { if (weMode && delegateRoot.fileIsDir && status === Image.Error) {
if (weExtIndex < weExtensions.length - 1) { if (weExtIndex < weExtensions.length - 1) {
weExtIndex++ weExtIndex++;
source = "file://" + delegateRoot.filePath + "/preview" + weExtensions[weExtIndex]
} else { } else {
source = "" imagePath = "";
} }
} }
} }
@@ -198,7 +196,7 @@ StyledRect {
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
itemClicked(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir) itemClicked(delegateRoot.index, delegateRoot.filePath, delegateRoot.fileName, delegateRoot.fileIsDir);
} }
} }
} }

View File

@@ -20,97 +20,97 @@ StyledRect {
signal itemSelected(int index, string path, string name, bool isDir) signal itemSelected(int index, string path, string name, bool isDir)
function getFileExtension(fileName) { function getFileExtension(fileName) {
const parts = fileName.split('.') const parts = fileName.split('.');
if (parts.length > 1) { if (parts.length > 1) {
return parts[parts.length - 1].toLowerCase() return parts[parts.length - 1].toLowerCase();
} }
return "" return "";
} }
function determineFileType(fileName) { function determineFileType(fileName) {
const ext = getFileExtension(fileName) const ext = getFileExtension(fileName);
const imageExts = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "ico"] const imageExts = ["png", "jpg", "jpeg", "gif", "bmp", "webp", "svg", "ico"];
if (imageExts.includes(ext)) { if (imageExts.includes(ext)) {
return "image" return "image";
} }
const videoExts = ["mp4", "mkv", "avi", "mov", "webm", "flv", "wmv", "m4v"] const videoExts = ["mp4", "mkv", "avi", "mov", "webm", "flv", "wmv", "m4v"];
if (videoExts.includes(ext)) { if (videoExts.includes(ext)) {
return "video" return "video";
} }
const audioExts = ["mp3", "wav", "flac", "ogg", "m4a", "aac", "wma"] const audioExts = ["mp3", "wav", "flac", "ogg", "m4a", "aac", "wma"];
if (audioExts.includes(ext)) { if (audioExts.includes(ext)) {
return "audio" return "audio";
} }
const codeExts = ["js", "ts", "jsx", "tsx", "py", "go", "rs", "c", "cpp", "h", "java", "kt", "swift", "rb", "php", "html", "css", "scss", "json", "xml", "yaml", "yml", "toml", "sh", "bash", "zsh", "fish", "qml", "vue", "svelte"] const codeExts = ["js", "ts", "jsx", "tsx", "py", "go", "rs", "c", "cpp", "h", "java", "kt", "swift", "rb", "php", "html", "css", "scss", "json", "xml", "yaml", "yml", "toml", "sh", "bash", "zsh", "fish", "qml", "vue", "svelte"];
if (codeExts.includes(ext)) { if (codeExts.includes(ext)) {
return "code" return "code";
} }
const docExts = ["txt", "md", "pdf", "doc", "docx", "odt", "rtf"] const docExts = ["txt", "md", "pdf", "doc", "docx", "odt", "rtf"];
if (docExts.includes(ext)) { if (docExts.includes(ext)) {
return "document" return "document";
} }
const archiveExts = ["zip", "tar", "gz", "bz2", "xz", "7z", "rar"] const archiveExts = ["zip", "tar", "gz", "bz2", "xz", "7z", "rar"];
if (archiveExts.includes(ext)) { if (archiveExts.includes(ext)) {
return "archive" return "archive";
} }
if (!ext || fileName.indexOf('.') === -1) { if (!ext || fileName.indexOf('.') === -1) {
return "binary" return "binary";
} }
return "file" return "file";
} }
function isImageFile(fileName) { function isImageFile(fileName) {
if (!fileName) { if (!fileName) {
return false return false;
} }
return determineFileType(fileName) === "image" return determineFileType(fileName) === "image";
} }
function getIconForFile(fileName) { function getIconForFile(fileName) {
const lowerName = fileName.toLowerCase() const lowerName = fileName.toLowerCase();
if (lowerName.startsWith("dockerfile")) { if (lowerName.startsWith("dockerfile")) {
return "docker" return "docker";
} }
const ext = fileName.split('.').pop() const ext = fileName.split('.').pop();
return ext || "" return ext || "";
} }
function formatFileSize(size) { function formatFileSize(size) {
if (size < 1024) if (size < 1024)
return size + " B" return size + " B";
if (size < 1024 * 1024) if (size < 1024 * 1024)
return (size / 1024).toFixed(1) + " KB" return (size / 1024).toFixed(1) + " KB";
if (size < 1024 * 1024 * 1024) if (size < 1024 * 1024 * 1024)
return (size / (1024 * 1024)).toFixed(1) + " MB" return (size / (1024 * 1024)).toFixed(1) + " MB";
return (size / (1024 * 1024 * 1024)).toFixed(1) + " GB" return (size / (1024 * 1024 * 1024)).toFixed(1) + " GB";
} }
height: 44 height: 44
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: { color: {
if (keyboardNavigationActive && listDelegateRoot.index === selectedIndex) if (keyboardNavigationActive && listDelegateRoot.index === selectedIndex)
return Theme.surfacePressed return Theme.surfacePressed;
return listMouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent" return listMouseArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent";
} }
border.color: keyboardNavigationActive && listDelegateRoot.index === selectedIndex ? Theme.primary : "transparent" border.color: keyboardNavigationActive && listDelegateRoot.index === selectedIndex ? Theme.primary : "transparent"
border.width: (keyboardNavigationActive && listDelegateRoot.index === selectedIndex) ? 2 : 0 border.width: (keyboardNavigationActive && listDelegateRoot.index === selectedIndex) ? 2 : 0
Component.onCompleted: { Component.onCompleted: {
if (keyboardNavigationActive && listDelegateRoot.index === selectedIndex) if (keyboardNavigationActive && listDelegateRoot.index === selectedIndex)
itemSelected(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir) itemSelected(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir);
} }
onSelectedIndexChanged: { onSelectedIndexChanged: {
if (keyboardNavigationActive && selectedIndex === listDelegateRoot.index) if (keyboardNavigationActive && selectedIndex === listDelegateRoot.index)
itemSelected(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir) itemSelected(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir);
} }
Row { Row {
@@ -127,7 +127,7 @@ StyledRect {
CachingImage { CachingImage {
id: listPreviewImage id: listPreviewImage
anchors.fill: parent anchors.fill: parent
source: (!listDelegateRoot.fileIsDir && isImageFile(listDelegateRoot.fileName)) ? ("file://" + listDelegateRoot.filePath) : "" imagePath: (!listDelegateRoot.fileIsDir && isImageFile(listDelegateRoot.fileName)) ? listDelegateRoot.filePath : ""
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
maxCacheSize: 32 maxCacheSize: 32
visible: false visible: false
@@ -203,7 +203,7 @@ StyledRect {
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
itemClicked(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir) itemClicked(listDelegateRoot.index, listDelegateRoot.filePath, listDelegateRoot.fileName, listDelegateRoot.fileIsDir);
} }
} }
} }

View File

@@ -40,6 +40,12 @@ Variants {
id: root id: root
anchors.fill: parent anchors.fill: parent
function encodeFileUrl(path) {
if (!path)
return "";
return "file://" + path.split('/').map(s => encodeURIComponent(s)).join('/');
}
property string source: SessionData.getMonitorWallpaper(modelData.name) || "" property string source: SessionData.getMonitorWallpaper(modelData.name) || ""
property bool isColorSource: source.startsWith("#") property bool isColorSource: source.startsWith("#")
@@ -83,7 +89,7 @@ Variants {
isInitialized = true; isInitialized = true;
return; return;
} }
const formattedSource = source.startsWith("file://") ? source : "file://" + source; const formattedSource = source.startsWith("file://") ? source : encodeFileUrl(source);
setWallpaperImmediate(formattedSource); setWallpaperImmediate(formattedSource);
isInitialized = true; isInitialized = true;
} }
@@ -100,7 +106,7 @@ Variants {
return; return;
} }
const formattedSource = source.startsWith("file://") ? source : "file://" + source; const formattedSource = source.startsWith("file://") ? source : encodeFileUrl(source);
if (!isInitialized || !currentWallpaper.source) { if (!isInitialized || !currentWallpaper.source) {
setWallpaperImmediate(formattedSource); setWallpaperImmediate(formattedSource);

View File

@@ -1,7 +1,6 @@
import Qt.labs.folderlistmodel import Qt.labs.folderlistmodel
import QtCore import QtCore
import QtQuick import QtQuick
import QtQuick.Controls
import QtQuick.Effects import QtQuick.Effects
import qs.Common import qs.Common
import qs.Modals.FileBrowser import qs.Modals.FileBrowser
@@ -311,7 +310,7 @@ Item {
showFiles: true showFiles: true
showDirs: false showDirs: false
sortField: FolderListModel.Name sortField: FolderListModel.Name
folder: wallpaperDir ? "file://" + wallpaperDir : "" folder: wallpaperDir ? "file://" + wallpaperDir.split('/').map(s => encodeURIComponent(s)).join('/') : ""
} }
FileBrowserSurfaceModal { FileBrowserSurfaceModal {
@@ -401,7 +400,9 @@ Item {
currentIndex = clampedIndex; currentIndex = clampedIndex;
positionViewAtIndex(clampedIndex, GridView.Contain); positionViewAtIndex(clampedIndex, GridView.Contain);
} }
Qt.callLater(() => { enableAnimation = true; }); Qt.callLater(() => {
enableAnimation = true;
});
} }
Connections { Connections {

View File

@@ -15,6 +15,12 @@ import qs.Modules.Lock
Item { Item {
id: root id: root
function encodeFileUrl(path) {
if (!path)
return "";
return "file://" + path.split('/').map(s => encodeURIComponent(s)).join('/');
}
readonly property string xdgDataDirs: Quickshell.env("XDG_DATA_DIRS") readonly property string xdgDataDirs: Quickshell.env("XDG_DATA_DIRS")
property string screenName: "" property string screenName: ""
property string randomFact: "" property string randomFact: ""
@@ -162,7 +168,7 @@ Item {
var _ = SessionData.perMonitorWallpaper; var _ = SessionData.perMonitorWallpaper;
var __ = SessionData.monitorWallpapers; var __ = SessionData.monitorWallpapers;
var currentWallpaper = SessionData.getMonitorWallpaper(screenName); var currentWallpaper = SessionData.getMonitorWallpaper(screenName);
return (currentWallpaper && !currentWallpaper.startsWith("#")) ? currentWallpaper : ""; return (currentWallpaper && !currentWallpaper.startsWith("#")) ? encodeFileUrl(currentWallpaper) : "";
} }
fillMode: Theme.getFillMode(GreetdSettings.wallpaperFillMode) fillMode: Theme.getFillMode(GreetdSettings.wallpaperFillMode)
smooth: true smooth: true
@@ -356,14 +362,10 @@ Item {
Layout.preferredWidth: 60 Layout.preferredWidth: 60
Layout.preferredHeight: 60 Layout.preferredHeight: 60
imageSource: { imageSource: {
if (PortalService.profileImage === "") { if (PortalService.profileImage === "")
return ""; return "";
} if (PortalService.profileImage.startsWith("/"))
return encodeFileUrl(PortalService.profileImage);
if (PortalService.profileImage.startsWith("/")) {
return "file://" + PortalService.profileImage;
}
return PortalService.profileImage; return PortalService.profileImage;
} }
fallbackIcon: "person" fallbackIcon: "person"
@@ -1154,7 +1156,7 @@ Item {
required property string modelData required property string modelData
FolderListModel { FolderListModel {
folder: "file://" + modelData folder: encodeFileUrl(modelData)
nameFilters: ["*.desktop"] nameFilters: ["*.desktop"]
showDirs: false showDirs: false
showDotAndDotDot: false showDotAndDotDot: false

View File

@@ -14,6 +14,12 @@ import qs.Widgets
Item { Item {
id: root id: root
function encodeFileUrl(path) {
if (!path)
return "";
return "file://" + path.split('/').map(s => encodeURIComponent(s)).join('/');
}
property string passwordBuffer: "" property string passwordBuffer: ""
property bool demoMode: false property bool demoMode: false
property string screenName: "" property string screenName: ""
@@ -170,7 +176,7 @@ Item {
anchors.fill: parent anchors.fill: parent
source: { source: {
var currentWallpaper = SessionData.getMonitorWallpaper(screenName); var currentWallpaper = SessionData.getMonitorWallpaper(screenName);
return (currentWallpaper && !currentWallpaper.startsWith("#")) ? currentWallpaper : ""; return (currentWallpaper && !currentWallpaper.startsWith("#")) ? encodeFileUrl(currentWallpaper) : "";
} }
fillMode: Theme.getFillMode(SettingsData.wallpaperFillMode) fillMode: Theme.getFillMode(SettingsData.wallpaperFillMode)
smooth: true smooth: true
@@ -659,14 +665,10 @@ Item {
Layout.preferredWidth: 60 Layout.preferredWidth: 60
Layout.preferredHeight: 60 Layout.preferredHeight: 60
imageSource: { imageSource: {
if (PortalService.profileImage === "") { if (PortalService.profileImage === "")
return ""; return "";
} if (PortalService.profileImage.startsWith("/"))
return encodeFileUrl(PortalService.profileImage);
if (PortalService.profileImage.startsWith("/")) {
return "file://" + PortalService.profileImage;
}
return PortalService.profileImage; return PortalService.profileImage;
} }
fallbackIcon: "person" fallbackIcon: "person"

View File

@@ -389,7 +389,7 @@ Item {
CachingImage { CachingImage {
anchors.fill: parent anchors.fill: parent
anchors.margins: 1 anchors.margins: 1
source: Theme.wallpaperPath ? "file://" + Theme.wallpaperPath : "" imagePath: (Theme.wallpaperPath && !Theme.wallpaperPath.startsWith("#")) ? Theme.wallpaperPath : ""
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
visible: Theme.wallpaperPath && !Theme.wallpaperPath.startsWith("#") visible: Theme.wallpaperPath && !Theme.wallpaperPath.startsWith("#")
layer.enabled: true layer.enabled: true

View File

@@ -55,9 +55,9 @@ Item {
CachingImage { CachingImage {
anchors.fill: parent anchors.fill: parent
anchors.margins: 1 anchors.margins: 1
source: { imagePath: {
var currentWallpaper = SessionData.perMonitorWallpaper ? SessionData.getMonitorWallpaper(selectedMonitorName) : SessionData.wallpaperPath; var currentWallpaper = SessionData.perMonitorWallpaper ? SessionData.getMonitorWallpaper(selectedMonitorName) : SessionData.wallpaperPath;
return (currentWallpaper !== "" && !currentWallpaper.startsWith("#")) ? "file://" + currentWallpaper : ""; return (currentWallpaper !== "" && !currentWallpaper.startsWith("#")) ? currentWallpaper : "";
} }
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
visible: { visible: {
@@ -391,9 +391,9 @@ Item {
CachingImage { CachingImage {
anchors.fill: parent anchors.fill: parent
anchors.margins: 1 anchors.margins: 1
source: { imagePath: {
var lightWallpaper = SessionData.wallpaperPathLight; var lightWallpaper = SessionData.wallpaperPathLight;
return (lightWallpaper !== "" && !lightWallpaper.startsWith("#")) ? "file://" + lightWallpaper : ""; return (lightWallpaper !== "" && !lightWallpaper.startsWith("#")) ? lightWallpaper : "";
} }
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
visible: { visible: {
@@ -575,9 +575,9 @@ Item {
CachingImage { CachingImage {
anchors.fill: parent anchors.fill: parent
anchors.margins: 1 anchors.margins: 1
source: { imagePath: {
var darkWallpaper = SessionData.wallpaperPathDark; var darkWallpaper = SessionData.wallpaperPathDark;
return (darkWallpaper !== "" && !darkWallpaper.startsWith("#")) ? "file://" + darkWallpaper : ""; return (darkWallpaper !== "" && !darkWallpaper.startsWith("#")) ? darkWallpaper : "";
} }
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
visible: { visible: {
@@ -968,17 +968,9 @@ Item {
SettingsDropdownRow { SettingsDropdownRow {
id: intervalDropdown id: intervalDropdown
property var intervalOptions: [ property var intervalOptions: ["5 seconds", "10 seconds", "15 seconds", "20 seconds", "25 seconds", "30 seconds", "35 seconds", "40 seconds", "45 seconds", "50 seconds", "55 seconds", "1 minute", "5 minutes", "15 minutes", "30 minutes", "1 hour", "1.5 hours", "2 hours", "3 hours", "4 hours", "6 hours", "8 hours", "12 hours"]
"5 seconds", "10 seconds", "15 seconds", "20 seconds", "25 seconds", "30 seconds",
"35 seconds", "40 seconds", "45 seconds", "50 seconds", "55 seconds",
"1 minute", "5 minutes", "15 minutes", "30 minutes", "1 hour", "1.5 hours", "2 hours",
"3 hours", "4 hours", "6 hours", "8 hours", "12 hours"
]
property var intervalValues: [ property var intervalValues: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 300, 900, 1800, 3600, 5400, 7200, 10800, 14400, 21600, 28800, 43200]
5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60,
300, 900, 1800, 3600, 5400, 7200, 10800, 14400, 21600, 28800, 43200
]
tab: "wallpaper" tab: "wallpaper"
tags: ["interval", "cycling", "time", "frequency"] tags: ["interval", "cycling", "time", "frequency"]
settingKey: "wallpaperCyclingInterval" settingKey: "wallpaperCyclingInterval"

View File

@@ -39,6 +39,12 @@ Variants {
id: root id: root
anchors.fill: parent anchors.fill: parent
function encodeFileUrl(path) {
if (!path)
return "";
return "file://" + path.split('/').map(s => encodeURIComponent(s)).join('/');
}
property string source: SessionData.getMonitorWallpaper(modelData.name) || "" property string source: SessionData.getMonitorWallpaper(modelData.name) || ""
property bool isColorSource: source.startsWith("#") property bool isColorSource: source.startsWith("#")
property string transitionType: SessionData.wallpaperTransition property string transitionType: SessionData.wallpaperTransition
@@ -108,7 +114,7 @@ Variants {
isInitialized = true; isInitialized = true;
return; return;
} }
const formattedSource = source.startsWith("file://") ? source : "file://" + source; const formattedSource = source.startsWith("file://") ? source : encodeFileUrl(source);
setWallpaperImmediate(formattedSource); setWallpaperImmediate(formattedSource);
isInitialized = true; isInitialized = true;
} }
@@ -119,7 +125,7 @@ Variants {
return; return;
} }
const formattedSource = source.startsWith("file://") ? source : "file://" + source; const formattedSource = source.startsWith("file://") ? source : encodeFileUrl(source);
if (!isInitialized || !currentWallpaper.source) { if (!isInitialized || !currentWallpaper.source) {
setWallpaperImmediate(formattedSource); setWallpaperImmediate(formattedSource);

View File

@@ -20,6 +20,7 @@ Image {
readonly property string imageHash: imagePath ? djb2Hash(imagePath) : "" readonly property string imageHash: imagePath ? djb2Hash(imagePath) : ""
readonly property string cachePath: imageHash ? `${Paths.stringify(Paths.imagecache)}/${imageHash}@${maxCacheSize}x${maxCacheSize}.png` : "" readonly property string cachePath: imageHash ? `${Paths.stringify(Paths.imagecache)}/${imageHash}@${maxCacheSize}x${maxCacheSize}.png` : ""
readonly property string encodedImagePath: imagePath ? "file://" + imagePath.split('/').map(s => encodeURIComponent(s)).join('/') : ""
asynchronous: true asynchronous: true
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
@@ -33,15 +34,15 @@ Image {
return; return;
} }
Paths.mkdir(Paths.imagecache); Paths.mkdir(Paths.imagecache);
source = cachePath || imagePath; source = cachePath || encodedImagePath;
} }
onStatusChanged: { onStatusChanged: {
if (source == cachePath && status === Image.Error) { if (source == cachePath && status === Image.Error) {
source = imagePath; source = encodedImagePath;
return; return;
} }
if (source != imagePath || status !== Image.Ready || !cachePath) if (source != encodedImagePath || status !== Image.Ready || !cachePath)
return; return;
Paths.mkdir(Paths.imagecache); Paths.mkdir(Paths.imagecache);
const grabPath = cachePath; const grabPath = cachePath;