mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 13:32:50 -05:00
feat: PowerMenu modal
This commit is contained in:
@@ -12,14 +12,27 @@ DankModal {
|
|||||||
property string powerConfirmAction: ""
|
property string powerConfirmAction: ""
|
||||||
property string powerConfirmTitle: ""
|
property string powerConfirmTitle: ""
|
||||||
property string powerConfirmMessage: ""
|
property string powerConfirmMessage: ""
|
||||||
|
property int selectedButton: -1 // -1 = none, 0 = Cancel, 1 = Confirm
|
||||||
|
property bool keyboardNavigation: false
|
||||||
|
|
||||||
function show(action, title, message) {
|
function show(action, title, message) {
|
||||||
powerConfirmAction = action
|
powerConfirmAction = action
|
||||||
powerConfirmTitle = title
|
powerConfirmTitle = title
|
||||||
powerConfirmMessage = message
|
powerConfirmMessage = message
|
||||||
|
selectedButton = -1 // No button selected initially
|
||||||
|
keyboardNavigation = false
|
||||||
open()
|
open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectButton() {
|
||||||
|
if (selectedButton === 0) {
|
||||||
|
close()
|
||||||
|
} else {
|
||||||
|
close()
|
||||||
|
executePowerAction(powerConfirmAction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function executePowerAction(action) {
|
function executePowerAction(action) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "logout":
|
case "logout":
|
||||||
@@ -44,6 +57,35 @@ DankModal {
|
|||||||
onBackgroundClicked: {
|
onBackgroundClicked: {
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
onOpened: {
|
||||||
|
modalFocusScope.forceActiveFocus()
|
||||||
|
}
|
||||||
|
modalFocusScope.Keys.onPressed: function(event) {
|
||||||
|
switch (event.key) {
|
||||||
|
case Qt.Key_Left:
|
||||||
|
case Qt.Key_Up:
|
||||||
|
keyboardNavigation = true
|
||||||
|
selectedButton = 0
|
||||||
|
event.accepted = true
|
||||||
|
break
|
||||||
|
case Qt.Key_Right:
|
||||||
|
case Qt.Key_Down:
|
||||||
|
keyboardNavigation = true
|
||||||
|
selectedButton = 1
|
||||||
|
event.accepted = true
|
||||||
|
break
|
||||||
|
case Qt.Key_Tab:
|
||||||
|
keyboardNavigation = true
|
||||||
|
selectedButton = selectedButton === -1 ? 0 : (selectedButton + 1) % 2
|
||||||
|
event.accepted = true
|
||||||
|
break
|
||||||
|
case Qt.Key_Return:
|
||||||
|
case Qt.Key_Enter:
|
||||||
|
selectButton()
|
||||||
|
event.accepted = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
content: Component {
|
content: Component {
|
||||||
Item {
|
Item {
|
||||||
@@ -93,7 +135,16 @@ DankModal {
|
|||||||
width: 120
|
width: 120
|
||||||
height: 40
|
height: 40
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: cancelButton.containsMouse ? Theme.surfaceTextPressed : Theme.surfaceVariantAlpha
|
color: {
|
||||||
|
if (keyboardNavigation && selectedButton === 0)
|
||||||
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
|
||||||
|
else if (cancelButton.containsMouse)
|
||||||
|
return Theme.surfacePressed
|
||||||
|
else
|
||||||
|
return Theme.surfaceVariantAlpha
|
||||||
|
}
|
||||||
|
border.color: (keyboardNavigation && selectedButton === 0) ? Theme.primary : "transparent"
|
||||||
|
border.width: (keyboardNavigation && selectedButton === 0) ? 1 : 0
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Cancel"
|
text: "Cancel"
|
||||||
@@ -110,9 +161,11 @@ DankModal {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
close()
|
selectedButton = 0
|
||||||
|
selectButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -132,12 +185,15 @@ DankModal {
|
|||||||
baseColor = Theme.primary
|
baseColor = Theme.primary
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return confirmButton.containsMouse ? Qt.rgba(
|
if (keyboardNavigation && selectedButton === 1)
|
||||||
baseColor.r,
|
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 1)
|
||||||
baseColor.g,
|
else if (confirmButton.containsMouse)
|
||||||
baseColor.b,
|
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, 0.9)
|
||||||
0.9) : baseColor
|
else
|
||||||
|
return baseColor
|
||||||
}
|
}
|
||||||
|
border.color: (keyboardNavigation && selectedButton === 1) ? "white" : "transparent"
|
||||||
|
border.width: (keyboardNavigation && selectedButton === 1) ? 1 : 0
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: "Confirm"
|
text: "Confirm"
|
||||||
@@ -154,13 +210,19 @@ DankModal {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
close()
|
selectedButton = 1
|
||||||
executePowerAction(powerConfirmAction)
|
selectButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
337
Modals/PowerMenuModal.qml
Normal file
337
Modals/PowerMenuModal.qml
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
DankModal {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int selectedIndex: 0
|
||||||
|
property int optionCount: 4
|
||||||
|
|
||||||
|
signal powerActionRequested(string action, string title, string message)
|
||||||
|
|
||||||
|
function selectOption() {
|
||||||
|
close()
|
||||||
|
switch (selectedIndex) {
|
||||||
|
case 0:
|
||||||
|
root.powerActionRequested("logout", "Log Out", "Are you sure you want to log out?")
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
root.powerActionRequested("suspend", "Suspend", "Are you sure you want to suspend the system?")
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
root.powerActionRequested("reboot", "Reboot", "Are you sure you want to reboot the system?")
|
||||||
|
break
|
||||||
|
case 3:
|
||||||
|
root.powerActionRequested("poweroff", "Power Off", "Are you sure you want to power off the system?")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldBeVisible: false
|
||||||
|
width: 320
|
||||||
|
height: 300
|
||||||
|
enableShadow: true
|
||||||
|
onBackgroundClicked: {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
onOpened: {
|
||||||
|
selectedIndex = 0
|
||||||
|
modalFocusScope.forceActiveFocus()
|
||||||
|
}
|
||||||
|
modalFocusScope.Keys.onPressed: function(event) {
|
||||||
|
switch (event.key) {
|
||||||
|
case Qt.Key_Up:
|
||||||
|
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount
|
||||||
|
event.accepted = true
|
||||||
|
break
|
||||||
|
case Qt.Key_Down:
|
||||||
|
selectedIndex = (selectedIndex + 1) % optionCount
|
||||||
|
event.accepted = true
|
||||||
|
break
|
||||||
|
case Qt.Key_Tab:
|
||||||
|
selectedIndex = (selectedIndex + 1) % optionCount
|
||||||
|
event.accepted = true
|
||||||
|
break
|
||||||
|
case Qt.Key_Return:
|
||||||
|
case Qt.Key_Enter:
|
||||||
|
selectOption()
|
||||||
|
event.accepted = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
content: Component {
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingL
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Power Options"
|
||||||
|
font.pixelSize: Theme.fontSizeLarge
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width - 150
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
iconName: "close"
|
||||||
|
iconSize: Theme.iconSize - 4
|
||||||
|
iconColor: Theme.surfaceText
|
||||||
|
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
||||||
|
onClicked: {
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 50
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: {
|
||||||
|
if (selectedIndex === 0)
|
||||||
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
|
||||||
|
else if (logoutArea.containsMouse)
|
||||||
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
|
||||||
|
else
|
||||||
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
|
||||||
|
}
|
||||||
|
border.color: selectedIndex === 0 ? Theme.primary : "transparent"
|
||||||
|
border.width: selectedIndex === 0 ? 1 : 0
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "logout"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Log Out"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: logoutArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
selectedIndex = 0
|
||||||
|
selectOption()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 50
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: {
|
||||||
|
if (selectedIndex === 1)
|
||||||
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
|
||||||
|
else if (suspendArea.containsMouse)
|
||||||
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
|
||||||
|
else
|
||||||
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
|
||||||
|
}
|
||||||
|
border.color: selectedIndex === 1 ? Theme.primary : "transparent"
|
||||||
|
border.width: selectedIndex === 1 ? 1 : 0
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "bedtime"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Suspend"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: suspendArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
selectedIndex = 1
|
||||||
|
selectOption()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 50
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: {
|
||||||
|
if (selectedIndex === 2)
|
||||||
|
return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.12);
|
||||||
|
else if (rebootArea.containsMouse)
|
||||||
|
return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.08);
|
||||||
|
else
|
||||||
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
|
||||||
|
}
|
||||||
|
border.color: selectedIndex === 2 ? Theme.warning : "transparent"
|
||||||
|
border.width: selectedIndex === 2 ? 1 : 0
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "restart_alt"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Reboot"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: rebootArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
selectedIndex = 2
|
||||||
|
selectOption()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 50
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: {
|
||||||
|
if (selectedIndex === 3)
|
||||||
|
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12);
|
||||||
|
else if (powerOffArea.containsMouse)
|
||||||
|
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.08);
|
||||||
|
else
|
||||||
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
|
||||||
|
}
|
||||||
|
border.color: selectedIndex === 3 ? Theme.error : "transparent"
|
||||||
|
border.width: selectedIndex === 3 ? 1 : 0
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.spacingM
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "power_settings_new"
|
||||||
|
size: Theme.iconSize
|
||||||
|
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Power Off"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: powerOffArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
selectedIndex = 3
|
||||||
|
selectOption()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
height: Theme.spacingS
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "↑↓ Navigate • Tab Cycle • Enter Select • Esc Close"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
opacity: 0.7
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -301,6 +301,9 @@ binds {
|
|||||||
Super+Alt+L hotkey-overlay-title="Lock Screen" {
|
Super+Alt+L hotkey-overlay-title="Lock Screen" {
|
||||||
spawn "qs" "-c" "dms" "ipc" "call" "lock" "lock";
|
spawn "qs" "-c" "dms" "ipc" "call" "lock" "lock";
|
||||||
}
|
}
|
||||||
|
Mod+X hotkey-overlay-title="Power Menu" {
|
||||||
|
spawn "qs" "-c" "dms" "ipc" "call" "powermenu" "toggle";
|
||||||
|
}
|
||||||
XF86AudioRaiseVolume allow-when-locked=true {
|
XF86AudioRaiseVolume allow-when-locked=true {
|
||||||
spawn "qs" "-c" "dms" "ipc" "call" "audio" "increment" "3";
|
spawn "qs" "-c" "dms" "ipc" "call" "audio" "increment" "3";
|
||||||
}
|
}
|
||||||
@@ -351,6 +354,7 @@ bind = SUPER, M, exec, qs -c dms ipc call processlist toggle
|
|||||||
bind = SUPER, N, exec, qs -c dms ipc call notifications toggle
|
bind = SUPER, N, exec, qs -c dms ipc call notifications toggle
|
||||||
bind = SUPER, comma, exec, qs -c dms ipc call settings toggle
|
bind = SUPER, comma, exec, qs -c dms ipc call settings toggle
|
||||||
bind = SUPERALT, L, exec, qs -c dms ipc call lock lock
|
bind = SUPERALT, L, exec, qs -c dms ipc call lock lock
|
||||||
|
bind = SUPER, X, exec, qs -c dms ipc call powermenu toggle
|
||||||
|
|
||||||
# Audio controls (function keys)
|
# Audio controls (function keys)
|
||||||
bindl = , XF86AudioRaiseVolume, exec, qs -c dms ipc call audio increment 3
|
bindl = , XF86AudioRaiseVolume, exec, qs -c dms ipc call audio increment 3
|
||||||
@@ -378,6 +382,7 @@ qs -c dms ipc call audio mute
|
|||||||
```bash
|
```bash
|
||||||
qs -c dms ipc call spotlight toggle
|
qs -c dms ipc call spotlight toggle
|
||||||
qs -c dms ipc call processlist toggle
|
qs -c dms ipc call processlist toggle
|
||||||
|
qs -c dms ipc call powermenu toggle
|
||||||
```
|
```
|
||||||
# System control
|
# System control
|
||||||
```
|
```
|
||||||
|
|||||||
12
docs/IPC.md
12
docs/IPC.md
@@ -361,6 +361,14 @@ System process list and performance modal control.
|
|||||||
- `close` - Hide process list modal
|
- `close` - Hide process list modal
|
||||||
- `toggle` - Toggle process list modal visibility
|
- `toggle` - Toggle process list modal visibility
|
||||||
|
|
||||||
|
### Target: `powermenu`
|
||||||
|
Power menu modal control for system power actions.
|
||||||
|
|
||||||
|
**Functions:**
|
||||||
|
- `open` - Show power menu modal
|
||||||
|
- `close` - Hide power menu modal
|
||||||
|
- `toggle` - Toggle power menu modal visibility
|
||||||
|
|
||||||
### Modal Examples
|
### Modal Examples
|
||||||
```bash
|
```bash
|
||||||
# Open application launcher
|
# Open application launcher
|
||||||
@@ -377,6 +385,9 @@ qs -c dms ipc call settings open
|
|||||||
|
|
||||||
# Show system monitor
|
# Show system monitor
|
||||||
qs -c dms ipc call processlist toggle
|
qs -c dms ipc call processlist toggle
|
||||||
|
|
||||||
|
# Show power menu
|
||||||
|
qs -c dms ipc call powermenu toggle
|
||||||
```
|
```
|
||||||
|
|
||||||
## Common Usage Patterns
|
## Common Usage Patterns
|
||||||
@@ -389,6 +400,7 @@ These IPC commands are designed to be used with window manager keybindings. Exam
|
|||||||
binds {
|
binds {
|
||||||
Mod+Space { spawn "qs" "-c" "dms" "ipc" "call" "spotlight" "toggle"; }
|
Mod+Space { spawn "qs" "-c" "dms" "ipc" "call" "spotlight" "toggle"; }
|
||||||
Mod+V { spawn "qs" "-c" "dms" "ipc" "call" "clipboard" "toggle"; }
|
Mod+V { spawn "qs" "-c" "dms" "ipc" "call" "clipboard" "toggle"; }
|
||||||
|
Mod+X { spawn "qs" "-c" "dms" "ipc" "call" "powermenu" "toggle"; }
|
||||||
XF86AudioRaiseVolume { spawn "qs" "-c" "dms" "ipc" "call" "audio" "increment" "3"; }
|
XF86AudioRaiseVolume { spawn "qs" "-c" "dms" "ipc" "call" "audio" "increment" "3"; }
|
||||||
XF86MonBrightnessUp { spawn "qs" "-c" "dms" "ipc" "call" "brightness" "increment" "5" ""; }
|
XF86MonBrightnessUp { spawn "qs" "-c" "dms" "ipc" "call" "brightness" "increment" "5" ""; }
|
||||||
}
|
}
|
||||||
|
|||||||
115
shell.qml
115
shell.qml
@@ -3,22 +3,22 @@ import QtQuick
|
|||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
|
import qs.Common
|
||||||
import qs.Modals
|
import qs.Modals
|
||||||
import qs.Modules
|
import qs.Modules
|
||||||
import qs.Modules.AppDrawer
|
import qs.Modules.AppDrawer
|
||||||
import qs.Modules.OSD
|
|
||||||
import qs.Modules.CentcomCenter
|
import qs.Modules.CentcomCenter
|
||||||
import qs.Modules.ControlCenter
|
import qs.Modules.ControlCenter
|
||||||
import qs.Modules.ControlCenter.Network
|
import qs.Modules.ControlCenter.Network
|
||||||
|
import qs.Modules.Dock
|
||||||
import qs.Modules.Lock
|
import qs.Modules.Lock
|
||||||
import qs.Modules.Notifications.Center
|
import qs.Modules.Notifications.Center
|
||||||
import qs.Modules.Notifications.Popup
|
import qs.Modules.Notifications.Popup
|
||||||
|
import qs.Modules.OSD
|
||||||
import qs.Modules.ProcessList
|
import qs.Modules.ProcessList
|
||||||
import qs.Modules.Settings
|
import qs.Modules.Settings
|
||||||
import qs.Modules.TopBar
|
import qs.Modules.TopBar
|
||||||
import qs.Modules.Dock
|
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Common
|
|
||||||
|
|
||||||
ShellRoot {
|
ShellRoot {
|
||||||
id: root
|
id: root
|
||||||
@@ -27,7 +27,8 @@ ShellRoot {
|
|||||||
PortalService.init()
|
PortalService.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
WallpaperBackground {}
|
WallpaperBackground {
|
||||||
|
}
|
||||||
|
|
||||||
Lock {
|
Lock {
|
||||||
id: lock
|
id: lock
|
||||||
@@ -41,6 +42,7 @@ ShellRoot {
|
|||||||
delegate: TopBar {
|
delegate: TopBar {
|
||||||
modelData: item
|
modelData: item
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
@@ -49,40 +51,47 @@ ShellRoot {
|
|||||||
delegate: Dock {
|
delegate: Dock {
|
||||||
modelData: item
|
modelData: item
|
||||||
contextMenu: dockContextMenuLoader.item ? dockContextMenuLoader.item : null
|
contextMenu: dockContextMenuLoader.item ? dockContextMenuLoader.item : null
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
dockContextMenuLoader.active = true
|
dockContextMenuLoader.active = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: centcomPopoutLoader
|
id: centcomPopoutLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
sourceComponent: Component {
|
sourceComponent: Component {
|
||||||
CentcomPopout {
|
CentcomPopout {
|
||||||
id: centcomPopout
|
id: centcomPopout
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: dockContextMenuLoader
|
id: dockContextMenuLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
DockContextMenu {
|
DockContextMenu {
|
||||||
id: dockContextMenu
|
id: dockContextMenu
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: notificationCenterLoader
|
id: notificationCenterLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
NotificationCenterPopout {
|
NotificationCenterPopout {
|
||||||
id: notificationCenter
|
id: notificationCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
@@ -91,87 +100,99 @@ ShellRoot {
|
|||||||
delegate: NotificationPopupManager {
|
delegate: NotificationPopupManager {
|
||||||
modelData: item
|
modelData: item
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: controlCenterLoader
|
id: controlCenterLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
ControlCenterPopout {
|
ControlCenterPopout {
|
||||||
id: controlCenterPopout
|
id: controlCenterPopout
|
||||||
|
|
||||||
onPowerActionRequested: (action, title, message) => {
|
onPowerActionRequested: (action, title, message) => {
|
||||||
powerConfirmModalLoader.active = true
|
powerConfirmModalLoader.active = true
|
||||||
if (powerConfirmModalLoader.item) {
|
if (powerConfirmModalLoader.item)
|
||||||
powerConfirmModalLoader.item.show(
|
powerConfirmModalLoader.item.show(action, title, message)
|
||||||
action, title, message)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
onLockRequested: {
|
onLockRequested: {
|
||||||
lock.activate()
|
lock.activate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: wifiPasswordModalLoader
|
id: wifiPasswordModalLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
WifiPasswordModal {
|
WifiPasswordModal {
|
||||||
id: wifiPasswordModal
|
id: wifiPasswordModal
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: networkInfoModalLoader
|
id: networkInfoModalLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
NetworkInfoModal {
|
NetworkInfoModal {
|
||||||
id: networkInfoModal
|
id: networkInfoModal
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: batteryPopoutLoader
|
id: batteryPopoutLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
BatteryPopout {
|
BatteryPopout {
|
||||||
id: batteryPopout
|
id: batteryPopout
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: powerMenuLoader
|
id: powerMenuLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
PowerMenu {
|
PowerMenu {
|
||||||
id: powerMenu
|
id: powerMenu
|
||||||
|
|
||||||
onPowerActionRequested: (action, title, message) => {
|
onPowerActionRequested: (action, title, message) => {
|
||||||
powerConfirmModalLoader.active = true
|
powerConfirmModalLoader.active = true
|
||||||
if (powerConfirmModalLoader.item) {
|
if (powerConfirmModalLoader.item)
|
||||||
powerConfirmModalLoader.item.show(
|
powerConfirmModalLoader.item.show(action, title, message)
|
||||||
action, title, message)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: powerConfirmModalLoader
|
id: powerConfirmModalLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
PowerConfirmModal {
|
PowerConfirmModal {
|
||||||
id: powerConfirmModal
|
id: powerConfirmModal
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: processListPopoutLoader
|
id: processListPopoutLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
ProcessListPopout {
|
ProcessListPopout {
|
||||||
id: processListPopout
|
id: processListPopout
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsModal {
|
SettingsModal {
|
||||||
@@ -180,11 +201,13 @@ ShellRoot {
|
|||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: appDrawerLoader
|
id: appDrawerLoader
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
AppDrawerPopout {
|
AppDrawerPopout {
|
||||||
id: appDrawerPopout
|
id: appDrawerPopout
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SpotlightModal {
|
SpotlightModal {
|
||||||
@@ -207,6 +230,51 @@ ShellRoot {
|
|||||||
ProcessListModal {
|
ProcessListModal {
|
||||||
id: processListModal
|
id: processListModal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyLoader {
|
||||||
|
id: powerMenuModalLoader
|
||||||
|
|
||||||
|
active: false
|
||||||
|
|
||||||
|
PowerMenuModal {
|
||||||
|
id: powerMenuModal
|
||||||
|
|
||||||
|
onPowerActionRequested: (action, title, message) => {
|
||||||
|
powerConfirmModalLoader.active = true
|
||||||
|
if (powerConfirmModalLoader.item)
|
||||||
|
powerConfirmModalLoader.item.show(action, title, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
function open() {
|
||||||
|
powerMenuModalLoader.active = true
|
||||||
|
if (powerMenuModalLoader.item)
|
||||||
|
powerMenuModalLoader.item.open()
|
||||||
|
|
||||||
|
return "POWERMENU_OPEN_SUCCESS"
|
||||||
|
}
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
if (powerMenuModalLoader.item)
|
||||||
|
powerMenuModalLoader.item.close()
|
||||||
|
|
||||||
|
return "POWERMENU_CLOSE_SUCCESS"
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
powerMenuModalLoader.active = true
|
||||||
|
if (powerMenuModalLoader.item)
|
||||||
|
powerMenuModalLoader.item.toggle()
|
||||||
|
|
||||||
|
return "POWERMENU_TOGGLE_SUCCESS"
|
||||||
|
}
|
||||||
|
|
||||||
|
target: "powermenu"
|
||||||
}
|
}
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
@@ -243,6 +311,7 @@ ShellRoot {
|
|||||||
modelData: item
|
modelData: item
|
||||||
visible: ToastService.toastVisible
|
visible: ToastService.toastVisible
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
@@ -251,17 +320,16 @@ ShellRoot {
|
|||||||
delegate: VolumeOSD {
|
delegate: VolumeOSD {
|
||||||
modelData: item
|
modelData: item
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
model: SettingsData.getFilteredScreens("osd")
|
model: SettingsData.getFilteredScreens("osd")
|
||||||
|
|
||||||
delegate: MicMuteOSD {
|
delegate: MicMuteOSD {
|
||||||
modelData: item
|
modelData: item
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
@@ -270,6 +338,7 @@ ShellRoot {
|
|||||||
delegate: BrightnessOSD {
|
delegate: BrightnessOSD {
|
||||||
modelData: item
|
modelData: item
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
@@ -278,5 +347,7 @@ ShellRoot {
|
|||||||
delegate: IdleInhibitorOSD {
|
delegate: IdleInhibitorOSD {
|
||||||
modelData: item
|
modelData: item
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user