mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 13:32:50 -05:00
Add Desktop Actions to launcher + dock
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
@@ -13,7 +15,7 @@ Rectangle {
|
||||
|
||||
function show(x, y, app) {
|
||||
currentApp = app
|
||||
const menuWidth = 180
|
||||
const menuWidth = Math.max(180, Math.min(300, menuColumn.implicitWidth + Theme.spacingS * 2))
|
||||
const menuHeight = menuColumn.implicitHeight + Theme.spacingS * 2
|
||||
let finalX = x + 8
|
||||
let finalY = y + 8
|
||||
@@ -29,6 +31,7 @@ Rectangle {
|
||||
}
|
||||
contextMenu.x = finalX
|
||||
contextMenu.y = finalY
|
||||
contextMenu.width = menuWidth
|
||||
contextMenu.visible = true
|
||||
contextMenu.menuVisible = true
|
||||
}
|
||||
@@ -144,6 +147,82 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: contextMenu.currentApp && contextMenu.currentApp.desktopEntry && contextMenu.currentApp.desktopEntry.actions ? contextMenu.currentApp.desktopEntry.actions : []
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: actionMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingS
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Theme.iconSize - 2
|
||||
height: Theme.iconSize - 2
|
||||
visible: modelData.icon && modelData.icon !== ""
|
||||
|
||||
IconImage {
|
||||
anchors.fill: parent
|
||||
source: modelData.icon ? Quickshell.iconPath(modelData.icon, true) : ""
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
visible: status === Image.Ready
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: modelData.name || ""
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Normal
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
elide: Text.ElideRight
|
||||
width: parent.width - (modelData.icon && modelData.icon !== "" ? (Theme.iconSize - 2 + Theme.spacingS) : 0)
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: actionMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (modelData && contextMenu.currentApp && contextMenu.currentApp.desktopEntry) {
|
||||
SessionService.launchDesktopAction(contextMenu.currentApp.desktopEntry, modelData)
|
||||
if (appLauncher) {
|
||||
appLauncher.appLaunched(contextMenu.currentApp)
|
||||
}
|
||||
}
|
||||
contextMenu.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: contextMenu.currentApp && contextMenu.currentApp.desktopEntry && contextMenu.currentApp.desktopEntry.actions && contextMenu.currentApp.desktopEntry.actions.length > 0
|
||||
width: parent.width - Theme.spacingS * 2
|
||||
height: 5
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: "transparent"
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32
|
||||
|
||||
@@ -797,6 +797,76 @@ DankPopout {
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: contextMenu.currentApp && contextMenu.currentApp.desktopEntry && contextMenu.currentApp.desktopEntry.actions ? contextMenu.currentApp.desktopEntry.actions : []
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32
|
||||
radius: Theme.cornerRadius
|
||||
color: actionMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingS
|
||||
|
||||
Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Theme.iconSize - 2
|
||||
height: Theme.iconSize - 2
|
||||
visible: modelData.icon && modelData.icon !== ""
|
||||
|
||||
IconImage {
|
||||
anchors.fill: parent
|
||||
source: modelData.icon ? Quickshell.iconPath(modelData.icon, true) : ""
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
visible: status === Image.Ready
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: modelData.name || ""
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Normal
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: actionMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (modelData && contextMenu.currentApp && contextMenu.currentApp.desktopEntry) {
|
||||
SessionService.launchDesktopAction(contextMenu.currentApp.desktopEntry, modelData)
|
||||
appLauncher.appLaunched(contextMenu.currentApp)
|
||||
}
|
||||
contextMenu.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: contextMenu.currentApp && contextMenu.currentApp.desktopEntry && contextMenu.currentApp.desktopEntry.actions && contextMenu.currentApp.desktopEntry.actions.length > 0
|
||||
width: parent.width - Theme.spacingS * 2
|
||||
height: 5
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: "transparent"
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32
|
||||
|
||||
@@ -316,9 +316,8 @@ Item {
|
||||
console.warn("No toplevel found for grouped app")
|
||||
}
|
||||
} else {
|
||||
// For multiple windows, show context menu (hide pin option for left-click)
|
||||
if (contextMenu) {
|
||||
contextMenu.showForButton(root, appData, 65, true)
|
||||
contextMenu.showForButton(root, appData, 65, true, cachedDesktopEntry)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -338,8 +337,7 @@ Item {
|
||||
}
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
if (contextMenu && appData) {
|
||||
console.log("Right-clicked on app:", appData.appId, "type:", appData.type, "windowCount:", appData.windowCount || 0)
|
||||
contextMenu.showForButton(root, appData, 40, false)
|
||||
contextMenu.showForButton(root, appData, 40, false, cachedDesktopEntry)
|
||||
} else {
|
||||
console.warn("No context menu or appData available")
|
||||
}
|
||||
|
||||
@@ -16,12 +16,14 @@ PanelWindow {
|
||||
property real dockVisibleHeight: 40
|
||||
property int margin: 10
|
||||
property bool hidePin: false
|
||||
property var desktopEntry: null
|
||||
|
||||
function showForButton(button, data, dockHeight, hidePinOption) {
|
||||
function showForButton(button, data, dockHeight, hidePinOption, entry) {
|
||||
anchorItem = button
|
||||
appData = data
|
||||
dockVisibleHeight = dockHeight || 40
|
||||
hidePin = hidePinOption || false
|
||||
desktopEntry = entry || null
|
||||
|
||||
const dockWindow = button.Window.window
|
||||
if (dockWindow) {
|
||||
@@ -134,7 +136,7 @@ PanelWindow {
|
||||
Rectangle {
|
||||
id: menuContainer
|
||||
|
||||
width: Math.min(400, Math.max(200, menuColumn.implicitWidth + Theme.spacingS * 2))
|
||||
width: Math.min(400, Math.max(180, menuColumn.implicitWidth + Theme.spacingS * 2))
|
||||
height: Math.max(60, menuColumn.implicitHeight + Theme.spacingS * 2)
|
||||
|
||||
x: {
|
||||
@@ -289,6 +291,71 @@ PanelWindow {
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.desktopEntry && root.desktopEntry.actions ? root.desktopEntry.actions : []
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 28
|
||||
radius: Theme.cornerRadius
|
||||
color: actionArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingS
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.spacingS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingXS
|
||||
|
||||
Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 16
|
||||
height: 16
|
||||
visible: modelData.icon && modelData.icon !== ""
|
||||
|
||||
IconImage {
|
||||
anchors.fill: parent
|
||||
source: modelData.icon ? Quickshell.iconPath(modelData.icon, true) : ""
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
visible: status === Image.Ready
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: modelData.name || ""
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Normal
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.NoWrap
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: actionArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (modelData) {
|
||||
SessionService.launchDesktopAction(root.desktopEntry, modelData)
|
||||
}
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: root.desktopEntry && root.desktopEntry.actions && root.desktopEntry.actions.length > 0
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: !root.hidePin
|
||||
width: parent.width
|
||||
|
||||
@@ -101,6 +101,19 @@ Singleton {
|
||||
});
|
||||
}
|
||||
|
||||
function launchDesktopAction(desktopEntry, action) {
|
||||
let cmd = action.command
|
||||
if (SessionData.launchPrefix && SessionData.launchPrefix.length > 0) {
|
||||
const launchPrefix = SessionData.launchPrefix.trim().split(" ")
|
||||
cmd = launchPrefix.concat(cmd)
|
||||
}
|
||||
|
||||
Quickshell.execDetached({
|
||||
command: cmd,
|
||||
workingDirectory: desktopEntry.workingDirectory,
|
||||
});
|
||||
}
|
||||
|
||||
// * Session management
|
||||
function logout() {
|
||||
if (hasUwsm) {
|
||||
|
||||
Reference in New Issue
Block a user