added starting funtionality

This commit is contained in:
2026-08-24 15:06:58 +01:00
parent c4b4a3bd26
commit 6c415d6fbb
5 changed files with 544 additions and 73 deletions

View File

@@ -2,6 +2,7 @@ import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import "../../config"
Item {
@@ -9,6 +10,12 @@ Item {
implicitWidth: label.implicitWidth + 4
implicitHeight: Appearance.barHeight
// The bar's own PanelWindow — passed in from Bar.qml so this popup can
// anchor to the bar itself rather than to this icon, keeping it a fixed
// distance from the bar and the screen edge regardless of where this
// icon sits in the row.
required property var barWindow
Text {
id: label
anchors.centerIn: parent
@@ -22,7 +29,10 @@ Item {
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: menu.visible = !menu.visible
onClicked: {
menu.visible = !menu.visible
grab.active = menu.visible
}
}
Process { id: proc }
@@ -31,79 +41,134 @@ Item {
id: menu
visible: false
color: "transparent"
implicitWidth: 170
implicitHeight: list.model.length * 32 + (list.model.length - 1) * 2 + 16
implicitWidth: 210
// Same padding as Volume.qml's panel.
readonly property int contentPadding: 16
readonly property int labelOffset: -135
implicitHeight: mainColumn.implicitHeight + contentPadding * 2
anchor {
item: root
window: root.barWindow
// Unlike anchor.item, anchor.window doesn't default rect to the
// window's own bounds — set it explicitly so edges/gravity below
// resolve against the full bar (and thus the true screen edges)
// instead of a near-zero rect at the window's origin.
rect.x: 0
rect.y: 0
rect.width: root.barWindow.width
rect.height: root.barWindow.height
edges: Edges.Bottom | Edges.Right
gravity: Edges.Bottom | Edges.Left
margins.top: 4
margins.bottom: -4
margins.right: 0
}
HyprlandFocusGrab {
id: grab
windows: [menu]
onCleared: menu.visible = false
}
Rectangle {
anchors.fill: parent
radius: Appearance.radius
radius: 0
color: Colors.surface
border.color: Colors.muted
border.width: 1
border.width: 3
Column {
id: mainColumn
anchors.fill: parent
anchors.margins: 8
spacing: 2
anchors.margins: menu.contentPadding
spacing: 10
Repeater {
id: list
model: [
// "iconSize" is optional — omit it to use the 15px default below.
// Material Symbols glyphs aren't all the same visual weight at a
// given size (a padlock silhouette reads bulkier than a thin arrow),
// so nudge individual icons here to balance them by eye.
{ label: "Lock", icon: "lock", iconSize: 13, cmd: ["hyprlock"] },
{ label: "Log out", icon: "logout", cmd: ["hyprctl", "dispatch", "exit"] },
{ label: "Reboot", icon: "restart_alt", cmd: ["systemctl", "reboot"] },
{ label: "Shut down", icon: "power_settings_new", cmd: ["systemctl", "poweroff"] }
]
// Header — same title layout as Volume.qml's panel: the bar
// icon large, plus a bold title.
RowLayout {
id: header
width: parent.width
spacing: 8
delegate: Rectangle {
id: entry
required property var modelData
width: parent ? parent.width : 0
height: 32
radius: Appearance.radiusSmall
color: entryMouse.containsMouse ? Colors.primary : "transparent"
Text {
text: label.text
font.family: Appearance.iconFontFamily
font.variableAxes: Appearance.iconFontAxes
font.pixelSize: 30
color: Colors.foreground
}
RowLayout {
anchors.fill: parent
anchors.leftMargin: 8
spacing: 8
Text {
Layout.preferredWidth: 20
horizontalAlignment: Text.AlignHCenter
text: entry.modelData.icon
font.family: Appearance.iconFontFamily
font.variableAxes: Appearance.iconFontAxes
font.pixelSize: entry.modelData.iconSize || 15
color: entryMouse.containsMouse ? Colors.primaryText : Colors.foreground
Text {
Layout.fillWidth: true
text: "Power"
font.family: Appearance.fontFamily
font.pixelSize: 18
font.bold: true
color: Colors.foreground
}
}
Column {
width: parent.width
spacing: 2
Repeater {
id: list
model: [
{ label: "Lock", icon: "lock", cmd: ["hyprlock"] },
{ label: "Suspend", icon: "bedtime", cmd: ["systemctl", "suspend"] },
{ label: "Hibernate", icon: "ac_unit", cmd: ["systemctl", "hibernate"] },
{ label: "Log out", icon: "logout", cmd: ["hyprctl", "dispatch", "exit"] },
{ label: "Reboot", icon: "restart_alt", cmd: ["systemctl", "reboot"] },
{ label: "Shut down", icon: "power_settings_new", cmd: ["systemctl", "poweroff"] }
]
delegate: Rectangle {
id: entry
required property var modelData
width: parent ? parent.width : 0
height: 40
radius: Appearance.radiusSmall
color: (!entry.modelData.disabled && entryMouse.containsMouse) ? Colors.primary : "transparent"
RowLayout {
anchors.fill: parent
anchors.leftMargin: 8
spacing: 8
Text {
Layout.preferredWidth: 25
Layout.minimumWidth: 25
Layout.maximumWidth: 25
horizontalAlignment: Text.AlignLeft
text: entry.modelData.icon
font.family: Appearance.iconFontFamily
font.variableAxes: Appearance.iconFontAxes
font.pixelSize: entry.modelData.iconSize || 15
opacity: entry.modelData.disabled ? 0.4 : 1
color: entryMouse.containsMouse ? Colors.primaryText : Colors.foreground
}
Text {
Layout.leftMargin: menu.labelOffset + (entry.modelData.textOffset || 0)
text: entry.modelData.label
horizontalAlignment: Text.AlignLeft
font.family: Appearance.fontFamily
font.pixelSize: 16
opacity: entry.modelData.disabled ? 0.4 : 1
color: entryMouse.containsMouse ? Colors.primaryText : Colors.foreground
}
}
Text {
text: entry.modelData.label
font.family: Appearance.fontFamily
font.pixelSize: Appearance.fontSize
color: entryMouse.containsMouse ? Colors.primaryText : Colors.foreground
}
}
MouseArea {
id: entryMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
proc.command = entry.modelData.cmd
proc.running = true
menu.visible = false
MouseArea {
id: entryMouse
anchors.fill: parent
enabled: !entry.modelData.disabled
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
proc.command = entry.modelData.cmd
proc.running = true
menu.visible = false
grab.active = false
}
}
}
}