summaryrefslogtreecommitdiff
path: root/modules/session
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-05-11 23:55:05 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-05-11 23:55:05 +1000
commit60858f6f02fb7dc04e727db89090e7b83399803a (patch)
tree0a6300271786a38a468ba4bb6df0c392eed82043 /modules/session
parentosd: fix show on hover (diff)
downloadcaelestia-shell-60858f6f02fb7dc04e727db89090e7b83399803a.tar.gz
caelestia-shell-60858f6f02fb7dc04e727db89090e7b83399803a.tar.bz2
caelestia-shell-60858f6f02fb7dc04e727db89090e7b83399803a.zip
feat: session menu
Diffstat (limited to 'modules/session')
-rw-r--r--modules/session/Background.qml70
-rw-r--r--modules/session/Content.qml118
-rw-r--r--modules/session/Session.qml87
-rw-r--r--modules/session/Wrapper.qml62
4 files changed, 337 insertions, 0 deletions
diff --git a/modules/session/Background.qml b/modules/session/Background.qml
new file mode 100644
index 0000000..4b4b92e
--- /dev/null
+++ b/modules/session/Background.qml
@@ -0,0 +1,70 @@
+import "root:/services"
+import "root:/config"
+import QtQuick
+import QtQuick.Shapes
+
+Shape {
+ id: root
+
+ required property real wrapperWidth
+ required property real wrapperHeight
+ readonly property real rounding: BorderConfig.rounding
+ readonly property bool flatten: wrapperWidth < rounding * 2
+ readonly property real roundingX: flatten ? wrapperWidth / 2 : rounding
+
+ preferredRendererType: Shape.CurveRenderer
+ opacity: Colours.transparency.enabled ? Colours.transparency.base : 1
+
+ ShapePath {
+ strokeWidth: -1
+ fillColor: BorderConfig.colour
+
+ startX: root.wrapperWidth - 1
+
+ PathArc {
+ relativeX: -root.roundingX
+ relativeY: root.rounding
+ radiusX: Math.min(root.rounding, root.wrapperWidth)
+ radiusY: root.rounding
+ }
+ PathLine {
+ x: root.roundingX
+ relativeY: 0
+ }
+ PathArc {
+ relativeX: -root.roundingX
+ relativeY: root.rounding
+ radiusX: Math.min(root.rounding, root.wrapperWidth)
+ radiusY: root.rounding
+ direction: PathArc.Counterclockwise
+ }
+ PathLine {
+ y: root.wrapperHeight - root.rounding * 2
+ }
+ PathArc {
+ relativeX: root.roundingX
+ relativeY: root.rounding
+ radiusX: Math.min(root.rounding, root.wrapperWidth)
+ radiusY: root.rounding
+ direction: PathArc.Counterclockwise
+ }
+ PathLine {
+ x: (root.flatten ? root.roundingX : root.wrapperWidth - root.rounding) - 1
+ relativeY: 0
+ }
+ PathArc {
+ relativeX: root.roundingX
+ relativeY: root.rounding
+ radiusX: Math.min(root.rounding, root.wrapperWidth)
+ radiusY: root.rounding
+ }
+
+ Behavior on fillColor {
+ ColorAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.standard
+ }
+ }
+ }
+}
diff --git a/modules/session/Content.qml b/modules/session/Content.qml
new file mode 100644
index 0000000..d1a2c38
--- /dev/null
+++ b/modules/session/Content.qml
@@ -0,0 +1,118 @@
+pragma ComponentBehavior: Bound
+
+import "root:/widgets"
+import "root:/services"
+import "root:/config"
+import Quickshell
+import Quickshell.Io
+import QtQuick
+
+Column {
+ id: root
+
+ required property Scope session
+
+ padding: Appearance.padding.large
+
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+
+ spacing: Appearance.spacing.large
+
+ SessionButton {
+ id: logout
+
+ icon: "logout"
+ command: ["uwsm", "stop"]
+
+ KeyNavigation.down: shutdown
+
+ Connections {
+ target: session
+
+ function onSessionVisibleChanged(): void {
+ if (session.sessionVisible)
+ logout.focus = true;
+ }
+ }
+ }
+
+ SessionButton {
+ id: shutdown
+
+ icon: "power_settings_new"
+ command: ["systemctl", "poweroff"]
+
+ KeyNavigation.up: logout
+ KeyNavigation.down: hibernate
+ }
+
+ AnimatedImage {
+ width: SessionConfig.sizes.button
+ height: SessionConfig.sizes.button
+ sourceSize.width: width
+ sourceSize.height: height
+
+ playing: session.sessionVisible
+ asynchronous: true
+ speed: 0.7
+ source: "root:/assets/kurukuru.gif"
+ }
+
+ SessionButton {
+ id: hibernate
+
+ icon: "downloading"
+ command: ["systemctl", "hibernate"]
+
+ KeyNavigation.up: shutdown
+ KeyNavigation.down: reboot
+ }
+
+ SessionButton {
+ id: reboot
+
+ icon: "cached"
+ command: ["systemctl", "reboot"]
+
+ KeyNavigation.up: hibernate
+ }
+
+ component SessionButton: StyledRect {
+ id: button
+
+ required property string icon
+ required property list<string> command
+
+ implicitWidth: SessionConfig.sizes.button
+ implicitHeight: SessionConfig.sizes.button
+
+ radius: Appearance.rounding.large
+ color: button.activeFocus ? Colours.palette.m3secondaryContainer : Colours.palette.m3surfaceContainer
+
+ Keys.onEnterPressed: proc.startDetached()
+ Keys.onEscapePressed: root.session.sessionVisible = false
+
+ Process {
+ id: proc
+
+ command: button.command
+ }
+
+ StateLayer {
+ radius: parent.radius
+
+ function onClicked(): void {
+ proc.startDetached();
+ }
+ }
+
+ MaterialIcon {
+ anchors.centerIn: parent
+
+ text: button.icon
+ color: button.activeFocus ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
+ font.pointSize: Appearance.font.size.extraLarge
+ }
+ }
+}
diff --git a/modules/session/Session.qml b/modules/session/Session.qml
new file mode 100644
index 0000000..0f8a0d5
--- /dev/null
+++ b/modules/session/Session.qml
@@ -0,0 +1,87 @@
+import "root:/widgets"
+import "root:/services"
+import "root:/config"
+import Quickshell
+import Quickshell.Wayland
+import QtQuick
+
+Scope {
+ id: root
+
+ property int winHeight
+ property bool sessionVisible
+
+ Connections {
+ target: Drawers
+
+ function onPosChanged(screen: ShellScreen, x: int, y: int): void {
+ if (x > screen.width - BorderConfig.thickness && y > (screen.height - root.winHeight) / 2 && y < (screen.height + root.winHeight) / 2)
+ root.sessionVisible = true;
+ }
+ }
+
+ LazyLoader {
+ loading: true
+
+ StyledWindow {
+ id: win
+
+ name: "osd"
+ keyboardFocus: root.sessionVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
+ visible: wrapper.shouldBeVisible
+
+ mask: Region {
+ item: wrapper
+ }
+
+ anchors.left: true
+ anchors.right: true
+ height: wrapper.height
+
+ Component.onCompleted: {
+ root.winHeight = height;
+ Drawers.rightExclusion = Qt.binding(() => bg.width);
+ }
+
+ Background {
+ id: bg
+
+ visible: false
+
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+
+ wrapperWidth: Math.min(wrapper.width, content.width)
+ wrapperHeight: wrapper.height
+ }
+
+ LayerShadow {
+ source: bg
+ }
+
+ Wrapper {
+ id: wrapper
+
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+
+ implicitHeight: content.height + bg.rounding * 2
+
+ sessionVisible: root.sessionVisible
+ contentWidth: content.width
+
+ Content {
+ id: content
+
+ session: root
+ }
+ }
+ }
+ }
+
+ CustomShortcut {
+ name: "session"
+ description: "Toggle session menu"
+ onPressed: root.sessionVisible = !root.sessionVisible
+ }
+}
diff --git a/modules/session/Wrapper.qml b/modules/session/Wrapper.qml
new file mode 100644
index 0000000..5806972
--- /dev/null
+++ b/modules/session/Wrapper.qml
@@ -0,0 +1,62 @@
+import "root:/config"
+import QtQuick
+
+Item {
+ id: root
+
+ required property bool sessionVisible
+ required property real contentWidth
+ property bool shouldBeVisible
+
+ visible: width > 0
+ width: 0
+
+ states: State {
+ name: "visible"
+ when: root.sessionVisible
+
+ PropertyChanges {
+ root.width: contentWidth
+ root.shouldBeVisible: true
+ }
+ }
+
+ transitions: [
+ Transition {
+ from: ""
+ to: "visible"
+
+ SequentialAnimation {
+ PropertyAction {
+ target: root
+ property: "shouldBeVisible"
+ }
+ NumberAnimation {
+ target: root
+ property: "width"
+ duration: Appearance.anim.durations.large
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasizedDecel
+ }
+ }
+ },
+ Transition {
+ from: "visible"
+ to: ""
+
+ SequentialAnimation {
+ NumberAnimation {
+ target: root
+ property: "width"
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasizedAccel
+ }
+ PropertyAction {
+ target: root
+ property: "shouldBeVisible"
+ }
+ }
+ }
+ ]
+}