mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-29 07:52:50 -05:00
Add Desktop Actions to launcher + dock
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
@@ -13,7 +15,7 @@ Rectangle {
|
|||||||
|
|
||||||
function show(x, y, app) {
|
function show(x, y, app) {
|
||||||
currentApp = 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
|
const menuHeight = menuColumn.implicitHeight + Theme.spacingS * 2
|
||||||
let finalX = x + 8
|
let finalX = x + 8
|
||||||
let finalY = y + 8
|
let finalY = y + 8
|
||||||
@@ -29,6 +31,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
contextMenu.x = finalX
|
contextMenu.x = finalX
|
||||||
contextMenu.y = finalY
|
contextMenu.y = finalY
|
||||||
|
contextMenu.width = menuWidth
|
||||||
contextMenu.visible = true
|
contextMenu.visible = true
|
||||||
contextMenu.menuVisible = 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 {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 32
|
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 {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 32
|
height: 32
|
||||||
|
|||||||
@@ -316,9 +316,8 @@ Item {
|
|||||||
console.warn("No toplevel found for grouped app")
|
console.warn("No toplevel found for grouped app")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// For multiple windows, show context menu (hide pin option for left-click)
|
|
||||||
if (contextMenu) {
|
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) {
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
if (contextMenu && appData) {
|
if (contextMenu && appData) {
|
||||||
console.log("Right-clicked on app:", appData.appId, "type:", appData.type, "windowCount:", appData.windowCount || 0)
|
contextMenu.showForButton(root, appData, 40, false, cachedDesktopEntry)
|
||||||
contextMenu.showForButton(root, appData, 40, false)
|
|
||||||
} else {
|
} else {
|
||||||
console.warn("No context menu or appData available")
|
console.warn("No context menu or appData available")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ PanelWindow {
|
|||||||
property real dockVisibleHeight: 40
|
property real dockVisibleHeight: 40
|
||||||
property int margin: 10
|
property int margin: 10
|
||||||
property bool hidePin: false
|
property bool hidePin: false
|
||||||
|
property var desktopEntry: null
|
||||||
|
|
||||||
function showForButton(button, data, dockHeight, hidePinOption) {
|
function showForButton(button, data, dockHeight, hidePinOption, entry) {
|
||||||
anchorItem = button
|
anchorItem = button
|
||||||
appData = data
|
appData = data
|
||||||
dockVisibleHeight = dockHeight || 40
|
dockVisibleHeight = dockHeight || 40
|
||||||
hidePin = hidePinOption || false
|
hidePin = hidePinOption || false
|
||||||
|
desktopEntry = entry || null
|
||||||
|
|
||||||
const dockWindow = button.Window.window
|
const dockWindow = button.Window.window
|
||||||
if (dockWindow) {
|
if (dockWindow) {
|
||||||
@@ -134,7 +136,7 @@ PanelWindow {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: menuContainer
|
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)
|
height: Math.max(60, menuColumn.implicitHeight + Theme.spacingS * 2)
|
||||||
|
|
||||||
x: {
|
x: {
|
||||||
@@ -289,6 +291,71 @@ PanelWindow {
|
|||||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
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 {
|
Rectangle {
|
||||||
visible: !root.hidePin
|
visible: !root.hidePin
|
||||||
width: parent.width
|
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
|
// * Session management
|
||||||
function logout() {
|
function logout() {
|
||||||
if (hasUwsm) {
|
if (hasUwsm) {
|
||||||
|
|||||||
Reference in New Issue
Block a user