wonky fix for cropping rect desync
Lint & Format (JS/TS) / lint-format (pull_request) Successful in 14s
Python / lint-format (pull_request) Successful in 18s
Python / test (pull_request) Successful in 28s
Lint & Format (Rust) / lint-format (pull_request) Successful in 1m11s

This commit is contained in:
2026-06-24 20:21:36 +02:00
parent d08b2b7ac6
commit ecfa1115cd
4 changed files with 51 additions and 247 deletions
@@ -1,214 +0,0 @@
import QtQuick
import QtQuick.Layouts
import qs.Components
import qs.Config
import qs.Helpers
Item {
id: root
readonly property bool highlighted: SettingsHighlight.highlightedSetting === name
required property string name
required property var object
required property list<string> settings
property bool shouldBeActive: true
function commitChoice(choice: int, setting: string): void {
root.object[setting] = choice;
Config.save();
}
function formattedValue(setting: string): string {
const value = root.object[setting];
if (value === null || value === undefined)
return "";
return String(value);
}
function hourToAmPm(hour) {
var h = Number(hour) % 24;
var d = new Date(2000, 0, 1, h, 0, 0);
return Qt.formatTime(d, "h AP");
}
anchors.left: parent.left
anchors.right: parent.right
implicitHeight: shouldBeActive ? row.implicitHeight + Appearance.padding.smaller * 2 : 0
opacity: shouldBeActive ? 1 : 0
scale: shouldBeActive ? 1 : 0.8
visible: opacity > 0
Behavior on opacity {
Anim {
}
}
Behavior on scale {
Anim {
}
}
Behavior on y {
Anim {
}
}
Rectangle {
anchors.fill: parent
anchors.margins: -Appearance.padding.smaller
color: DynamicColors.palette.m3primaryContainer
opacity: root.highlighted ? 0.5 : 0
radius: Appearance.rounding.small
Behavior on opacity {
Anim {
duration: Appearance.anim.durations.normal
}
}
}
RowLayout {
id: row
anchors.left: parent.left
anchors.margins: Appearance.padding.small
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
CustomText {
id: text
Layout.alignment: Qt.AlignLeft
Layout.fillWidth: true
font.pointSize: Appearance.font.size.larger
text: root.name
}
CustomText {
Layout.alignment: Qt.AlignLeft
color: DynamicColors.palette.m3onSurfaceVariant
font.pointSize: Appearance.font.size.normal
text: qsTr("Hyprsunset will turn on at %1, and turn off at %2.").arg(root.hourToAmPm(root.object[root.settings[0]])).arg(root.hourToAmPm(root.object[root.settings[1]]))
}
}
ColumnLayout {
id: optionLayout
Layout.fillHeight: true
Layout.preferredWidth: 100
RowLayout {
Layout.preferredWidth: optionLayout.width
CustomText {
Layout.alignment: Qt.AlignLeft | Qt.AlignHCenter
Layout.fillWidth: true
text: qsTr("Enabled: ")
}
CustomSwitch {
id: enabledSwitch
Layout.alignment: Qt.AlignRight | Qt.AlignHCenter
checked: root.object[root.settings[2]]
onToggled: {
root.object[root.settings[2]] = checked;
Config.save();
}
}
}
RowLayout {
Layout.preferredWidth: optionLayout.width
z: setting2.expanded ? -1 : 1
CustomText {
Layout.alignment: Qt.AlignLeft | Qt.AlignHCenter
Layout.fillWidth: true
text: qsTr("Start: ")
}
SpinnerButton {
id: setting1
Layout.alignment: Qt.AlignRight | Qt.AlignHCenter
Layout.preferredHeight: Appearance.font.size.large + Appearance.padding.smaller * 2
Layout.preferredWidth: height * 2
currentIndex: root.object[root.settings[0]]
enabled: enabledSwitch.checked
text: root.formattedValue(root.settings[0])
menu.onItemSelected: item => {
root.commitChoice(item, root.settings[0]);
}
}
}
RowLayout {
Layout.preferredWidth: optionLayout.width
z: setting1.expanded ? -1 : 1
CustomText {
Layout.alignment: Qt.AlignLeft | Qt.AlignHCenter
Layout.fillWidth: true
text: qsTr("End: ")
}
SpinnerButton {
id: setting2
Layout.alignment: Qt.AlignRight | Qt.AlignHCenter
Layout.preferredHeight: Appearance.font.size.large + Appearance.padding.smaller * 2
Layout.preferredWidth: height * 2
currentIndex: root.object[root.settings[1]]
enabled: enabledSwitch.checked
text: root.formattedValue(root.settings[1])
menu.onItemSelected: item => {
root.commitChoice(item, root.settings[1]);
}
}
}
RowLayout {
Layout.preferredWidth: optionLayout.width
z: -2
CustomText {
Layout.alignment: Qt.AlignLeft | Qt.AlignHCenter
Layout.fillWidth: true
text: qsTr("Temp: ")
}
CustomRect {
id: rect
Layout.preferredHeight: 33
Layout.preferredWidth: Math.max(Math.min(textField.contentWidth + Appearance.padding.normal * 2, 200), 50)
color: DynamicColors.tPalette.m3surfaceContainerHigh
radius: Appearance.rounding.full
CustomTextField {
id: textField
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
implicitWidth: Math.min(contentWidth + Appearance.padding.normal * 2, 200)
text: root.formattedValue(root.settings[3])
onEditingFinished: {
root.object[root.settings[3]] = textField.text;
Config.save();
}
}
}
}
}
}
}
-10
View File
@@ -8,19 +8,9 @@ import qs.Helpers
CustomClippingRect {
id: root
readonly property string endTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(object[settings[2]]);
return Qt.formatTime(d, "hh:mm AP");
}
required property var object
required property list<string> settings
property bool shouldBeActive: true
readonly property string startTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(object[settings[1]]);
return Qt.formatTime(d, "hh:mm AP");
}
signal applySettings(startTime: int, endTime: int)
signal close
+22 -17
View File
@@ -12,6 +12,7 @@ import qs.Helpers
Item {
id: wrapper
property int buttonRowHeight: Appearance.padding.large * 3
property bool changesMade: false
readonly property var currentScreen: screens.length > selectedScreenIndex ? screens[selectedScreenIndex] : null
property var screens: []
@@ -34,13 +35,7 @@ Item {
function refreshScreens(): void {
screens = [...Quickshell.screens].sort((a, b) => a.x - b.x);
if (screens.length === 0) {
selectedScreenIndex = 0;
return;
}
selectedScreenIndex = Math.max(0, Math.min(selectedScreenIndex, screens.length - 1));
selectedScreenIndex = 0;
}
function selectScreen(index: int): void {
@@ -130,12 +125,13 @@ Item {
ButtonRow {
id: screenSelector
anchors.bottom: scaledImg.top
anchors.bottomMargin: Appearance.spacing.normal
anchors.left: parent.left
anchors.leftMargin: Appearance.padding.extraLarge * 2
anchors.right: parent.right
anchors.rightMargin: Appearance.padding.extraLarge * 2
anchors.top: parent.top
implicitHeight: 34
spacing: Appearance.spacing.small
Repeater {
@@ -196,8 +192,9 @@ Item {
anchors.bottomMargin: Appearance.spacing.normal
anchors.left: parent.left
anchors.right: parent.right
anchors.top: screenSelector.bottom
anchors.topMargin: Appearance.spacing.normal
anchors.top: parent.top
anchors.topMargin: wrapper.buttonRowHeight + Appearance.spacing.normal
// anchors.top: screenSelector.bottom
asynchronous: true
fillMode: Image.PreserveAspectFit
retainWhileLoading: true
@@ -207,24 +204,33 @@ Item {
onPaintedWidthChanged: {
if (paintedWidth > 0 && cropRectLoader.item) {
cropRectLoader.item.restoreFromData();
if (!wrapper.screens.length)
wrapper.refreshScreens();
wrapper.syncCropToScreen();
}
}
onSourceChanged: {
if (cropRectLoader.item) {
cropRectLoader.item.restoreFromData();
if (!wrapper.screens.length)
wrapper.refreshScreens();
wrapper.syncCropToScreen();
}
}
onStatusChanged: {
if (scaledImg.status == Image.Ready && cropRectLoader.item) {
cropRectLoader.item.restoreFromData();
if (!wrapper.screens.length)
wrapper.refreshScreens();
wrapper.syncCropToScreen();
}
}
Loader {
id: cropRectLoader
active: scaledImg.paintedWidth > 0 && wrapper.currentScreen
active: scaledImg.status === Image.Ready
sourceComponent: Component {
CustomRect {
@@ -259,11 +265,10 @@ Item {
}
function restoreFromData() {
if (!wrapper.currentScreen)
return;
let data = Wallpapers.getCrop(wrapper.currentScreen.name);
console.log(data.x, data.y);
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 = imageX + (data.x * scaledImg.paintedWidth);
+29 -6
View File
@@ -25,10 +25,7 @@ PageBase {
Layout.alignment: Qt.AlignHCenter
implicitHeight: cropper.height
implicitWidth: {
const screen = root.sState.screen;
return implicitHeight / screen.height * screen.width;
}
implicitWidth: root.cappedWidth
WallpaperCropper {
id: cropper
@@ -76,9 +73,22 @@ PageBase {
}
OverlayRow {
id: darkMode
readonly property string endTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(Config.general.color.scheduleDarkEnd);
return Qt.formatTime(d, "hh:mm AP");
}
readonly property string startTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(Config.general.color.scheduleDarkStart);
return Qt.formatTime(d, "hh:mm AP");
}
checked: Config.general.color.scheduleDark
first: true
subtext: qsTr("Dark mode will turn on at %1, and turn off at %2.").arg(Config.general.color.scheduleDarkStart).arg(Config.general.color.scheduleDarkEnd)
subtext: qsTr("Dark mode will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
text: qsTr("Schedule dark mode")
popup: Component {
@@ -103,10 +113,23 @@ PageBase {
}
OverlayRow {
id: hyprsunset
readonly property string endTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(Config.general.color.scheduleHyprsunsetEnd);
return Qt.formatTime(d, "hh:mm AP");
}
readonly property string startTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(Config.general.color.scheduleHyprsunsetStart);
return Qt.formatTime(d, "hh:mm AP");
}
Layout.topMargin: Appearance.spacing.extraSmall / 2 - parent.spacing
checked: Config.general.color.scheduleHyprsunset
last: true
subtext: qsTr("Hyprsunset will turn on at %1, and turn off at %2.").arg(Config.general.color.scheduleHyprsunsetStart).arg(Config.general.color.scheduleHyprsunsetEnd)
subtext: qsTr("Hyprsunset will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
text: qsTr("Schedule hyprsunset")
popup: Component {