From 1193b7a80223b7a7e9822a4b10c82b4ea2afc197 Mon Sep 17 00:00:00 2001 From: EoinKanro <54404008+EoinKanro@users.noreply.github.com> Date: Thu, 4 Dec 2025 22:30:55 +0100 Subject: [PATCH] Rework parallax --- .../quickshell/ii/modules/common/Config.qml | 2 +- .../ii/modules/ii/background/Background.qml | 114 ++++++++++-------- .../ii/modules/settings/BackgroundConfig.qml | 4 +- 3 files changed, 68 insertions(+), 52 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index b0b767a44..121f78741 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -208,7 +208,7 @@ Singleton { property bool vertical: false property bool autoVertical: false property bool enableWorkspace: true - property real workspaceZoom: 1.07 // Relative to your screen, not wallpaper size + property real workspaceZoom: 1.0 // Relative to wallpaper size property bool enableSidebar: true property real widgetsFactor: 1.2 } diff --git a/dots/.config/quickshell/ii/modules/ii/background/Background.qml b/dots/.config/quickshell/ii/modules/ii/background/Background.qml index 68d8b1698..f9ffe54d2 100644 --- a/dots/.config/quickshell/ii/modules/ii/background/Background.qml +++ b/dots/.config/quickshell/ii/modules/ii/background/Background.qml @@ -37,6 +37,7 @@ Variants { property list relevantWindows: HyprlandData.windowList.filter(win => win.monitor == monitor?.id && win.workspace.id >= 0).sort((a, b) => a.workspace.id - b.workspace.id) property int firstWorkspaceId: relevantWindows[0]?.workspace.id || 1 property int lastWorkspaceId: relevantWindows[relevantWindows.length - 1]?.workspace.id || 10 + property int totalWorkspaces: Config?.options.bar.workspaces.shown ?? 10 // Wallpaper property bool wallpaperIsVideo: Config.options.background.wallpaperPath.endsWith(".mp4") || Config.options.background.wallpaperPath.endsWith(".webm") || Config.options.background.wallpaperPath.endsWith(".mkv") || Config.options.background.wallpaperPath.endsWith(".avi") || Config.options.background.wallpaperPath.endsWith(".mov") property string wallpaperPath: wallpaperIsVideo ? Config.options.background.thumbnailPath : Config.options.background.wallpaperPath @@ -46,13 +47,15 @@ Variants { const sensitiveNetwork = (CF.StringUtils.stringListContainsSubstring(Network.networkName.toLowerCase(), Config.options.workSafety.triggerCondition.networkNameKeywords)); return enabled && sensitiveWallpaper && sensitiveNetwork; } - property real wallpaperToScreenRatio: Math.min(wallpaperWidth / screen.width, wallpaperHeight / screen.height) - property real preferredWallpaperScale: Config.options.background.parallax.workspaceZoom + property real parallaxRation: 1.2 + property real additionalScaleFactor: Config.options.background.parallax.workspaceZoom property real effectiveWallpaperScale: 1 // Some reasonable init value, to be updated property int wallpaperWidth: modelData.width // Some reasonable init value, to be updated property int wallpaperHeight: modelData.height // Some reasonable init value, to be updated - property real movableXSpace: ((wallpaperWidth / wallpaperToScreenRatio * effectiveWallpaperScale) - screen.width) / 2 - property real movableYSpace: ((wallpaperHeight / wallpaperToScreenRatio * effectiveWallpaperScale) - screen.height) / 2 + property real scaledWallpaperWidth: wallpaperWidth * effectiveWallpaperScale + property real scaledWallpaperHeight: wallpaperHeight * effectiveWallpaperScale + property real parallaxTotalPixelsX: Math.max(screen.width - scaledWallpaperWidth, scaledWallpaperWidth - screen.width) + property real parallaxTotalPixelsY: Math.max(screen.height - scaledWallpaperHeight, scaledWallpaperHeight - screen.height) readonly property bool verticalParallax: (Config.options.background.parallax.autoVertical && wallpaperHeight > wallpaperWidth) || Config.options.background.parallax.vertical // Colors property bool shouldBlur: (GlobalStates.screenLocked && Config.options.lock.blur.enable) @@ -111,13 +114,13 @@ Variants { bgRoot.wallpaperWidth = width; bgRoot.wallpaperHeight = height; - if (width <= screenWidth || height <= screenHeight) { - // Undersized/perfectly sized wallpapers - bgRoot.effectiveWallpaperScale = Math.max(screenWidth / width, screenHeight / height); - } else { - // Oversized = can be zoomed for parallax, yay - bgRoot.effectiveWallpaperScale = Math.min(bgRoot.preferredWallpaperScale, width / screenWidth, height / screenHeight); - } + // Perfect image; scale = 1 + // Small picture; scale > 1; will zoom in the picture + // Big picture; scale < 1; will zoom out the picture + // Choose max number so every side will fit + const minSuitableScale = Math.max(screenWidth / width, screenHeight / height); + //todo switch off parallax + bgRoot.effectiveWallpaperScale = minSuitableScale * bgRoot.additionalScaleFactor * bgRoot.parallaxRation; } } } @@ -133,32 +136,49 @@ Variants { opacity: (status === Image.Ready && !bgRoot.wallpaperIsVideo) ? 1 : 0 cache: false smooth: false - // Range = groups that workspaces span on - property int chunkSize: Config?.options.bar.workspaces.shown ?? 10 - property int lower: Math.floor(bgRoot.firstWorkspaceId / chunkSize) * chunkSize - property int upper: Math.ceil(bgRoot.lastWorkspaceId / chunkSize) * chunkSize - property int range: upper - lower - property real valueX: { - let result = 0.5; + + property int workspaceIndex: (bgRoot.monitor.activeWorkspace?.id ?? 1) - 1 + property real middleFraction: 0.5 + property real fraction: { + // 0 - start of the picture + // 1 - end of the picture + if (bgRoot.totalWorkspaces <= 1) { + return middleFraction; + } + return Math.max(0, Math.min(1, workspaceIndex / (bgRoot.totalWorkspaces - 1))); + } + + x: { + if (bgRoot.screen.width > bgRoot.scaledWallpaperWidth) { + // Center the picture + return bgRoot.parallaxTotalPixelsX / 2; + } + + let usedFraction = middleFraction; if (Config.options.background.parallax.enableWorkspace && !bgRoot.verticalParallax) { - result = ((bgRoot.monitor.activeWorkspace?.id - lower) / range); + usedFraction = fraction; } if (Config.options.background.parallax.enableSidebar) { - result += (0.15 * GlobalStates.sidebarRightOpen - 0.15 * GlobalStates.sidebarLeftOpen); + let sidebarFraction = bgRoot.parallaxRation / 10; + usedFraction += (sidebarFraction * GlobalStates.sidebarRightOpen - sidebarFraction * GlobalStates.sidebarLeftOpen); } - return result; + usedFraction = Math.max(0, Math.min(1, usedFraction)); + return - bgRoot.parallaxTotalPixelsX * usedFraction; } - property real valueY: { - let result = 0.5; + y: { + if (bgRoot.screen.height > bgRoot.scaledWallpaperHeight) { + // Center the picture + return bgRoot.parallaxTotalPixelsY / 2; + } + + let usedFraction = middleFraction; if (Config.options.background.parallax.enableWorkspace && bgRoot.verticalParallax) { - result = ((bgRoot.monitor.activeWorkspace?.id - lower) / range); + usedFraction = fraction; } - return result; + usedFraction = Math.max(0, Math.min(1, usedFraction)); + return - bgRoot.parallaxTotalPixelsY * usedFraction; } - property real effectiveValueX: Math.max(0, Math.min(1, valueX)) - property real effectiveValueY: Math.max(0, Math.min(1, valueY)) - x: -(bgRoot.movableXSpace) - (effectiveValueX - 0.5) * 2 * bgRoot.movableXSpace - y: -(bgRoot.movableYSpace) - (effectiveValueY - 0.5) * 2 * bgRoot.movableYSpace + source: bgRoot.wallpaperSafetyTriggered ? "" : bgRoot.wallpaperPath fillMode: Image.PreserveAspectCrop Behavior on x { @@ -174,11 +194,11 @@ Variants { } } sourceSize { - width: bgRoot.screen.width * bgRoot.effectiveWallpaperScale * bgRoot.monitor.scale - height: bgRoot.screen.height * bgRoot.effectiveWallpaperScale * bgRoot.monitor.scale + width: bgRoot.scaledWallpaperWidth + height: bgRoot.scaledWallpaperHeight } - width: bgRoot.wallpaperWidth / bgRoot.wallpaperToScreenRatio * bgRoot.effectiveWallpaperScale - height: bgRoot.wallpaperHeight / bgRoot.wallpaperToScreenRatio * bgRoot.effectiveWallpaperScale + width: bgRoot.scaledWallpaperWidth + height: bgRoot.scaledWallpaperHeight } Loader { @@ -210,22 +230,18 @@ Variants { WidgetCanvas { id: widgetCanvas anchors { - left: wallpaper.left - right: wallpaper.right - top: wallpaper.top - bottom: wallpaper.bottom + left: bgRoot.screen.left + right: bgRoot.screen.right + top: bgRoot.screen.top + bottom: bgRoot.screen.bottom horizontalCenter: undefined verticalCenter: undefined readonly property real parallaxFactor: Config.options.background.parallax.widgetsFactor leftMargin: { - const xOnWallpaper = bgRoot.movableXSpace; - const extraMove = (wallpaper.effectiveValueX * 2 * bgRoot.movableXSpace) * (parallaxFactor - 1); - return xOnWallpaper - extraMove; + return bgRoot.screen.width * 0.2; } topMargin: { - const yOnWallpaper = bgRoot.movableYSpace; - const extraMove = (wallpaper.effectiveValueY * 2 * bgRoot.movableYSpace) * (parallaxFactor - 1); - return yOnWallpaper - extraMove; + return bgRoot.screen.height * 0.2; } Behavior on leftMargin { animation: Appearance.animation.elementMove.numberAnimation.createObject(this) @@ -275,9 +291,9 @@ Variants { sourceComponent: WeatherWidget { screenWidth: bgRoot.screen.width screenHeight: bgRoot.screen.height - scaledScreenWidth: bgRoot.screen.width / bgRoot.effectiveWallpaperScale - scaledScreenHeight: bgRoot.screen.height / bgRoot.effectiveWallpaperScale - wallpaperScale: bgRoot.effectiveWallpaperScale + scaledScreenWidth: bgRoot.screen.width + scaledScreenHeight: bgRoot.screen.height + wallpaperScale: 1 } } @@ -286,9 +302,9 @@ Variants { sourceComponent: ClockWidget { screenWidth: bgRoot.screen.width screenHeight: bgRoot.screen.height - scaledScreenWidth: bgRoot.screen.width / bgRoot.effectiveWallpaperScale - scaledScreenHeight: bgRoot.screen.height / bgRoot.effectiveWallpaperScale - wallpaperScale: bgRoot.effectiveWallpaperScale + scaledScreenWidth: bgRoot.screen.width + scaledScreenHeight: bgRoot.screen.height + wallpaperScale: 1 wallpaperSafetyTriggered: bgRoot.wallpaperSafetyTriggered } } diff --git a/dots/.config/quickshell/ii/modules/settings/BackgroundConfig.qml b/dots/.config/quickshell/ii/modules/settings/BackgroundConfig.qml index 66630cc24..86debf5d7 100644 --- a/dots/.config/quickshell/ii/modules/settings/BackgroundConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/BackgroundConfig.qml @@ -43,8 +43,8 @@ ContentPage { icon: "loupe" text: Translation.tr("Preferred wallpaper zoom (%)") value: Config.options.background.parallax.workspaceZoom * 100 - from: 100 - to: 150 + from: 10 + to: 200 stepSize: 1 onValueChanged: { Config.options.background.parallax.workspaceZoom = value / 100;