diff --git a/Shell/Windows/QuickSettings/QuickSettingsApp.qml b/Shell/Windows/QuickSettings/QuickSettingsApp.qml index a1fe1df..7681501 100644 --- a/Shell/Windows/QuickSettings/QuickSettingsApp.qml +++ b/Shell/Windows/QuickSettings/QuickSettingsApp.qml @@ -37,6 +37,8 @@ Item { property bool inBluetoothMenu: false property bool inWallpaperMenu: false property bool inNotificationsMenu: false + property bool inPowerMenu: false + property bool inPowerConfirm: false property bool isSelected: false @@ -82,7 +84,7 @@ Item { } function currentAction() { - if (root.inBluetoothMenu || root.inWallpaperMenu || root.inNotificationsMenu) + if (root.inBluetoothMenu || root.inWallpaperMenu || root.inNotificationsMenu || root.inPowerMenu) return null; return menuLength() > 0 ? menuAt(activeSelection) : null; } @@ -197,6 +199,9 @@ Item { property int bluetoothActionIndex: 1 property int wallpaperActionIndex: 2 property int notificationsActionIndex: 3 + property int powerActionIndex: 4 + property int pendingPowerActionIndex: 0 + property var pendingPowerCommand: [] property var actions: [ { name: "Master Volume", @@ -252,6 +257,8 @@ Item { root.inNotificationsMenu = true; root.inBluetoothMenu = false; root.inWallpaperMenu = false; + root.inPowerMenu = false; + root.inPowerConfirm = false; root.isSelected = false; root.activeSelection = 0; root.clampSelection(); @@ -259,6 +266,48 @@ Item { getState: function () { return ""; } + }, + { + name: "Power", + ent: function () { + root.inPowerMenu = true; + root.inPowerConfirm = false; + root.inBluetoothMenu = false; + root.inWallpaperMenu = false; + root.inNotificationsMenu = false; + root.isSelected = false; + root.activeSelection = 0; + root.pendingPowerActionIndex = 0; + root.pendingPowerCommand = []; + root.clampSelection(); + }, + getState: function () { + return ""; + } + } + ] + + property var powerActions: [ + { + name: "Shutdown", + command: ["systemctl", "poweroff"] + }, + { + name: "Reboot", + command: ["systemctl", "reboot"] + }, + { + name: "Logout", + command: ["hyprctl", "dispatch", "exit"] + } + ] + + property var powerConfirmActions: [ + { + name: "Yes" + }, + { + name: "No" } ] @@ -277,7 +326,7 @@ Item { } ] - property var menuModel: root.inBluetoothMenu ? Bluetooth.devices : (root.inWallpaperMenu ? wallpaperFolderModel : (root.inNotificationsMenu ? notificationActions : actions)) + property var menuModel: root.inBluetoothMenu ? Bluetooth.devices : (root.inWallpaperMenu ? wallpaperFolderModel : (root.inNotificationsMenu ? notificationActions : (root.inPowerMenu ? (root.inPowerConfirm ? powerConfirmActions : powerActions) : actions))) FolderListModel { id: wallpaperFolderModel @@ -308,6 +357,27 @@ Item { id: wallpaperApplyProcess } + Process { + id: powerCommandProcess + } + + function executePowerCommand(command) { + if (!command || command.length === 0) + return; + powerCommandProcess.running = false; + powerCommandProcess.command = command; + powerCommandProcess.running = true; + if (manager && manager.closeShell) + manager.closeShell(); + } + + function pendingPowerActionName() { + if (pendingPowerActionIndex < 0 || pendingPowerActionIndex >= powerActions.length) + return ""; + var action = powerActions[pendingPowerActionIndex]; + return action && action.name ? String(action.name) : ""; + } + Connections { target: Bluetooth.devices ignoreUnknownSignals: true @@ -353,7 +423,7 @@ Item { } Text { - text: root.inBluetoothMenu ? "BLUETOOTH" : (root.inWallpaperMenu ? "WALLPAPER" : (root.inNotificationsMenu ? "NOTIFICATIONS" : "CONFIG")) + text: root.inPowerConfirm ? "CONFIRM" : (root.inPowerMenu ? "POWER" : (root.inBluetoothMenu ? "BLUETOOTH" : (root.inWallpaperMenu ? "WALLPAPER" : (root.inNotificationsMenu ? "NOTIFICATIONS" : "CONFIG")))) font.family: "8bitoperator JVE" font.pixelSize: 71 renderType: Text.NativeRendering @@ -365,6 +435,20 @@ Item { y: 32 } + Text { + visible: root.inPowerConfirm + text: root.pendingPowerActionName().toUpperCase() + "?" + font.family: "8bitoperator JVE" + font.pixelSize: 44 + renderType: Text.NativeRendering + font.hintingPreference: Font.PreferNoHinting + smooth: false + antialiasing: false + anchors.horizontalCenter: parent.horizontalCenter + color: "#fefe00" + y: 102 + } + Repeater { id: bluetoothRepeater model: root.menuModel @@ -401,7 +485,7 @@ Item { antialiasing: false wrapMode: Text.NoWrap elide: Text.ElideRight - color: (root.activeSelection == index && (root.isSelected == true || root.inBluetoothMenu || root.inWallpaperMenu)) ? "#fefe00" : "#ffffff" + color: (root.activeSelection == index && (root.isSelected == true || root.inBluetoothMenu || root.inWallpaperMenu || root.inPowerMenu)) ? "#fefe00" : "#ffffff" } // Option state @@ -417,7 +501,7 @@ Item { font.hintingPreference: Font.PreferNoHinting smooth: false antialiasing: false - color: (root.activeSelection == index && (root.isSelected == true || root.inBluetoothMenu || root.inWallpaperMenu)) ? "#fefe00" : "#ffffff" + color: (root.activeSelection == index && (root.isSelected == true || root.inBluetoothMenu || root.inWallpaperMenu || root.inPowerMenu)) ? "#fefe00" : "#ffffff" } } } @@ -429,13 +513,13 @@ Item { function handleKey(key) { switch (key) { case Qt.Key_Up: - if (root.inBluetoothMenu || root.inWallpaperMenu || root.isSelected === false) { + if (root.inBluetoothMenu || root.inWallpaperMenu || root.inPowerMenu || root.isSelected === false) { activeSelection = wrapIndex(activeSelection - 1); root.ensureVisible(); } return true; case Qt.Key_Down: - if (root.inBluetoothMenu || root.inWallpaperMenu || root.isSelected === false) { + if (root.inBluetoothMenu || root.inWallpaperMenu || root.inPowerMenu || root.isSelected === false) { activeSelection = wrapIndex(activeSelection + 1); root.ensureVisible(); } @@ -477,6 +561,24 @@ Item { const notificationAction = menuAt(activeSelection); if (notificationAction && notificationAction.ent) notificationAction.ent(); + } else if (root.inPowerConfirm) { + const confirmAction = menuAt(activeSelection); + if (confirmAction && confirmAction.name === "Yes") { + root.executePowerCommand(root.pendingPowerCommand); + } else { + root.inPowerConfirm = false; + root.activeSelection = root.pendingPowerActionIndex; + root.clampSelection(); + } + } else if (root.inPowerMenu) { + const powerAction = menuAt(activeSelection); + if (powerAction && powerAction.command) { + root.pendingPowerActionIndex = activeSelection; + root.pendingPowerCommand = powerAction.command; + root.inPowerConfirm = true; + root.activeSelection = 0; + root.clampSelection(); + } } else { const a = currentAction(); if (a && a.ent) { @@ -496,6 +598,19 @@ Item { root.scrollOffset = 0; root.activeSelection = root.wallpaperActionIndex; root.clampSelection(); + } else if (root.inPowerConfirm) { + root.inPowerConfirm = false; + root.isSelected = false; + root.activeSelection = root.pendingPowerActionIndex; + root.clampSelection(); + } else if (root.inPowerMenu) { + root.inPowerMenu = false; + root.inPowerConfirm = false; + root.isSelected = false; + root.pendingPowerActionIndex = 0; + root.pendingPowerCommand = []; + root.activeSelection = root.powerActionIndex; + root.clampSelection(); } else if (root.inNotificationsMenu) { root.inNotificationsMenu = false; root.isSelected = false; @@ -524,6 +639,10 @@ Item { root.inBluetoothMenu = false; root.inWallpaperMenu = false; root.inNotificationsMenu = false; + root.inPowerMenu = false; + root.inPowerConfirm = false; + root.pendingPowerActionIndex = 0; + root.pendingPowerCommand = []; root.scrollOffset = 0; root.refreshCurrentWallpaper(); ShellInputManager.registerHandler("quickSettings", handleKey);