launcher: inset spotlight results and clip them to the frame radius

fixes #3498
This commit is contained in:
bbedward
2026-09-19 22:12:29 -04:00
parent 84594e6449
commit 60e79909c0
5 changed files with 20 additions and 17 deletions
@@ -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) {
@@ -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) => {
@@ -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
+6 -14
View File
@@ -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();
}
}
}
@@ -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();