diff --git a/Modules/Settings/Common/WallpaperCropper.qml b/Modules/Settings/Common/WallpaperCropper.qml index bd1e8b0..0b5b0d9 100644 --- a/Modules/Settings/Common/WallpaperCropper.qml +++ b/Modules/Settings/Common/WallpaperCropper.qml @@ -16,8 +16,20 @@ Item { readonly property var currentScreen: screens.length > selectedScreenIndex ? screens[selectedScreenIndex] : null readonly property real maxZoom: 5.0 + readonly property bool changesMade: { + cropRevision; + + const r = cropRectLoader.item; + if (!r || !currentScreen || scaledImg.status !== Image.Ready) + return false; + + const t = r.savedTarget(); + + return Math.abs(r.x - t.x) > 0.5 || Math.abs(r.y - t.y) > 0.5 || Math.abs(r.zoom - t.zoom) > 0.001; + } + + property int cropRevision: 0 property int buttonRowHeight: Tokens.padding.large * 3 - property bool changesMade: false property var screens: [] property int selectedScreenIndex: 0 property bool shouldBeActive: true @@ -42,6 +54,7 @@ Item { const cropHeightPercent = cropRect.height / cropRect.imageH; Wallpapers.setCrop(currentScreen.name, Qt.rect(cropXPercent, cropYPercent, cropWidthPercent, cropHeightPercent), cropRect.zoom); + cropRevision++; } function refreshScreens(): void { @@ -161,8 +174,6 @@ Item { onInteraction: value => { wrapper.zoomClipRect(wrapper.zoomFromSlider(value)); } - - onPosChanged: wrapper.changesMade = true } ButtonRow { @@ -181,7 +192,6 @@ Item { onClicked: { wrapper.syncCropToScreen(); - wrapper.changesMade = false; } } @@ -198,7 +208,6 @@ Item { onClicked: { wrapper.applyCrop(); - wrapper.changesMade = false; } } } @@ -318,19 +327,33 @@ Item { y = Math.max(imageY, Math.min(y, imageY + imageH - height)); } + // Where the rect should be according to saved data (same rules as a restore). + function savedTarget() { + const data = Wallpapers.getCrop(wrapper.currentScreen.name); + const hasCrop = data && (Math.abs(data.x) > 0.001 || Math.abs(data.y) > 0.001 || Math.abs(data.width - 1.0) > 0.001 || Math.abs(data.height - 1.0) > 0.001); + + const z = hasCrop && data.zoom > 0 ? data.zoom : 1.0; + const w = Math.round(baseWidth / z); + const h = Math.round(baseHeight / z); + + let tx = hasCrop ? Math.round(imageX + data.x * imageW) : Math.round(imageX + (imageW - w) / 2); + let ty = hasCrop ? Math.round(imageY + data.y * imageH) : Math.round(imageY + (imageH - h) / 2); + + tx = Math.max(imageX, Math.min(tx, imageX + imageW - w)); + ty = Math.max(imageY, Math.min(ty, imageY + imageH - h)); + + return { + x: tx, + y: ty, + zoom: z + }; + } + function restoreFromData() { - let data = Wallpapers.getCrop(wrapper.currentScreen.name); - - if (data && (Math.abs(data.x) > 0.001 || Math.abs(data.y) > 0.001 || Math.abs(data.width - 1.0) > 0.001 || Math.abs(data.height - 1.0) > 0.001)) { - zoom = data.zoom > 0 ? data.zoom : 1.0; - x = Math.round(imageX + (data.x * imageW)); - y = Math.round(imageY + (data.y * imageH)); - - clampToBounds(); - } else { - zoom = 1.0; - centerInImage(); - } + const t = savedTarget(); + zoom = t.zoom; + x = t.x; + y = t.y; } height: Math.round(baseHeight / zoom) @@ -424,7 +447,6 @@ Item { onPositionChanged: mouse => { if (pressed) { updateCrop(mouse.x, mouse.y); - wrapper.changesMade = true; } } onPressed: mouse => { diff --git a/shell.qml b/shell.qml index 60ec9ed..6df3f3a 100644 --- a/shell.qml +++ b/shell.qml @@ -3,7 +3,7 @@ // @ pragma DefaultEnv QSG_RHI_BACKEND=vulkan //@ pragma DefaultEnv QSG_NO_VSYNC=1 //@ pragma DefaultEnv QS_NO_RELOAD_POPUP=1 -// @ pragma DefaultEnv QT_SCALE_FACTOR_ROUNDING_POLICY=Round +//@ pragma DefaultEnv QT_SCALE_FACTOR_ROUNDING_POLICY=Round //@ pragma DefaultEnv QT_QUICK_FLICKABLE_WHEEL_DECELERATION=10000 //@ pragma DropExpensiveFonts import Quickshell