session menu: only show on focused monitor

This commit is contained in:
end-4
2025-05-18 00:37:08 +02:00
parent 4626ab2bb2
commit 5af7ede329
+181 -203
View File
@@ -4,198 +4,191 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Hyprland
import Quickshell.Io import Quickshell.Io
import Quickshell.Wayland
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Wayland
import Quickshell.Hyprland
Scope { Scope {
id: root id: root
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
Variants { Loader {
id: sessionVariants id: sessionLoader
model: Quickshell.screens active: false
Loader { PanelWindow { // Session menu
id: sessionLoader id: sessionRoot
property var modelData visible: sessionLoader.active
active: false property string subtitle
PanelWindow { // Session menu
id: sessionRoot
visible: sessionLoader.active
function hide() {
sessionLoader.active = false
}
property string subtitle
screen: modelData
exclusionMode: ExclusionMode.Ignore
WlrLayershell.namespace: "quickshell:session"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
color: Appearance.transparentize(Appearance.m3colors.m3background, 0.3)
anchors {
top: true
left: true
right: true
}
implicitWidth: modelData.width
implicitHeight: modelData.height
MouseArea {
id: sessionMouseArea
anchors.fill: parent
onClicked: {
sessionRoot.hide()
}
}
ColumnLayout { // Content column
anchors.centerIn: parent
spacing: 15
Keys.onPressed: (event) => {
if (event.key === Qt.Key_Escape) {
sessionRoot.hide();
}
}
ColumnLayout {
Layout.alignment: Qt.AlignHCenter
spacing: 0
StyledText { // Title
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
font.family: Appearance.font.family.title
font.pixelSize: Appearance.font.pixelSize.title
font.weight: Font.DemiBold
text: qsTr("Session")
}
StyledText { // Small instruction
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
font.family: Appearance.font.family.title
font.pixelSize: Appearance.font.pixelSize.normal
text: qsTr("Arrow keys to navigate, Enter to select\nEsc or click anywhere to cancel")
}
}
RowLayout { // First row of buttons
spacing: 15
SessionActionButton {
id: sessionLock
focus: sessionRoot.visible
buttonIcon: "lock"
buttonText: qsTr("Lock")
onClicked: { Hyprland.dispatch("exec loginctl lock-session"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.right: sessionSleep
KeyNavigation.down: sessionHibernate
}
SessionActionButton {
id: sessionSleep
buttonIcon: "dark_mode"
buttonText: qsTr("Sleep")
onClicked: { Hyprland.dispatch("exec systemctl suspend || loginctl suspend"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionLock
KeyNavigation.right: sessionLogout
KeyNavigation.down: sessionShutdown
}
SessionActionButton {
id: sessionLogout
buttonIcon: "logout"
buttonText: qsTr("Logout")
onClicked: { Hyprland.dispatch("exec pkill Hyprland"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionSleep
KeyNavigation.right: sessionTaskManager
KeyNavigation.down: sessionReboot
}
SessionActionButton {
id: sessionTaskManager
buttonIcon: "browse_activity"
buttonText: qsTr("Task Manager")
onClicked: { Hyprland.dispatch("exec gnome-system-monitor & disown"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionLogout
KeyNavigation.down: sessionFirmwareReboot
}
}
RowLayout { // Second row of buttons
spacing: 15
SessionActionButton {
id: sessionHibernate
buttonIcon: "downloading"
buttonText: qsTr("Hibernate")
onClicked: { Hyprland.dispatch("exec systemctl hibernate || loginctl hibernate"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.up: sessionLock
KeyNavigation.right: sessionShutdown
}
SessionActionButton {
id: sessionShutdown
buttonIcon: "power_settings_new"
buttonText: qsTr("Shutdown")
onClicked: { Hyprland.dispatch("exec systemctl poweroff || loginctl poweroff"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionHibernate
KeyNavigation.right: sessionReboot
KeyNavigation.up: sessionSleep
}
SessionActionButton {
id: sessionReboot
buttonIcon: "restart_alt"
buttonText: qsTr("Reboot")
onClicked: { Hyprland.dispatch("exec reboot || loginctl reboot"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionShutdown
KeyNavigation.right: sessionFirmwareReboot
KeyNavigation.up: sessionLogout
}
SessionActionButton {
id: sessionFirmwareReboot
buttonIcon: "settings_applications"
buttonText: qsTr("Reboot to firmware settings")
onClicked: { Hyprland.dispatch("exec systemctl reboot --firmware-setup || loginctl reboot --firmware-setup"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.up: sessionTaskManager
KeyNavigation.left: sessionReboot
}
}
Rectangle {
Layout.alignment: Qt.AlignHCenter
radius: Appearance.rounding.normal
implicitHeight: sessionSubtitle.implicitHeight + 10 * 2
implicitWidth: sessionSubtitle.implicitWidth + 15 * 2
color: Appearance.colors.colTooltip
clip: true
Behavior on implicitWidth {
SmoothedAnimation {
velocity: Appearance.animation.elementMoveFast.velocity
}
}
StyledText {
id: sessionSubtitle
anchors.centerIn: parent
color: Appearance.colors.colOnTooltip
text: sessionRoot.subtitle
}
}
}
function hide() {
sessionLoader.active = false
} }
exclusionMode: ExclusionMode.Ignore
WlrLayershell.namespace: "quickshell:session"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
color: Appearance.transparentize(Appearance.m3colors.m3background, 0.3)
anchors {
top: true
left: true
right: true
}
implicitWidth: root.focusedScreen?.width ?? 0
implicitHeight: root.focusedScreen?.height ?? 0
MouseArea {
id: sessionMouseArea
anchors.fill: parent
onClicked: {
sessionRoot.hide()
}
}
ColumnLayout { // Content column
anchors.centerIn: parent
spacing: 15
Keys.onPressed: (event) => {
if (event.key === Qt.Key_Escape) {
sessionRoot.hide();
}
}
ColumnLayout {
Layout.alignment: Qt.AlignHCenter
spacing: 0
StyledText { // Title
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
font.family: Appearance.font.family.title
font.pixelSize: Appearance.font.pixelSize.title
font.weight: Font.DemiBold
text: qsTr("Session")
}
StyledText { // Small instruction
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
font.family: Appearance.font.family.title
font.pixelSize: Appearance.font.pixelSize.normal
text: qsTr("Arrow keys to navigate, Enter to select\nEsc or click anywhere to cancel")
}
}
RowLayout { // First row of buttons
spacing: 15
SessionActionButton {
id: sessionLock
focus: sessionRoot.visible
buttonIcon: "lock"
buttonText: qsTr("Lock")
onClicked: { Hyprland.dispatch("exec loginctl lock-session"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.right: sessionSleep
KeyNavigation.down: sessionHibernate
}
SessionActionButton {
id: sessionSleep
buttonIcon: "dark_mode"
buttonText: qsTr("Sleep")
onClicked: { Hyprland.dispatch("exec systemctl suspend || loginctl suspend"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionLock
KeyNavigation.right: sessionLogout
KeyNavigation.down: sessionShutdown
}
SessionActionButton {
id: sessionLogout
buttonIcon: "logout"
buttonText: qsTr("Logout")
onClicked: { Hyprland.dispatch("exec pkill Hyprland"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionSleep
KeyNavigation.right: sessionTaskManager
KeyNavigation.down: sessionReboot
}
SessionActionButton {
id: sessionTaskManager
buttonIcon: "browse_activity"
buttonText: qsTr("Task Manager")
onClicked: { Hyprland.dispatch("exec gnome-system-monitor & disown"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionLogout
KeyNavigation.down: sessionFirmwareReboot
}
}
RowLayout { // Second row of buttons
spacing: 15
SessionActionButton {
id: sessionHibernate
buttonIcon: "downloading"
buttonText: qsTr("Hibernate")
onClicked: { Hyprland.dispatch("exec systemctl hibernate || loginctl hibernate"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.up: sessionLock
KeyNavigation.right: sessionShutdown
}
SessionActionButton {
id: sessionShutdown
buttonIcon: "power_settings_new"
buttonText: qsTr("Shutdown")
onClicked: { Hyprland.dispatch("exec systemctl poweroff || loginctl poweroff"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionHibernate
KeyNavigation.right: sessionReboot
KeyNavigation.up: sessionSleep
}
SessionActionButton {
id: sessionReboot
buttonIcon: "restart_alt"
buttonText: qsTr("Reboot")
onClicked: { Hyprland.dispatch("exec reboot || loginctl reboot"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionShutdown
KeyNavigation.right: sessionFirmwareReboot
KeyNavigation.up: sessionLogout
}
SessionActionButton {
id: sessionFirmwareReboot
buttonIcon: "settings_applications"
buttonText: qsTr("Reboot to firmware settings")
onClicked: { Hyprland.dispatch("exec systemctl reboot --firmware-setup || loginctl reboot --firmware-setup"); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.up: sessionTaskManager
KeyNavigation.left: sessionReboot
}
}
Rectangle {
Layout.alignment: Qt.AlignHCenter
radius: Appearance.rounding.normal
implicitHeight: sessionSubtitle.implicitHeight + 10 * 2
implicitWidth: sessionSubtitle.implicitWidth + 15 * 2
color: Appearance.colors.colTooltip
clip: true
Behavior on implicitWidth {
SmoothedAnimation {
velocity: Appearance.animation.elementMoveFast.velocity
}
}
StyledText {
id: sessionSubtitle
anchors.centerIn: parent
color: Appearance.colors.colOnTooltip
text: sessionRoot.subtitle
}
}
}
} }
} }
@@ -203,24 +196,15 @@ Scope {
target: "session" target: "session"
function toggle(): void { function toggle(): void {
for (let i = 0; i < sessionVariants.instances.length; i++) { sessionLoader.active = !sessionLoader.active;
let loader = sessionVariants.instances[i];
loader.active = !loader.active;
}
} }
function close(): void { function close(): void {
for (let i = 0; i < sessionVariants.instances.length; i++) { sessionLoader.active = false;
let loader = sessionVariants.instances[i];
loader.active = false;
}
} }
function open(): void { function open(): void {
for (let i = 0; i < sessionVariants.instances.length; i++) { sessionLoader.active = true;
let loader = sessionVariants.instances[i];
loader.active = true;
}
} }
} }
@@ -229,10 +213,7 @@ Scope {
description: "Toggles session screen on press" description: "Toggles session screen on press"
onPressed: { onPressed: {
for (let i = 0; i < sessionVariants.instances.length; i++) { sessionLoader.active = !sessionLoader.active;
let loader = sessionVariants.instances[i];
loader.active = !loader.active;
}
} }
} }
@@ -241,10 +222,7 @@ Scope {
description: "Opens session screen on press" description: "Opens session screen on press"
onPressed: { onPressed: {
for (let i = 0; i < sessionVariants.instances.length; i++) { sessionLoader.active = true;
let loader = sessionVariants.instances[i];
loader.active = !loader.active;
}
} }
} }