diff --git a/quickshell/Modules/Lock/LockWidgetItem.qml b/quickshell/Modules/Lock/LockWidgetItem.qml index 36f2fd461..5b1963efb 100644 --- a/quickshell/Modules/Lock/LockWidgetItem.qml +++ b/quickshell/Modules/Lock/LockWidgetItem.qml @@ -18,6 +18,7 @@ Item { readonly property bool selected: hostLayer.selectedInstanceId === instanceId readonly property bool interacting: editChrome.item?.interacting ?? false readonly property var contrastColors: content.item?.contrastColors ?? [] + readonly property real bottomOverflow: content.item?.bottomOverflow ?? 0 readonly property bool hasSavedPosition: geometry.hasSavedPosition readonly property bool automaticPlacement: widgetType === "lockClock" && (instanceData?.config?.autoPosition ?? true) && !hasSavedPosition readonly property bool dragging: editChrome.item?.dragging ?? false @@ -215,6 +216,7 @@ Item { hasOptions: true cornerResize: content.contentResizable sizeText: Math.round(root.width) + "×" + Math.round(root.height) + snapped: geometry.squareSnapped onRemoveRequested: root.removeRequested() onOptionsRequested: root.optionsRequested() onResizeStarted: (px, py) => { diff --git a/quickshell/Modules/Lock/LockWidgetLayer.qml b/quickshell/Modules/Lock/LockWidgetLayer.qml index 737ae505f..57364d9b4 100644 --- a/quickshell/Modules/Lock/LockWidgetLayer.qml +++ b/quickshell/Modules/Lock/LockWidgetLayer.qml @@ -170,7 +170,7 @@ FocusScope { const auth = itemOfType("lockAuth"); return { x: centerX, - y: auth ? auth.y + auth.height + Theme.spacingL : height / 2 + Theme.spacingL + y: auth ? auth.y + auth.height + auth.bottomOverflow + Theme.spacingL : height / 2 + Theme.spacingL }; } case "lockStatus": diff --git a/quickshell/Modules/Lock/Widgets/LockAuthWidget.qml b/quickshell/Modules/Lock/Widgets/LockAuthWidget.qml index c4bc6e1cc..e72f70b63 100644 --- a/quickshell/Modules/Lock/Widgets/LockAuthWidget.qml +++ b/quickshell/Modules/Lock/Widgets/LockAuthWidget.qml @@ -53,7 +53,7 @@ Item { readonly property color accentColor: Theme.primary readonly property color plainColor: Theme.lockScreenContentColor readonly property bool resizable: true - readonly property real minWidth: LockMetrics.fieldWidth / 2 + readonly property real minWidth: ring ? ringSize : LockMetrics.fieldWidth / 2 readonly property real minHeight: implicitHeight property alias showPassword: passwordBox.showPassword @@ -63,8 +63,10 @@ Item { readonly property string pamState: lockHost?.pamState ?? "" readonly property string passwordBuffer: lockHost?.passwordBuffer ?? "" - implicitWidth: Math.min(LockMetrics.passwordRowWidth, (lockHost?.width ?? LockMetrics.passwordRowWidth) - Theme.spacingXL * 2) - implicitHeight: passwordLayout.implicitHeight + Theme.spacingS + capsLockRow.implicitHeight + implicitWidth: ring ? ringSize : Math.min(LockMetrics.passwordRowWidth, (lockHost?.width ?? LockMetrics.passwordRowWidth) - Theme.spacingXL * 2) + implicitHeight: passwordLayout.implicitHeight + // Feedback and the caps lock warning hang below the box so centring the box centres the field. + readonly property real bottomOverflow: Theme.spacingS + Math.max(capsLockRow.implicitHeight, authFeedbackText.height) function encodeFileUrl(path) { if (!path) @@ -165,7 +167,7 @@ Item { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - spacing: Theme.spacingM + spacing: 0 Item { id: ringIndicator @@ -1106,12 +1108,21 @@ Item { } } } + } + + Column { + id: belowField + anchors.top: passwordLayout.bottom + anchors.topMargin: Theme.spacingS + width: Math.max(parent.width, LockMetrics.passwordRowWidth) + x: (parent.width - width) / 2 + spacing: Theme.spacingXS StyledText { id: authFeedbackText - Layout.fillWidth: true - Layout.preferredHeight: text.length > 0 ? Math.min(implicitHeight, Math.ceil(Theme.fontSizeSmall * 4.5)) : 0 + width: parent.width + height: text.length > 0 ? Math.min(implicitHeight, Math.ceil(Theme.fontSizeSmall * 4.5)) : 0 text: root.currentAuthFeedbackText() color: root.authFeedbackIsHint() ? Theme.outline : Theme.error font.pixelSize: Theme.fontSizeSmall @@ -1129,35 +1140,33 @@ Item { } } } - } - Row { - id: capsLockRow - anchors.top: passwordLayout.bottom - anchors.topMargin: Theme.spacingS - anchors.horizontalCenter: passwordLayout.horizontalCenter - spacing: Theme.spacingXS - opacity: DMSService.capsLockState ? 1 : 0 + Row { + id: capsLockRow + x: (parent.width - width) / 2 + spacing: Theme.spacingXS + opacity: DMSService.capsLockState ? 1 : 0 - DankIcon { - name: "shift_lock" - size: Theme.iconSizeSmall - color: Theme.error - anchors.verticalCenter: parent.verticalCenter - } + DankIcon { + name: "shift_lock" + size: Theme.iconSizeSmall + color: Theme.error + anchors.verticalCenter: parent.verticalCenter + } - StyledText { - text: I18n.tr("Caps Lock is on") - font.pixelSize: Theme.fontSizeSmall - color: Theme.error - anchors.verticalCenter: parent.verticalCenter - } + StyledText { + text: I18n.tr("Caps Lock is on") + font.pixelSize: Theme.fontSizeSmall + color: Theme.error + anchors.verticalCenter: parent.verticalCenter + } - Behavior on opacity { - NumberAnimation { - duration: LockMetrics.effectsDuration - easing.type: Easing.BezierSpline - easing.bezierCurve: Theme.expressiveCurves.expressiveEffects + Behavior on opacity { + NumberAnimation { + duration: LockMetrics.effectsDuration + easing.type: Easing.BezierSpline + easing.bezierCurve: Theme.expressiveCurves.expressiveEffects + } } } } diff --git a/quickshell/Modules/Lock/Widgets/LockNotificationsWidget.qml b/quickshell/Modules/Lock/Widgets/LockNotificationsWidget.qml index 74cfe5e10..067d199aa 100644 --- a/quickshell/Modules/Lock/Widgets/LockNotificationsWidget.qml +++ b/quickshell/Modules/Lock/Widgets/LockNotificationsWidget.qml @@ -95,6 +95,7 @@ Item { property int fitCount: root.visibleGroups.length // One width for every app chip keeps the row symmetric about the centre whatever the label lengths. property real chipWidth: 0 + property bool moreFits: true readonly property int hiddenCount: root.appNameGroups.length - fitCount implicitWidth: chipRow.implicitWidth implicitHeight: chipRow.implicitHeight @@ -110,6 +111,7 @@ Item { while (count > 1 && total(count) + overflow(count) > width) count--; fitCount = count; + moreFits = total(count) + overflow(count) <= width; } onWidthChanged: Qt.callLater(measure) @@ -205,7 +207,7 @@ Item { } Chip { - visible: chipHost.hiddenCount > 0 + visible: chipHost.hiddenCount > 0 && chipHost.moreFits StyledText { anchors.verticalCenter: parent.verticalCenter diff --git a/quickshell/Modules/Plugins/DesktopWidgetGeometry.qml b/quickshell/Modules/Plugins/DesktopWidgetGeometry.qml index 559aa5f48..2f79c8771 100644 --- a/quickshell/Modules/Plugins/DesktopWidgetGeometry.qml +++ b/quickshell/Modules/Plugins/DesktopWidgetGeometry.qml @@ -51,6 +51,7 @@ QtObject { property real dragOverrideY: -1 property real dragOverrideW: -1 property real dragOverrideH: -1 + property bool squareSnapped: false readonly property real effectiveX: dragOverrideX >= 0 ? dragOverrideX : savedX readonly property real effectiveY: dragOverrideY >= 0 ? dragOverrideY : savedY @@ -81,6 +82,7 @@ QtObject { dragOverrideY = -1; dragOverrideW = -1; dragOverrideH = -1; + squareSnapped = false; } function requestResize(width, height) { @@ -148,8 +150,11 @@ QtObject { newW = Math.max(minWidth, snapToGrid(newW)); newH = Math.max(minHeight, snapToGrid(newH)); } - if (!forceSquare) - return Qt.size(newW, newH); + if (!forceSquare) { + squareSnapped = Math.abs(newW - newH) <= (gridEnabled ? gridSize / 2 : Theme.spacingL); + if (!squareSnapped) + return Qt.size(newW, newH); + } const size = Math.max(newW, newH); return Qt.size(Math.min(size, screenWidth - widgetX), Math.min(size, screenHeight - widgetY)); } diff --git a/quickshell/Widgets/DankGridEditChrome.qml b/quickshell/Widgets/DankGridEditChrome.qml index 0e2722e75..59d528b7a 100644 --- a/quickshell/Widgets/DankGridEditChrome.qml +++ b/quickshell/Widgets/DankGridEditChrome.qml @@ -13,6 +13,7 @@ Item { property bool resizing: false property bool hasOptions: false property bool atDefault: false + property bool snapped: false property bool removable: true property bool horizontalResize: false property bool edgeResize: false @@ -132,7 +133,7 @@ Item { width: sizeLabel.implicitWidth + Theme.spacingM * 2 height: root.buttonSize radius: Theme.fullRadius(width, height) - color: root.atDefault ? Theme.primary : Theme.chipSurface + color: root.atDefault || root.snapped ? Theme.primary : Theme.chipSurface visible: root.resizing && root.sizeText.length > 0 StyledText { @@ -141,7 +142,7 @@ Item { text: root.sizeText font.pixelSize: Theme.fontSizeMedium font.weight: Theme.fontWeightMedium - color: root.atDefault ? Theme.onPrimary : Theme.surfaceText + color: root.atDefault || root.snapped ? Theme.onPrimary : Theme.surfaceText } }