From 60e79909c0bdab99d11bc43fb5db36d9f44b5dc9 Mon Sep 17 00:00:00 2001 From: bbedward Date: Sat, 19 Sep 2026 22:12:07 -0400 Subject: [PATCH] launcher: inset spotlight results and clip them to the frame radius fixes #3498 --- .../Components/LauncherMetrics.qml | 1 + .../SpotlightLauncherContent.qml | 14 ++++++++++--- .../Activities/LauncherExpanded.qml | 1 + quickshell/Modules/Dock/DockAppButton.qml | 20 ++++++------------- .../WorkspaceOverlays/NiriOverviewOverlay.qml | 1 + 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/quickshell/Modals/DankLauncherV2/Components/LauncherMetrics.qml b/quickshell/Modals/DankLauncherV2/Components/LauncherMetrics.qml index 66837d3e5..4a56bcf1d 100644 --- a/quickshell/Modals/DankLauncherV2/Components/LauncherMetrics.qml +++ b/quickshell/Modals/DankLauncherV2/Components/LauncherMetrics.qml @@ -27,6 +27,7 @@ Singleton { readonly property real screenMargin: Theme.launcherScreenMargin readonly property real spotlightWidth: Theme.launcherWidthWide readonly property real spotlightTopFraction: 0.33 + readonly property real spotlightInset: Theme.spacingS function sizeWidth(size) { switch (size) { diff --git a/quickshell/Modals/DankLauncherV2/SpotlightLauncherContent.qml b/quickshell/Modals/DankLauncherV2/SpotlightLauncherContent.qml index 545e74c9d..1f36d63cc 100644 --- a/quickshell/Modals/DankLauncherV2/SpotlightLauncherContent.qml +++ b/quickshell/Modals/DankLauncherV2/SpotlightLauncherContent.qml @@ -1,6 +1,7 @@ pragma ComponentBehavior: Bound import QtQuick +import Quickshell.Widgets import qs.Common import qs.Services import qs.Widgets @@ -21,6 +22,7 @@ FocusScope { property bool showResultsWithoutQuery: false property bool suspendSearchUpdates: false property real maxResultsHeight: 0 + property real resultsInset: LauncherMetrics.spotlightInset readonly property bool _hasQuery: root.showResultsWithoutQuery || searchInput.text.length > 0 readonly property real _searchBarH: LauncherMetrics.pillHeight @@ -29,9 +31,10 @@ FocusScope { readonly property real actionPanelHeight: actionPanel.height readonly property real _statusH: Theme.listItemTwoLineHeight + Theme.spacingXL readonly property real _maxResultsH: root.maxResultsHeight > 0 ? root.maxResultsHeight : Math.max(0, Math.min(LauncherMetrics.maxResultsHeight, (parentModal?.screenHeight ?? Theme.mediumBreakpoint) - (parentModal?.modalY ?? 0) - LauncherMetrics.pillHeight - actionPanel.height - Theme.spacingL)) - readonly property real _resultsContentH: resultsList.contentHeight > 0 ? resultsList.contentHeight + resultsList.bottomInset : _statusH + readonly property real _resultsContentH: resultsList.contentHeight > 0 ? resultsInset + resultsList.contentHeight + resultsList.bottomInset : _statusH readonly property real _resultsH: _hasQuery ? Math.min(_resultsContentH, _maxResultsH) : 0 readonly property int _resizeDuration: Theme.expressiveDurations.expressiveFastSpatial + readonly property real _frameClipRadius: Math.max(0, (parentModal?.frameBottomRadius ?? 0) - resultsInset) implicitHeight: _searchAreaH + resultsContainer.height + actionPanel.height @@ -334,12 +337,16 @@ FocusScope { } } - Item { + ClippingRectangle { id: resultsContainer anchors.top: searchBarItem.bottom anchors.left: parent.left anchors.right: parent.right - clip: true + anchors.leftMargin: root.resultsInset + anchors.rightMargin: root.resultsInset + color: "transparent" + bottomLeftRadius: actionPanel.height > 0 ? 0 : root._frameClipRadius + bottomRightRadius: bottomLeftRadius height: root._resultsH Behavior on height { @@ -357,6 +364,7 @@ FocusScope { keyForwardTargets: [searchKeyHandler] readonly property real bottomInset: Theme.spacingS anchors.fill: parent + anchors.topMargin: root.resultsInset controller: root.controller onItemRightClicked: (index, item, sceneX, sceneY) => { diff --git a/quickshell/Modules/DankIsland/Activities/LauncherExpanded.qml b/quickshell/Modules/DankIsland/Activities/LauncherExpanded.qml index 889c53736..1472566ae 100644 --- a/quickshell/Modules/DankIsland/Activities/LauncherExpanded.qml +++ b/quickshell/Modules/DankIsland/Activities/LauncherExpanded.qml @@ -69,6 +69,7 @@ FocusScope { anchors.topMargin: Theme.spacingM anchors.bottomMargin: root.bottomInset parentModal: hostContract + resultsInset: 0 controllerOverride: root.launcherController transientSurfaceTracker: root.transientSurfaceTracker showResultsWithoutQuery: true diff --git a/quickshell/Modules/Dock/DockAppButton.qml b/quickshell/Modules/Dock/DockAppButton.qml index 11e4d6ab7..4ebed713d 100644 --- a/quickshell/Modules/Dock/DockAppButton.qml +++ b/quickshell/Modules/Dock/DockAppButton.qml @@ -144,16 +144,11 @@ Item { return overviewFocused ? toplevels.indexOf(overviewFocused) : -1; } - function cycleGroupedToplevels() { - const toplevels = getGroupedToplevels(); - if (toplevels.length === 0) + function showContextMenu() { + if (!contextMenu) return; - - const currentIndex = getActiveGroupedToplevelIndex(toplevels); - const nextToplevel = toplevels[(currentIndex + 1) % toplevels.length]; - if (restoreSpecialWorkspaceWindow(nextToplevel)) - return; - CompositorService.activateToplevel(nextToplevel); + const shouldHidePin = appData.appId === "org.quickshell" || appData.appId === "com.danklinux.dms"; + contextMenu.showForButton(root, appData, root.height, shouldHidePin, cachedDesktopEntry, parentDockScreen, dockApps); } function activate() { mouseArea.handleLeftClick(); @@ -312,7 +307,7 @@ Item { CompositorService.toggleToplevel(groupedToplevel); } } else { - cycleGroupedToplevels(); + root.showContextMenu(); } break; } @@ -380,10 +375,7 @@ Item { break; } } else if (mouse.button === Qt.RightButton) { - if (!contextMenu) - return; - const shouldHidePin = appData.appId === "org.quickshell" || appData.appId === "com.danklinux.dms"; - contextMenu.showForButton(root, appData, root.height, shouldHidePin, cachedDesktopEntry, parentDockScreen, dockApps); + root.showContextMenu(); } } } diff --git a/quickshell/Modules/WorkspaceOverlays/NiriOverviewOverlay.qml b/quickshell/Modules/WorkspaceOverlays/NiriOverviewOverlay.qml index 9afc25bde..3258dfbd4 100644 --- a/quickshell/Modules/WorkspaceOverlays/NiriOverviewOverlay.qml +++ b/quickshell/Modules/WorkspaceOverlays/NiriOverviewOverlay.qml @@ -111,6 +111,7 @@ Scope { readonly property real alignedX: spotlightContainer.x readonly property real alignedY: spotlightContainer.y readonly property real screenHeight: overlayWindow.screen?.height ?? 1080 + readonly property real frameBottomRadius: spotlightContainer.bottomRadius function hide() { if (niriOverviewScope.searchActive) { niriOverviewScope.hideSpotlight();