1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-10 07:28:30 -04:00

dock/apps: support minimize

This commit is contained in:
bbedward
2026-08-09 17:08:43 -04:00
parent 80bad610ce
commit b0b9b61593
8 changed files with 242 additions and 50 deletions
@@ -350,7 +350,7 @@ Item {
} }
const nextWindow = windows[nextIndex]; const nextWindow = windows[nextIndex];
if (nextWindow) { if (nextWindow) {
nextWindow.activate(); CompositorService.activateToplevel(nextWindow);
} }
} }
@@ -569,6 +569,14 @@ BasePill {
return modelData.toplevel ? modelData.toplevel.activated : false; return modelData.toplevel ? modelData.toplevel.activated : false;
} }
readonly property bool isMinimized: {
if (!CompositorService.supportsMinimize)
return false;
if (modelData.type === "grouped")
return modelData.allWindows.length > 0 && modelData.allWindows.every(w => w.toplevel && w.toplevel.minimized);
return modelData.toplevel?.minimized === true;
}
property var appId: modelData.appId property var appId: modelData.appId
property int windowCount: modelData.windowCount || (modelData.isRunning ? 1 : 0) property int windowCount: modelData.windowCount || (modelData.isRunning ? 1 : 0)
property string windowTitle: { property string windowTitle: {
@@ -698,6 +706,7 @@ BasePill {
mipmap: true mipmap: true
asynchronous: true asynchronous: true
visible: status === Image.Ready && !coreIcon.visible visible: status === Image.Ready && !coreIcon.visible
opacity: appItem.isMinimized ? 0.4 : 1
layer.enabled: appItem.appId === "org.quickshell" || appItem.appId === "com.danklinux.dms" layer.enabled: appItem.appId === "org.quickshell" || appItem.appId === "com.danklinux.dms"
layer.smooth: true layer.smooth: true
layer.mipmap: true layer.mipmap: true
@@ -730,6 +739,7 @@ BasePill {
name: "sports_esports" name: "sports_esports"
color: Theme.widgetTextColor color: Theme.widgetTextColor
visible: !iconImg.visible && !coreIcon.visible && Paths.isSteamApp(appItem.appId) visible: !iconImg.visible && !coreIcon.visible && Paths.isSteamApp(appItem.appId)
opacity: appItem.isMinimized ? 0.4 : 1
transformOrigin: Item.Center transformOrigin: Item.Center
scale: appItem.enlargeScale scale: appItem.enlargeScale
@@ -754,6 +764,7 @@ BasePill {
} }
font.pixelSize: 10 font.pixelSize: 10
color: Theme.widgetTextColor color: Theme.widgetTextColor
opacity: appItem.isMinimized ? 0.4 : 1
transformOrigin: Item.Center transformOrigin: Item.Center
scale: appItem.enlargeScale scale: appItem.enlargeScale
@@ -884,8 +895,7 @@ BasePill {
SessionService.launchDesktopEntry(desktopEntry); SessionService.launchDesktopEntry(desktopEntry);
} }
} else if (modelData.windowCount === 1) { } else if (modelData.windowCount === 1) {
if (modelData.allWindows[0].toplevel) CompositorService.toggleToplevel(modelData.allWindows[0].toplevel);
modelData.allWindows[0].toplevel.activate();
} else { } else {
let currentIndex = -1; let currentIndex = -1;
for (var i = 0; i < modelData.allWindows.length; i++) { for (var i = 0; i < modelData.allWindows.length; i++) {
@@ -895,7 +905,7 @@ BasePill {
} }
} }
const nextIndex = (currentIndex + 1) % modelData.allWindows.length; const nextIndex = (currentIndex + 1) % modelData.allWindows.length;
modelData.allWindows[nextIndex].toplevel.activate(); CompositorService.activateToplevel(modelData.allWindows[nextIndex].toplevel);
} }
} }
} }
@@ -171,7 +171,7 @@ PanelWindow {
} }
Rectangle { Rectangle {
implicitWidth: Theme.spacingS + windowTitle.implicitWidth + Theme.spacingXS + closeButton.width + Theme.spacingXS implicitWidth: Theme.spacingS + windowTitle.implicitWidth + Theme.spacingXS + (minimizeButton.visible ? minimizeButton.width + 2 : 0) + closeButton.width + Theme.spacingXS
width: parent.width width: parent.width
height: 28 height: 28
radius: Theme.cornerRadius radius: Theme.cornerRadius
@@ -181,7 +181,7 @@ PanelWindow {
id: windowTitle id: windowTitle
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Theme.spacingS anchors.leftMargin: Theme.spacingS
anchors.right: closeButton.left anchors.right: minimizeButton.visible ? minimizeButton.left : closeButton.left
anchors.rightMargin: Theme.spacingXS anchors.rightMargin: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: (modelData && modelData.title) ? modelData.title : I18n.tr("(Unnamed)") text: (modelData && modelData.title) ? modelData.title : I18n.tr("(Unnamed)")
@@ -192,6 +192,40 @@ PanelWindow {
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
} }
Rectangle {
id: minimizeButton
visible: CompositorService.canMinimize(modelData)
anchors.right: closeButton.left
anchors.rightMargin: 2
anchors.verticalCenter: parent.verticalCenter
width: 20
height: 20
radius: 10
color: minimizeMouseArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
DankIcon {
anchors.centerIn: parent
name: modelData.minimized ? "expand_content" : "minimize"
size: 12
color: Theme.surfaceText
}
MouseArea {
id: minimizeMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (modelData.minimized) {
CompositorService.activateToplevel(modelData);
} else {
modelData.minimized = true;
}
root.close();
}
}
}
Rectangle { Rectangle {
id: closeButton id: closeButton
anchors.right: parent.right anchors.right: parent.right
@@ -232,14 +266,12 @@ PanelWindow {
MouseArea { MouseArea {
id: windowArea id: windowArea
anchors.fill: parent anchors.fill: parent
anchors.rightMargin: 24 anchors.rightMargin: minimizeButton.visible ? 46 : 24
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onPressed: mouse => windowRipple.trigger(mouse.x, mouse.y) onPressed: mouse => windowRipple.trigger(mouse.x, mouse.y)
onClicked: { onClicked: {
if (modelData && modelData.activate) { CompositorService.activateToplevel(modelData);
modelData.activate();
}
root.close(); root.close();
} }
} }
@@ -187,7 +187,7 @@ BasePill {
const nextWindow = windows[nextIndex]; const nextWindow = windows[nextIndex];
if (nextWindow) if (nextWindow)
nextWindow.activate(); CompositorService.activateToplevel(nextWindow);
} else { } else {
scrollAccumulator += deltaY; scrollAccumulator += deltaY;
@@ -209,7 +209,7 @@ BasePill {
const nextWindow = windows[nextIndex]; const nextWindow = windows[nextIndex];
if (nextWindow) if (nextWindow)
nextWindow.activate(); CompositorService.activateToplevel(nextWindow);
scrollAccumulator = 0; scrollAccumulator = 0;
} }
@@ -261,6 +261,13 @@ BasePill {
property string windowTitle: toplevelData ? (toplevelData.title || "(Unnamed)") : "(Unnamed)" property string windowTitle: toplevelData ? (toplevelData.title || "(Unnamed)") : "(Unnamed)"
property var toplevelObject: toplevelData property var toplevelObject: toplevelData
property int windowCount: isGrouped ? modelData.windows.length : 1 property int windowCount: isGrouped ? modelData.windows.length : 1
readonly property bool isMinimized: {
if (!CompositorService.supportsMinimize)
return false;
if (isGrouped)
return groupData.windows.length > 0 && groupData.windows.every(w => w.toplevel.minimized);
return toplevelObject?.minimized === true;
}
property string tooltipText: { property string tooltipText: {
root._desktopEntriesUpdateTrigger; root._desktopEntriesUpdateTrigger;
const desktopEntry = effectiveAppId ? DesktopEntries.heuristicLookup(effectiveAppId) : null; const desktopEntry = effectiveAppId ? DesktopEntries.heuristicLookup(effectiveAppId) : null;
@@ -309,6 +316,7 @@ BasePill {
mipmap: true mipmap: true
asynchronous: true asynchronous: true
visible: status === Image.Ready visible: status === Image.Ready
opacity: delegateItem.isMinimized ? 0.4 : 1
layer.enabled: appId === "org.quickshell" || appId === "com.danklinux.dms" layer.enabled: appId === "org.quickshell" || appId === "com.danklinux.dms"
layer.smooth: true layer.smooth: true
layer.mipmap: true layer.mipmap: true
@@ -327,6 +335,7 @@ BasePill {
name: "sports_esports" name: "sports_esports"
color: Theme.widgetTextColor color: Theme.widgetTextColor
visible: !iconImg.visible && Paths.isSteamApp(effectiveAppId) visible: !iconImg.visible && Paths.isSteamApp(effectiveAppId)
opacity: delegateItem.isMinimized ? 0.4 : 1
} }
StyledText { StyledText {
@@ -343,6 +352,7 @@ BasePill {
} }
font.pixelSize: 10 font.pixelSize: 10
color: Theme.widgetTextColor color: Theme.widgetTextColor
opacity: delegateItem.isMinimized ? 0.4 : 1
} }
Rectangle { Rectangle {
@@ -406,9 +416,9 @@ BasePill {
} }
} }
const nextIndex = (currentIndex + 1) % groupData.windows.length; const nextIndex = (currentIndex + 1) % groupData.windows.length;
groupData.windows[nextIndex].toplevel.activate(); CompositorService.activateToplevel(groupData.windows[nextIndex].toplevel);
} else if (toplevelObject) { } else if (toplevelObject) {
toplevelObject.activate(); CompositorService.toggleToplevel(toplevelObject);
} }
} else if (mouse.button === Qt.RightButton) { } else if (mouse.button === Qt.RightButton) {
if (tooltipLoader.item) { if (tooltipLoader.item) {
@@ -433,7 +443,7 @@ BasePill {
const localPos = delegateItem.mapToItem(null, delegateItem.width / 2, 0); const localPos = delegateItem.mapToItem(null, delegateItem.width / 2, 0);
const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height; const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height;
const isBottom = root.axis?.edge === "bottom"; const isBottom = root.axis?.edge === "bottom";
const yPos = isBottom ? (screenHeight - root.barThickness - root.barSpacing - 32 - Theme.spacingXS) : (root.barThickness + root.barSpacing + Theme.spacingXS); const yPos = isBottom ? (screenHeight - root.barThickness - root.barSpacing - windowContextMenuLoader.item.menuHeight - Theme.spacingXS) : (root.barThickness + root.barSpacing + Theme.spacingXS);
windowContextMenuLoader.item.showAt(localPos.x, yPos, false, root.axis?.edge); windowContextMenuLoader.item.showAt(localPos.x, yPos, false, root.axis?.edge);
} }
} }
@@ -506,6 +516,13 @@ BasePill {
property string windowTitle: toplevelData ? (toplevelData.title || "(Unnamed)") : "(Unnamed)" property string windowTitle: toplevelData ? (toplevelData.title || "(Unnamed)") : "(Unnamed)"
property var toplevelObject: toplevelData property var toplevelObject: toplevelData
property int windowCount: isGrouped ? modelData.windows.length : 1 property int windowCount: isGrouped ? modelData.windows.length : 1
readonly property bool isMinimized: {
if (!CompositorService.supportsMinimize)
return false;
if (isGrouped)
return groupData.windows.length > 0 && groupData.windows.every(w => w.toplevel.minimized);
return toplevelObject?.minimized === true;
}
property string tooltipText: { property string tooltipText: {
root._desktopEntriesUpdateTrigger; root._desktopEntriesUpdateTrigger;
const desktopEntry = effectiveAppId ? DesktopEntries.heuristicLookup(effectiveAppId) : null; const desktopEntry = effectiveAppId ? DesktopEntries.heuristicLookup(effectiveAppId) : null;
@@ -553,6 +570,7 @@ BasePill {
mipmap: true mipmap: true
asynchronous: true asynchronous: true
visible: status === Image.Ready visible: status === Image.Ready
opacity: delegateItem.isMinimized ? 0.4 : 1
layer.enabled: appId === "org.quickshell" || appId === "com.danklinux.dms" layer.enabled: appId === "org.quickshell" || appId === "com.danklinux.dms"
layer.smooth: true layer.smooth: true
layer.mipmap: true layer.mipmap: true
@@ -571,6 +589,7 @@ BasePill {
name: "sports_esports" name: "sports_esports"
color: Theme.widgetTextColor color: Theme.widgetTextColor
visible: !iconImg.visible && Paths.isSteamApp(effectiveAppId) visible: !iconImg.visible && Paths.isSteamApp(effectiveAppId)
opacity: delegateItem.isMinimized ? 0.4 : 1
} }
StyledText { StyledText {
@@ -587,6 +606,7 @@ BasePill {
} }
font.pixelSize: 10 font.pixelSize: 10
color: Theme.widgetTextColor color: Theme.widgetTextColor
opacity: delegateItem.isMinimized ? 0.4 : 1
} }
Rectangle { Rectangle {
@@ -650,9 +670,9 @@ BasePill {
} }
} }
const nextIndex = (currentIndex + 1) % groupData.windows.length; const nextIndex = (currentIndex + 1) % groupData.windows.length;
groupData.windows[nextIndex].toplevel.activate(); CompositorService.activateToplevel(groupData.windows[nextIndex].toplevel);
} else if (toplevelObject) { } else if (toplevelObject) {
toplevelObject.activate(); CompositorService.toggleToplevel(toplevelObject);
} }
} else if (mouse.button === Qt.RightButton) { } else if (mouse.button === Qt.RightButton) {
if (tooltipLoader.item) { if (tooltipLoader.item) {
@@ -677,7 +697,7 @@ BasePill {
const localPos = delegateItem.mapToItem(null, delegateItem.width / 2, 0); const localPos = delegateItem.mapToItem(null, delegateItem.width / 2, 0);
const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height; const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height;
const isBottom = root.axis?.edge === "bottom"; const isBottom = root.axis?.edge === "bottom";
const yPos = isBottom ? (screenHeight - root.barThickness - root.barSpacing - 32 - Theme.spacingXS) : (root.barThickness + root.barSpacing + Theme.spacingXS); const yPos = isBottom ? (screenHeight - root.barThickness - root.barSpacing - windowContextMenuLoader.item.menuHeight - Theme.spacingXS) : (root.barThickness + root.barSpacing + Theme.spacingXS);
windowContextMenuLoader.item.showAt(localPos.x, yPos, false, root.axis?.edge); windowContextMenuLoader.item.showAt(localPos.x, yPos, false, root.axis?.edge);
} }
} }
@@ -742,6 +762,7 @@ BasePill {
} }
property var currentWindow: null property var currentWindow: null
readonly property real menuHeight: contextMenuRect.height
property bool isVisible: false property bool isVisible: false
property point anchorPos: Qt.point(0, 0) property point anchorPos: Qt.point(0, 0)
property bool isVertical: false property bool isVertical: false
@@ -858,36 +879,79 @@ BasePill {
return contextMenuWindow.anchorPos.y; return contextMenuWindow.anchorPos.y;
} }
} }
width: 100 width: 120
height: 32 height: menuColumn.height + Theme.spacingXS * 2
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
radius: Theme.cornerRadius radius: Theme.cornerRadius
border.width: BlurService.borderWidth border.width: BlurService.borderWidth
border.color: BlurService.borderColor border.color: BlurService.borderColor
Rectangle { Column {
anchors.fill: parent id: menuColumn
radius: parent.radius anchors.horizontalCenter: parent.horizontalCenter
color: closeMouseArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : Theme.withAlpha(BlurService.hoverColor(Theme.widgetBaseHoverColor), 0) anchors.top: parent.top
} anchors.topMargin: Theme.spacingXS
width: parent.width - Theme.spacingXS * 2
spacing: 1
StyledText { Rectangle {
anchors.centerIn: parent visible: CompositorService.canMinimize(contextMenuWindow.currentWindow)
text: I18n.tr("Close") width: parent.width
font.pixelSize: Theme.fontSizeSmall height: 28
color: Theme.widgetTextColor radius: Theme.cornerRadius
} color: minimizeMouseArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
MouseArea { StyledText {
id: closeMouseArea anchors.centerIn: parent
anchors.fill: parent text: contextMenuWindow.currentWindow?.minimized ? I18n.tr("Restore") : I18n.tr("Minimize")
hoverEnabled: true font.pixelSize: Theme.fontSizeSmall
cursorShape: Qt.PointingHandCursor color: Theme.widgetTextColor
onClicked: { }
if (contextMenuWindow.currentWindow) {
contextMenuWindow.currentWindow.close(); MouseArea {
id: minimizeMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
const targetWindow = contextMenuWindow.currentWindow;
if (targetWindow) {
if (targetWindow.minimized) {
CompositorService.activateToplevel(targetWindow);
} else {
targetWindow.minimized = true;
}
}
contextMenuWindow.close();
}
}
}
Rectangle {
width: parent.width
height: 28
radius: Theme.cornerRadius
color: closeMouseArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
StyledText {
anchors.centerIn: parent
text: I18n.tr("Close")
font.pixelSize: Theme.fontSizeSmall
color: Theme.widgetTextColor
}
MouseArea {
id: closeMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (contextMenuWindow.currentWindow) {
contextMenuWindow.currentWindow.close();
}
contextMenuWindow.close();
}
} }
contextMenuWindow.close();
} }
} }
} }
+23 -3
View File
@@ -107,6 +107,23 @@ Item {
return false; return false;
} }
readonly property bool isMinimized: {
if (!CompositorService.supportsMinimize || !appData) {
return false;
}
switch (appData.type) {
case "window":
return getToplevelObject()?.minimized === true;
case "grouped":
{
const toplevels = getGroupedToplevels();
return toplevels.length > 0 && toplevels.every(t => t.minimized);
}
default:
return false;
}
}
property string tooltipText: { property string tooltipText: {
if (!appData || !appData.appId) { if (!appData || !appData.appId) {
return ""; return "";
@@ -185,7 +202,7 @@ Item {
const nextToplevel = toplevels[(currentIndex + 1) % toplevels.length]; const nextToplevel = toplevels[(currentIndex + 1) % toplevels.length];
if (restoreSpecialWorkspaceWindow(nextToplevel)) if (restoreSpecialWorkspaceWindow(nextToplevel))
return; return;
nextToplevel.activate(); CompositorService.activateToplevel(nextToplevel);
} }
onIsHoveredChanged: { onIsHoveredChanged: {
if (mouseArea.pressed || dragging) if (mouseArea.pressed || dragging)
@@ -333,7 +350,7 @@ Item {
if (windowToplevel) { if (windowToplevel) {
if (restoreSpecialWorkspaceWindow(windowToplevel)) if (restoreSpecialWorkspaceWindow(windowToplevel))
return; return;
windowToplevel.activate(); CompositorService.toggleToplevel(windowToplevel);
} }
break; break;
case "grouped": case "grouped":
@@ -360,7 +377,7 @@ Item {
if (groupedToplevel) { if (groupedToplevel) {
if (restoreSpecialWorkspaceWindow(groupedToplevel)) if (restoreSpecialWorkspaceWindow(groupedToplevel))
return; return;
groupedToplevel.activate(); CompositorService.toggleToplevel(groupedToplevel);
} }
} else { } else {
cycleGroupedToplevels(); cycleGroupedToplevels();
@@ -503,6 +520,7 @@ Item {
smooth: true smooth: true
asynchronous: true asynchronous: true
visible: status === Image.Ready && !coreIcon.visible visible: status === Image.Ready && !coreIcon.visible
opacity: root.isMinimized ? 0.4 : 1
layer.enabled: appData && (appData.appId === "org.quickshell" || appData.appId === "com.danklinux.dms") layer.enabled: appData && (appData.appId === "org.quickshell" || appData.appId === "com.danklinux.dms")
layer.smooth: true layer.smooth: true
layer.mipmap: true layer.mipmap: true
@@ -518,6 +536,7 @@ Item {
height: actualIconSize height: actualIconSize
anchors.centerIn: parent anchors.centerIn: parent
visible: !coreIcon.visible && iconImg.status !== Image.Ready && appData && appData.appId && !Paths.isSteamApp(appData.appId) visible: !coreIcon.visible && iconImg.status !== Image.Ready && appData && appData.appId && !Paths.isSteamApp(appData.appId)
opacity: root.isMinimized ? 0.4 : 1
color: Theme.surfaceLight color: Theme.surfaceLight
radius: Theme.cornerRadius radius: Theme.cornerRadius
border.width: 1 border.width: 1
@@ -550,6 +569,7 @@ Item {
name: "sports_esports" name: "sports_esports"
color: Theme.surfaceText color: Theme.surfaceText
visible: !coreIcon.visible && iconImg.status !== Image.Ready && appData && appData.appId && Paths.isSteamApp(appData.appId) visible: !coreIcon.visible && iconImg.status !== Image.Ready && appData && appData.appId && Paths.isSteamApp(appData.appId)
opacity: root.isMinimized ? 0.4 : 1
} }
Loader { Loader {
+38 -6
View File
@@ -31,7 +31,7 @@ DockContextMenuBase {
} }
Rectangle { Rectangle {
implicitWidth: Theme.spacingS + windowTitle.implicitWidth + Theme.spacingXS + closeButton.width + Theme.spacingXS implicitWidth: Theme.spacingS + windowTitle.implicitWidth + Theme.spacingXS + (minimizeButton.visible ? minimizeButton.width + 2 : 0) + closeButton.width + Theme.spacingXS
width: parent.width width: parent.width
height: 28 height: 28
radius: Theme.cornerRadius radius: Theme.cornerRadius
@@ -41,7 +41,7 @@ DockContextMenuBase {
id: windowTitle id: windowTitle
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Theme.spacingS anchors.leftMargin: Theme.spacingS
anchors.right: closeButton.left anchors.right: minimizeButton.visible ? minimizeButton.left : closeButton.left
anchors.rightMargin: Theme.spacingXS anchors.rightMargin: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: (modelData && modelData.title) ? modelData.title : I18n.tr("(Unnamed)") text: (modelData && modelData.title) ? modelData.title : I18n.tr("(Unnamed)")
@@ -52,6 +52,40 @@ DockContextMenuBase {
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
} }
Rectangle {
id: minimizeButton
visible: CompositorService.canMinimize(modelData)
anchors.right: closeButton.left
anchors.rightMargin: 2
anchors.verticalCenter: parent.verticalCenter
width: 20
height: 20
radius: 10
color: minimizeMouseArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
DankIcon {
anchors.centerIn: parent
name: modelData.minimized ? "expand_content" : "minimize"
size: 12
color: Theme.surfaceText
}
MouseArea {
id: minimizeMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (modelData.minimized) {
CompositorService.activateToplevel(modelData);
} else {
modelData.minimized = true;
}
root.close();
}
}
}
Rectangle { Rectangle {
id: closeButton id: closeButton
anchors.right: parent.right anchors.right: parent.right
@@ -92,14 +126,12 @@ DockContextMenuBase {
MouseArea { MouseArea {
id: windowArea id: windowArea
anchors.fill: parent anchors.fill: parent
anchors.rightMargin: 24 anchors.rightMargin: minimizeButton.visible ? 46 : 24
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onPressed: mouse => windowRipple.trigger(mouse.x, mouse.y) onPressed: mouse => windowRipple.trigger(mouse.x, mouse.y)
onClicked: { onClicked: {
if (modelData && modelData.activate) { CompositorService.activateToplevel(modelData);
modelData.activate();
}
root.close(); root.close();
} }
} }
+34
View File
@@ -7,6 +7,7 @@ import Quickshell.I3
import Quickshell.Wayland import Quickshell.Wayland
import Quickshell.Hyprland import Quickshell.Hyprland
import qs.Common import qs.Common
import qs.DankCommon.Common as DankCommon
import qs.Services import qs.Services
Singleton { Singleton {
@@ -44,6 +45,39 @@ Singleton {
signal toplevelsChanged signal toplevelsChanged
readonly property bool supportsMinimize: DankCommon.Compositor.supportsMinimize
function canMinimize(toplevel) {
return supportsMinimize && toplevel && toplevel.minimized !== undefined;
}
function activateToplevel(toplevel) {
if (!toplevel)
return;
if (canMinimize(toplevel) && toplevel.minimized)
toplevel.minimized = false;
toplevel.activate();
}
function toggleToplevel(toplevel) {
if (!toplevel)
return;
if (!canMinimize(toplevel)) {
toplevel.activate();
return;
}
if (toplevel.minimized) {
toplevel.minimized = false;
toplevel.activate();
return;
}
if (toplevel.activated) {
toplevel.minimized = true;
return;
}
toplevel.activate();
}
function fetchRandrData() { function fetchRandrData() {
Proc.runCommand("randr", [Proc.dmsBin, "randr", "--json"], (output, exitCode) => { Proc.runCommand("randr", [Proc.dmsBin, "randr", "--json"], (output, exitCode) => {
if (exitCode === 0 && output) { if (exitCode === 0 && output) {