180 lines
6.9 KiB
QML
180 lines
6.9 KiB
QML
import QtQuick
|
|
import QtQuick.Layouts
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Hyprland
|
|
import "../../config"
|
|
|
|
Item {
|
|
id: root
|
|
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
|
|
font.family: Appearance.iconFontFamily
|
|
font.variableAxes: Appearance.iconFontAxes
|
|
font.pixelSize: 16
|
|
color: Colors.foreground
|
|
text: "power_settings_new"
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: {
|
|
menu.visible = !menu.visible
|
|
grab.active = menu.visible
|
|
}
|
|
}
|
|
|
|
Process { id: proc }
|
|
|
|
PopupWindow {
|
|
id: menu
|
|
visible: false
|
|
color: "transparent"
|
|
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 {
|
|
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.bottom: -4
|
|
margins.right: 0
|
|
}
|
|
|
|
HyprlandFocusGrab {
|
|
id: grab
|
|
windows: [menu]
|
|
onCleared: menu.visible = false
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
radius: 0
|
|
color: Colors.surface
|
|
border.color: Colors.muted
|
|
border.width: 3
|
|
|
|
Column {
|
|
id: mainColumn
|
|
anchors.fill: parent
|
|
anchors.margins: menu.contentPadding
|
|
spacing: 10
|
|
|
|
// 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
|
|
|
|
Text {
|
|
text: label.text
|
|
font.family: Appearance.iconFontFamily
|
|
font.variableAxes: Appearance.iconFontAxes
|
|
font.pixelSize: 30
|
|
color: 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
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|