quickshell and hyprland additions

This commit is contained in:
2026-03-15 13:56:00 +02:00
parent c9c27d1554
commit 1ad06b82a6
509 changed files with 68371 additions and 19 deletions

View File

@@ -0,0 +1,60 @@
import qs.components
import qs.services
import qs.config
import QtQuick
import QtQuick.Shapes
ShapePath {
id: root
required property Wrapper wrapper
readonly property real rounding: Config.border.rounding
readonly property bool flatten: wrapper.width < rounding * 2
readonly property real roundingX: flatten ? wrapper.width / 2 : rounding
strokeWidth: -1
fillColor: Colours.palette.m3surface
PathArc {
relativeX: -root.roundingX
relativeY: root.rounding
radiusX: Math.min(root.rounding, root.wrapper.width)
radiusY: root.rounding
}
PathLine {
relativeX: -(root.wrapper.width - root.roundingX * 2)
relativeY: 0
}
PathArc {
relativeX: -root.roundingX
relativeY: root.rounding
radiusX: Math.min(root.rounding, root.wrapper.width)
radiusY: root.rounding
direction: PathArc.Counterclockwise
}
PathLine {
relativeX: 0
relativeY: root.wrapper.height - root.rounding * 2
}
PathArc {
relativeX: root.roundingX
relativeY: root.rounding
radiusX: Math.min(root.rounding, root.wrapper.width)
radiusY: root.rounding
direction: PathArc.Counterclockwise
}
PathLine {
relativeX: root.wrapper.width - root.roundingX * 2
relativeY: 0
}
PathArc {
relativeX: root.roundingX
relativeY: root.rounding
radiusX: Math.min(root.rounding, root.wrapper.width)
radiusY: root.rounding
}
Behavior on fillColor {
CAnim {}
}
}

View File

@@ -0,0 +1,135 @@
pragma ComponentBehavior: Bound
import qs.components
import qs.services
import qs.config
import qs.utils
import Quickshell
import QtQuick
Column {
id: root
required property PersistentProperties visibilities
padding: Appearance.padding.large
spacing: Appearance.spacing.large
SessionButton {
id: logout
icon: Config.session.icons.logout
command: Config.session.commands.logout
KeyNavigation.down: shutdown
Component.onCompleted: forceActiveFocus()
Connections {
target: root.visibilities
function onLauncherChanged(): void {
if (!root.visibilities.launcher)
logout.forceActiveFocus();
}
}
}
SessionButton {
id: shutdown
icon: Config.session.icons.shutdown
command: Config.session.commands.shutdown
KeyNavigation.up: logout
KeyNavigation.down: hibernate
}
AnimatedImage {
width: Config.session.sizes.button
height: Config.session.sizes.button
sourceSize.width: width
sourceSize.height: height
playing: visible
asynchronous: true
speed: Appearance.anim.sessionGifSpeed
source: Paths.absolutePath(Config.paths.sessionGif)
}
SessionButton {
id: hibernate
icon: Config.session.icons.hibernate
command: Config.session.commands.hibernate
KeyNavigation.up: shutdown
KeyNavigation.down: reboot
}
SessionButton {
id: reboot
icon: Config.session.icons.reboot
command: Config.session.commands.reboot
KeyNavigation.up: hibernate
}
component SessionButton: StyledRect {
id: button
required property string icon
required property list<string> command
implicitWidth: Config.session.sizes.button
implicitHeight: Config.session.sizes.button
radius: Appearance.rounding.large
color: button.activeFocus ? Colours.palette.m3secondaryContainer : Colours.tPalette.m3surfaceContainer
Keys.onEnterPressed: Quickshell.execDetached(button.command)
Keys.onReturnPressed: Quickshell.execDetached(button.command)
Keys.onEscapePressed: root.visibilities.session = false
Keys.onPressed: event => {
if (!Config.session.vimKeybinds)
return;
if (event.modifiers & Qt.ControlModifier) {
if (event.key === Qt.Key_J && KeyNavigation.down) {
KeyNavigation.down.focus = true;
event.accepted = true;
} else if (event.key === Qt.Key_K && KeyNavigation.up) {
KeyNavigation.up.focus = true;
event.accepted = true;
}
} else if (event.key === Qt.Key_Tab && KeyNavigation.down) {
KeyNavigation.down.focus = true;
event.accepted = true;
} else if (event.key === Qt.Key_Backtab || (event.key === Qt.Key_Tab && (event.modifiers & Qt.ShiftModifier))) {
if (KeyNavigation.up) {
KeyNavigation.up.focus = true;
event.accepted = true;
}
}
}
StateLayer {
radius: parent.radius
color: button.activeFocus ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
function onClicked(): void {
Quickshell.execDetached(button.command);
}
}
MaterialIcon {
anchors.centerIn: parent
text: button.icon
color: button.activeFocus ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
font.pointSize: Appearance.font.size.extraLarge
font.weight: 500
}
}
}

View File

@@ -0,0 +1,63 @@
pragma ComponentBehavior: Bound
import qs.components
import qs.config
import Quickshell
import QtQuick
Item {
id: root
required property PersistentProperties visibilities
required property var panels
readonly property real nonAnimWidth: content.implicitWidth
visible: width > 0
implicitWidth: 0
implicitHeight: content.implicitHeight
states: State {
name: "visible"
when: root.visibilities.session && Config.session.enabled
PropertyChanges {
root.implicitWidth: root.nonAnimWidth
}
}
transitions: [
Transition {
from: ""
to: "visible"
Anim {
target: root
property: "implicitWidth"
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
}
},
Transition {
from: "visible"
to: ""
Anim {
target: root
property: "implicitWidth"
easing.bezierCurve: root.panels.osd.width > 0 ? Appearance.anim.curves.expressiveDefaultSpatial : Appearance.anim.curves.emphasized
}
}
]
Loader {
id: content
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
Component.onCompleted: active = Qt.binding(() => (root.visibilities.session && Config.session.enabled) || root.visible)
sourceComponent: Content {
visibilities: root.visibilities
}
}
}