lock: add session buttons

This commit is contained in:
2 * r + 2 * t 2025-06-25 17:45:26 +10:00
parent 173738c0be
commit 7a27d4126f
4 changed files with 191 additions and 0 deletions

View file

@ -19,5 +19,7 @@ JsonObject {
property int mediaCoverBorder: 3
property int largeScreenWidth: 2560
property int smallScreenWidth: 1080
property int buttonsWidth: 500
property int buttonsWidthSmall: 300
}
}

View file

@ -10,6 +10,8 @@ Item {
required property bool locked
required property real weatherWidth
required property real buttonsWidth
required property real buttonsHeight
required property bool isNormal
required property bool isLarge
@ -17,6 +19,8 @@ Item {
readonly property real inputTop: innerMask.anchors.margins + inputPath.height
readonly property real weatherTop: innerMask.anchors.margins + weatherPath.height
readonly property real weatherRight: innerMask.anchors.margins + weatherPath.width
readonly property real buttonsTop: innerMask.anchors.margins + buttonsPath.height
readonly property real buttonsLeft: innerMask.anchors.margins + buttonsPath.width
readonly property real mediaX: innerMask.anchors.margins + mediaPath.width
readonly property real mediaY: innerMask.anchors.margins + mediaPath.height
@ -331,6 +335,71 @@ Item {
}
}
}
ShapePath {
id: buttonsPath
property int width: root.locked ? root.buttonsWidth - Config.lock.sizes.border / 4 : 0
property real height: root.locked ? root.buttonsHeight - Config.lock.sizes.border / 4 : 0
readonly property real rounding: Appearance.rounding.large * 2
readonly property real roundingX: width < rounding * 2 ? width / 2 : rounding
readonly property real roundingY: height < rounding * 2 ? height / 2 : rounding
strokeWidth: -1
fillColor: root.isLarge ? Config.border.colour : "transparent"
startX: Math.ceil(innerMask.width)
startY: Math.ceil(innerMask.height) - height - roundingY
PathArc {
relativeX: -buttonsPath.roundingX
relativeY: buttonsPath.roundingY
radiusX: Math.min(buttonsPath.rounding, buttonsPath.width)
radiusY: Math.min(buttonsPath.rounding, buttonsPath.height)
}
PathLine {
relativeX: -(buttonsPath.width - buttonsPath.roundingX * 2)
relativeY: 0
}
PathArc {
relativeX: -buttonsPath.roundingX
relativeY: buttonsPath.roundingY
radiusX: Math.min(buttonsPath.rounding, buttonsPath.width)
radiusY: Math.min(buttonsPath.rounding, buttonsPath.height)
direction: PathArc.Counterclockwise
}
PathLine {
relativeX: 0
relativeY: buttonsPath.height - buttonsPath.roundingY * 2
}
PathArc {
relativeX: -buttonsPath.roundingX
relativeY: buttonsPath.roundingY
radiusX: Math.min(buttonsPath.rounding, buttonsPath.width)
radiusY: Math.min(buttonsPath.rounding, buttonsPath.height)
}
PathLine {
relativeX: buttonsPath.width + buttonsPath.roundingX
relativeY: 0
}
Behavior on width {
Anim {}
}
Behavior on height {
Anim {}
}
Behavior on fillColor {
ColorAnimation {
duration: Appearance.anim.durations.normal
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard
}
}
}
}
component Anim: NumberAnimation {

111
modules/lock/Buttons.qml Normal file
View file

@ -0,0 +1,111 @@
import "root:/widgets"
import "root:/services"
import "root:/config"
import Quickshell.Widgets
import QtQuick
import QtQuick.Layouts
WrapperItem {
readonly property real nonAnimMargin: handler.hovered ? Appearance.padding.large * 2 : Appearance.padding.large * 1.2
readonly property real nonAnimWidth: handler.hovered ? Config.lock.sizes.buttonsWidth : Config.lock.sizes.buttonsWidthSmall
readonly property real nonAnimHeight: (nonAnimWidth + nonAnimMargin * 2) / 4
margin: nonAnimMargin
rightMargin: 0
bottomMargin: 0
implicitWidth: nonAnimWidth
implicitHeight: nonAnimHeight
Behavior on margin {
NumberAnimation {
duration: Appearance.anim.durations.large
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.emphasized
}
}
Behavior on implicitWidth {
NumberAnimation {
duration: Appearance.anim.durations.large
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.emphasized
}
}
Behavior on implicitHeight {
NumberAnimation {
duration: Appearance.anim.durations.large
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.emphasized
}
}
HoverHandler {
id: handler
target: parent
}
RowLayout {
id: layout
spacing: Appearance.spacing.normal
SessionButton {
icon: "logout"
command: ["loginctl", "terminate-user", ""]
}
SessionButton {
icon: "power_settings_new"
command: ["systemctl", "poweroff"]
}
SessionButton {
icon: "downloading"
command: ["systemctl", "hibernate"]
}
SessionButton {
icon: "cached"
command: ["systemctl", "reboot"]
}
}
component SessionButton: StyledRect {
required property string icon
required property list<string> command
Layout.fillWidth: true
Layout.preferredHeight: width
radius: stateLayer.containsMouse ? Appearance.rounding.large * 2 : Appearance.rounding.large * 1.2
color: Colours.palette.m3secondaryContainer
StateLayer {
id: stateLayer
color: Colours.palette.m3onSecondaryContainer
function onClicked(): void {
Quickshell.execDetached(parent.command);
}
}
MaterialIcon {
anchors.centerIn: parent
text: parent.icon
color: Colours.palette.m3onSecondaryContainer
font.pointSize: (parent.width * 0.4) || 1
}
Behavior on radius {
NumberAnimation {
duration: Appearance.anim.durations.normal
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard
}
}
}
}

View file

@ -73,6 +73,8 @@ WlSessionLockSurface {
locked: root.locked
weatherWidth: weather.implicitWidth
buttonsWidth: buttons.item?.nonAnimWidth ?? 0
buttonsHeight: buttons.item?.nonAnimHeight ?? 0
isNormal: root.screen.width > Config.lock.sizes.smallScreenWidth
isLarge: root.screen.width > Config.lock.sizes.largeScreenWidth
visible: false
@ -153,9 +155,16 @@ WlSessionLockSurface {
}
Loader {
id: buttons
active: root.screen.width > Config.lock.sizes.largeScreenWidth
asynchronous: true
anchors.top: parent.bottom
anchors.left: parent.right
anchors.topMargin: -backgrounds.buttonsTop
anchors.leftMargin: -backgrounds.buttonsLeft
sourceComponent: Buttons {}
}