From eed3617a0de86d7299b1056632fec30dcc9272fd Mon Sep 17 00:00:00 2001 From: bbedward Date: Sun, 26 Jul 2026 14:37:17 -0400 Subject: [PATCH] ipc/dash: add openAt/toggleAt for opening popouts at specific locations fixes #2932 --- quickshell/DMSShellIPC.qml | 85 ++++++++++++------ quickshell/Modules/DankBar/DankBarBody.qml | 90 +++++++++++++------- quickshell/Modules/DankBar/DankBarWindow.qml | 11 ++- 3 files changed, 124 insertions(+), 62 deletions(-) diff --git a/quickshell/DMSShellIPC.qml b/quickshell/DMSShellIPC.qml index 3ea4d27ac..da0032467 100644 --- a/quickshell/DMSShellIPC.qml +++ b/quickshell/DMSShellIPC.qml @@ -285,28 +285,66 @@ Item { } } + function _resolvePosition(position) { + switch ((position || "").toLowerCase()) { + case "left": + return "left"; + case "center": + return "center"; + case "right": + return "right"; + default: + return ""; + } + } + + function _dashBar(position) { + if (position) + return root.getPreferredBar(); + return root.getPreferredBar("clockButtonRef") || root.getPreferredBar(); + } + + function _openDash(tab, position) { + const bar = _dashBar(position); + if (!bar) + return false; + + const tabId = _resolveTabId(tab); + const dash = root.dankDashPopoutLoader.item; + if (dash && dash.shouldBeVisible && dash.triggerScreen?.name === bar.screen?.name) { + if (position && bar.positionDash) + bar.positionDash(dash, position); + dash.requestTab(tabId); + if (dash.updateSurfacePosition) + dash.updateSurfacePosition(); + return true; + } + + return bar.triggerDashTab(tabId, position); + } + + function _toggleDash(tab, position) { + if (root.dankDashPopoutLoader.item?.dashVisible) { + root.dankDashPopoutLoader.item.dashVisible = false; + return true; + } + + const bar = _dashBar(position); + if (!bar) + return false; + return bar.triggerDashTab(_resolveTabId(tab), position); + } + function resolveTabIndex(tab: string): int { return SettingsData.dashTabIndexForId(_resolveTabId(tab)); } function open(tab: string): string { - const bar = root.getPreferredBar("clockButtonRef") || root.getPreferredBar(); - if (!bar) - return "DASH_OPEN_FAILED"; + return _openDash(tab, "") ? "DASH_OPEN_SUCCESS" : "DASH_OPEN_FAILED"; + } - const tabId = _resolveTabId(tab); - const dash = root.dankDashPopoutLoader.item; - if (dash && dash.shouldBeVisible && dash.triggerScreen?.name === bar.screen?.name) { - dash.requestTab(tabId); - if (dash.updateSurfacePosition) - dash.updateSurfacePosition(); - return "DASH_OPEN_SUCCESS"; - } - - if (!bar.triggerDashTab(tabId)) - return "DASH_OPEN_FAILED"; - - return "DASH_OPEN_SUCCESS"; + function openAt(tab: string, position: string): string { + return _openDash(tab, _resolvePosition(position)) ? "DASH_OPEN_SUCCESS" : "DASH_OPEN_FAILED"; } function close(): string { @@ -318,18 +356,11 @@ Item { } function toggle(tab: string): string { - if (root.dankDashPopoutLoader.item?.dashVisible) { - root.dankDashPopoutLoader.item.dashVisible = false; - return "DASH_TOGGLE_SUCCESS"; - } + return _toggleDash(tab, "") ? "DASH_TOGGLE_SUCCESS" : "DASH_TOGGLE_FAILED"; + } - const bar = root.getPreferredBar("clockButtonRef") || root.getPreferredBar(); - if (bar) { - if (!bar.triggerDashTab(_resolveTabId(tab))) - return "DASH_TOGGLE_FAILED"; - return "DASH_TOGGLE_SUCCESS"; - } - return "DASH_TOGGLE_FAILED"; + function toggleAt(tab: string, position: string): string { + return _toggleDash(tab, _resolvePosition(position)) ? "DASH_TOGGLE_SUCCESS" : "DASH_TOGGLE_FAILED"; } target: "dash" diff --git a/quickshell/Modules/DankBar/DankBarBody.qml b/quickshell/Modules/DankBar/DankBarBody.qml index aa581a3a4..6ca2527ed 100644 --- a/quickshell/Modules/DankBar/DankBarBody.qml +++ b/quickshell/Modules/DankBar/DankBarBody.qml @@ -69,7 +69,62 @@ Item { } } - function triggerDashTab(tabId) { + function dashSectionAnchor(section) { + let item; + switch (section) { + case "left": + item = barWindow.isVertical ? topBarContent.vLeftSection : topBarContent.hLeftSection; + break; + case "right": + item = barWindow.isVertical ? topBarContent.vRightSection : topBarContent.hRightSection; + break; + default: + item = barWindow.isVertical ? topBarContent.vCenterSection : topBarContent.hCenterSection; + } + if (!item) + return null; + if (barWindow.isVertical) + return { + "pos": item.mapToItem(null, 0, item.height / 2), + "width": item.height + }; + return { + "pos": item.mapToItem(null, 0, 0), + "width": item.width + }; + } + + function positionDash(popout, position) { + if (!popout.setTriggerPosition) { + popout.triggerScreen = barWindow.screen; + return "center"; + } + + const explicit = position === "left" || position === "center" || position === "right"; + const section = explicit ? position : (clockButtonRef?.section || "center"); + const clockAnchor = clockButtonRef?.visualContent ? { + "pos": clockButtonRef.visualContent.mapToItem(null, 0, 0), + "width": clockButtonRef.visualWidth + } : null; + + let anchor; + if (!explicit && section !== "center" && clockAnchor) + anchor = clockAnchor; + else + anchor = dashSectionAnchor(section) || clockAnchor; + + if (!anchor) { + popout.triggerScreen = barWindow.screen; + return section; + } + + const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1)); + const pos = SettingsData.getPopupTriggerPosition(anchor.pos, barWindow.screen, barWindow.effectiveBarThickness, anchor.width, barConfig?.spacing ?? 4, barPosition, barConfig); + popout.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, barConfig?.spacing ?? 4, barConfig); + return section; + } + + function triggerDashTab(tabId, position) { const loader = PopoutService.dankDashPopoutLoader; if (!loader) return false; @@ -78,38 +133,7 @@ Item { return false; } - let section = "center"; - if (clockButtonRef && clockButtonRef.visualContent && loader.item.setTriggerPosition) { - const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1)); - section = clockButtonRef.section || "center"; - - let triggerPos, triggerWidth; - if (section === "center") { - const centerSection = barWindow.isVertical ? (barWindow.axis?.edge === "left" ? topBarContent.vCenterSection : topBarContent.vCenterSection) : topBarContent.hCenterSection; - if (centerSection) { - if (barWindow.isVertical) { - const centerY = centerSection.height / 2; - triggerPos = centerSection.mapToItem(null, 0, centerY); - triggerWidth = centerSection.height; - } else { - triggerPos = centerSection.mapToItem(null, 0, 0); - triggerWidth = centerSection.width; - } - } else { - triggerPos = clockButtonRef.visualContent.mapToItem(null, 0, 0); - triggerWidth = clockButtonRef.visualWidth; - } - } else { - triggerPos = clockButtonRef.visualContent.mapToItem(null, 0, 0); - triggerWidth = clockButtonRef.visualWidth; - } - - const pos = SettingsData.getPopupTriggerPosition(triggerPos, barWindow.screen, barWindow.effectiveBarThickness, triggerWidth, barConfig?.spacing ?? 4, barPosition, barConfig); - loader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, barConfig?.spacing ?? 4, barConfig); - } else { - loader.item.triggerScreen = barWindow.screen; - } - + const section = positionDash(loader.item, position); if (loader.item.requestTab) loader.item.requestTab(tabId); PopoutManager.requestPopout(loader.item, undefined, (barConfig?.id ?? "default") + "-" + section + "-" + tabId); diff --git a/quickshell/Modules/DankBar/DankBarWindow.qml b/quickshell/Modules/DankBar/DankBarWindow.qml index 160dbeeb1..7c74e6852 100644 --- a/quickshell/Modules/DankBar/DankBarWindow.qml +++ b/quickshell/Modules/DankBar/DankBarWindow.qml @@ -20,14 +20,21 @@ PanelWindow { readonly property int barPos: body.barPos readonly property bool barRevealed: body.barRevealed + property alias controlCenterButtonRef: body.controlCenterButtonRef + property alias clockButtonRef: body.clockButtonRef + property alias systemUpdateButtonRef: body.systemUpdateButtonRef + function triggerSystemUpdate() { body.triggerSystemUpdate(); } function triggerControlCenter() { body.triggerControlCenter(); } - function triggerDashTab(tabId) { - body.triggerDashTab(tabId); + function triggerDashTab(tabId, position) { + return body.triggerDashTab(tabId, position); + } + function positionDash(popout, position) { + return body.positionDash(popout, position); } function triggerWallpaperBrowser() { body.triggerWallpaperBrowser();