diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 2a9184bb3..60d61e72f 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -217,7 +217,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..b63ba8862 100644 --- a/dots/.config/quickshell/ii/modules/ii/background/Background.qml +++ b/dots/.config/quickshell/ii/modules/ii/background/Background.qml @@ -37,6 +37,8 @@ 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 workspaceChunkSize: Config?.options.bar.workspaces.shown ?? 10 + property int totalWorkspaces: Math.ceil(lastWorkspaceId / workspaceChunkSize) * workspaceChunkSize // 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 +48,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 + readonly property real parallaxRation: 1.1 + readonly 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(0, scaledWallpaperWidth - screen.width) + property real parallaxTotalPixelsY: Math.max(0, 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,20 +115,18 @@ 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); + bgRoot.effectiveWallpaperScale = minSuitableScale * bgRoot.additionalScaleFactor * bgRoot.parallaxRation; } } } Item { anchors.fill: parent - clip: true // Wallpaper StyledImage { @@ -133,32 +135,52 @@ 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))); + } + + property real usedFractionX: { + 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 / bgRoot.workspaceChunkSize / 2; + usedFraction += (sidebarFraction * GlobalStates.sidebarRightOpen - sidebarFraction * GlobalStates.sidebarLeftOpen); } - return result; + return Math.max(0, Math.min(1, usedFraction)); } - property real valueY: { - let result = 0.5; + property real usedFractionY: { + let usedFraction = middleFraction; if (Config.options.background.parallax.enableWorkspace && bgRoot.verticalParallax) { - result = ((bgRoot.monitor.activeWorkspace?.id - lower) / range); + usedFraction = fraction; } - return result; + return Math.max(0, Math.min(1, 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 + + x: { + if (bgRoot.screen.width > bgRoot.scaledWallpaperWidth) { + // Center the picture + return (bgRoot.screen.width - bgRoot.scaledWallpaperWidth) / 2; + } + return - bgRoot.parallaxTotalPixelsX * usedFractionX; + } + y: { + if (bgRoot.screen.height > bgRoot.scaledWallpaperHeight) { + // Center the picture + return (bgRoot.screen.height - bgRoot.scaledWallpaperHeight) / 2; + } + return - bgRoot.parallaxTotalPixelsY * usedFractionY; + } + source: bgRoot.wallpaperSafetyTriggered ? "" : bgRoot.wallpaperPath fillMode: Image.PreserveAspectCrop Behavior on x { @@ -174,11 +196,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 { @@ -209,53 +231,20 @@ Variants { WidgetCanvas { id: widgetCanvas - anchors { - left: wallpaper.left - right: wallpaper.right - top: wallpaper.top - bottom: wallpaper.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; - } - topMargin: { - const yOnWallpaper = bgRoot.movableYSpace; - const extraMove = (wallpaper.effectiveValueY * 2 * bgRoot.movableYSpace) * (parallaxFactor - 1); - return yOnWallpaper - extraMove; - } - Behavior on leftMargin { - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } - Behavior on topMargin { - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } - } - width: wallpaper.width - height: wallpaper.height - states: State { - name: "centered" - when: GlobalStates.screenLocked || bgRoot.wallpaperSafetyTriggered - PropertyChanges { - target: widgetCanvas - width: parent.width - height: parent.height - } - AnchorChanges { - target: widgetCanvas - anchors { - left: undefined - right: undefined - top: undefined - bottom: undefined - horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter - } - } + width: parent.width + height: parent.height + readonly property real parallaxFactor: { + var f = Config.options.background.parallax.widgetsFactor; + return f / Config.options.background.parallax.workspaceZoom; } + readonly property real baseWallpaperOffsetX: (bgRoot.screen.width - bgRoot.scaledWallpaperWidth) / 2 + readonly property real baseWallpaperOffsetY: (bgRoot.screen.height - bgRoot.scaledWallpaperHeight) / 2 + readonly property real wallpaperTotalOffsetX: wallpaper.x - baseWallpaperOffsetX + readonly property real wallpaperTotalOffsetY: wallpaper.y - baseWallpaperOffsetY + readonly property bool locked: GlobalStates.screenLocked + x: wallpaperTotalOffsetX * parallaxFactor * !locked + y: wallpaperTotalOffsetY * parallaxFactor * !locked + transitions: Transition { PropertyAnimation { properties: "width,height" @@ -275,9 +264,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 +275,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 78e0473a2..680421f03 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;