summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-06-25 17:45:26 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-06-25 17:45:26 +1000
commit7a27d4126f06bc92041bd909929ebcdebb4a6cee (patch)
tree2ec1b086af0a28061349e59212cf1558b1b5b79e /modules
parentlock: fix media position (diff)
downloadcaelestia-shell-7a27d4126f06bc92041bd909929ebcdebb4a6cee.tar.gz
caelestia-shell-7a27d4126f06bc92041bd909929ebcdebb4a6cee.tar.bz2
caelestia-shell-7a27d4126f06bc92041bd909929ebcdebb4a6cee.zip
lock: add session buttons
Diffstat (limited to 'modules')
-rw-r--r--modules/lock/Backgrounds.qml69
-rw-r--r--modules/lock/Buttons.qml111
-rw-r--r--modules/lock/LockSurface.qml9
3 files changed, 189 insertions, 0 deletions
diff --git a/modules/lock/Backgrounds.qml b/modules/lock/Backgrounds.qml
index 3ac4999..e561c66 100644
--- a/modules/lock/Backgrounds.qml
+++ b/modules/lock/Backgrounds.qml
@@ -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 {
diff --git a/modules/lock/Buttons.qml b/modules/lock/Buttons.qml
new file mode 100644
index 0000000..ef7af37
--- /dev/null
+++ b/modules/lock/Buttons.qml
@@ -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
+ }
+ }
+ }
+}
diff --git a/modules/lock/LockSurface.qml b/modules/lock/LockSurface.qml
index 6c2ffa7..047116f 100644
--- a/modules/lock/LockSurface.qml
+++ b/modules/lock/LockSurface.qml
@@ -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 {}
}