1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

niri: fix exit anims on overview launcher

This commit is contained in:
bbedward
2025-11-25 14:54:29 -05:00
parent 004a014000
commit 8de77f283d
2 changed files with 287 additions and 264 deletions

View File

@@ -1,5 +1,4 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Modals.Spotlight
import qs.Modules.AppDrawer
@@ -17,33 +16,33 @@ Item {
function resetScroll() {
if (searchMode === "apps") {
resultsView.resetScroll()
resultsView.resetScroll();
} else {
fileSearchResults.resetScroll()
fileSearchResults.resetScroll();
}
}
function updateSearchMode() {
if (searchField.text.startsWith("/")) {
if (searchMode !== "files") {
searchMode = "files"
searchMode = "files";
}
const query = searchField.text.substring(1)
fileSearchController.searchQuery = query
const query = searchField.text.substring(1);
fileSearchController.searchQuery = query;
} else {
if (searchMode !== "apps") {
searchMode = "apps"
fileSearchController.reset()
appLauncher.searchQuery = searchField.text
searchMode = "apps";
fileSearchController.reset();
appLauncher.searchQuery = searchField.text;
}
}
}
onSearchModeChanged: {
if (searchMode === "files") {
appLauncher.keyboardNavigationActive = false
appLauncher.keyboardNavigationActive = false;
} else {
fileSearchController.keyboardNavigationActive = false
fileSearchController.keyboardNavigationActive = false;
}
}
@@ -51,104 +50,104 @@ Item {
focus: true
clip: false
Keys.onPressed: event => {
if (event.key === Qt.Key_Escape) {
if (parentModal)
parentModal.hide()
if (event.key === Qt.Key_Escape) {
if (parentModal)
parentModal.hide();
event.accepted = true
} else if (event.key === Qt.Key_Down) {
if (searchMode === "apps") {
appLauncher.selectNext()
} else {
fileSearchController.selectNext()
}
event.accepted = true
} else if (event.key === Qt.Key_Up) {
if (searchMode === "apps") {
appLauncher.selectPrevious()
} else {
fileSearchController.selectPrevious()
}
event.accepted = true
} else if (event.key === Qt.Key_Right && searchMode === "apps" && appLauncher.viewMode === "grid") {
appLauncher.selectNextInRow()
event.accepted = true
} else if (event.key === Qt.Key_Left && searchMode === "apps" && appLauncher.viewMode === "grid") {
appLauncher.selectPreviousInRow()
event.accepted = true
} else if (event.key == Qt.Key_J && event.modifiers & Qt.ControlModifier) {
if (searchMode === "apps") {
appLauncher.selectNext()
} else {
fileSearchController.selectNext()
}
event.accepted = true
} else if (event.key == Qt.Key_K && event.modifiers & Qt.ControlModifier) {
if (searchMode === "apps") {
appLauncher.selectPrevious()
} else {
fileSearchController.selectPrevious()
}
event.accepted = true
} else if (event.key == Qt.Key_L && event.modifiers & Qt.ControlModifier && searchMode === "apps" && appLauncher.viewMode === "grid") {
appLauncher.selectNextInRow()
event.accepted = true
} else if (event.key == Qt.Key_H && event.modifiers & Qt.ControlModifier && searchMode === "apps" && appLauncher.viewMode === "grid") {
appLauncher.selectPreviousInRow()
event.accepted = true
} else if (event.key === Qt.Key_Tab) {
if (searchMode === "apps") {
if (appLauncher.viewMode === "grid") {
appLauncher.selectNextInRow()
} else {
appLauncher.selectNext()
}
} else {
fileSearchController.selectNext()
}
event.accepted = true
} else if (event.key === Qt.Key_Backtab) {
if (searchMode === "apps") {
if (appLauncher.viewMode === "grid") {
appLauncher.selectPreviousInRow()
} else {
appLauncher.selectPrevious()
}
} else {
fileSearchController.selectPrevious()
}
event.accepted = true
} else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
if (searchMode === "apps") {
if (appLauncher.viewMode === "grid") {
appLauncher.selectNextInRow()
} else {
appLauncher.selectNext()
}
} else {
fileSearchController.selectNext()
}
event.accepted = true
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
if (searchMode === "apps") {
if (appLauncher.viewMode === "grid") {
appLauncher.selectPreviousInRow()
} else {
appLauncher.selectPrevious()
}
} else {
fileSearchController.selectPrevious()
}
event.accepted = true
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
if (searchMode === "apps") {
appLauncher.launchSelected()
} else if (searchMode === "files") {
fileSearchController.openSelected()
}
event.accepted = true
}
}
event.accepted = true;
} else if (event.key === Qt.Key_Down) {
if (searchMode === "apps") {
appLauncher.selectNext();
} else {
fileSearchController.selectNext();
}
event.accepted = true;
} else if (event.key === Qt.Key_Up) {
if (searchMode === "apps") {
appLauncher.selectPrevious();
} else {
fileSearchController.selectPrevious();
}
event.accepted = true;
} else if (event.key === Qt.Key_Right && searchMode === "apps" && appLauncher.viewMode === "grid") {
appLauncher.selectNextInRow();
event.accepted = true;
} else if (event.key === Qt.Key_Left && searchMode === "apps" && appLauncher.viewMode === "grid") {
appLauncher.selectPreviousInRow();
event.accepted = true;
} else if (event.key == Qt.Key_J && event.modifiers & Qt.ControlModifier) {
if (searchMode === "apps") {
appLauncher.selectNext();
} else {
fileSearchController.selectNext();
}
event.accepted = true;
} else if (event.key == Qt.Key_K && event.modifiers & Qt.ControlModifier) {
if (searchMode === "apps") {
appLauncher.selectPrevious();
} else {
fileSearchController.selectPrevious();
}
event.accepted = true;
} else if (event.key == Qt.Key_L && event.modifiers & Qt.ControlModifier && searchMode === "apps" && appLauncher.viewMode === "grid") {
appLauncher.selectNextInRow();
event.accepted = true;
} else if (event.key == Qt.Key_H && event.modifiers & Qt.ControlModifier && searchMode === "apps" && appLauncher.viewMode === "grid") {
appLauncher.selectPreviousInRow();
event.accepted = true;
} else if (event.key === Qt.Key_Tab) {
if (searchMode === "apps") {
if (appLauncher.viewMode === "grid") {
appLauncher.selectNextInRow();
} else {
appLauncher.selectNext();
}
} else {
fileSearchController.selectNext();
}
event.accepted = true;
} else if (event.key === Qt.Key_Backtab) {
if (searchMode === "apps") {
if (appLauncher.viewMode === "grid") {
appLauncher.selectPreviousInRow();
} else {
appLauncher.selectPrevious();
}
} else {
fileSearchController.selectPrevious();
}
event.accepted = true;
} else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
if (searchMode === "apps") {
if (appLauncher.viewMode === "grid") {
appLauncher.selectNextInRow();
} else {
appLauncher.selectNext();
}
} else {
fileSearchController.selectNext();
}
event.accepted = true;
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
if (searchMode === "apps") {
if (appLauncher.viewMode === "grid") {
appLauncher.selectPreviousInRow();
} else {
appLauncher.selectPrevious();
}
} else {
fileSearchController.selectPrevious();
}
event.accepted = true;
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
if (searchMode === "apps") {
appLauncher.launchSelected();
} else if (searchMode === "files") {
fileSearchController.openSelected();
}
event.accepted = true;
}
}
AppLauncher {
id: appLauncher
@@ -156,29 +155,27 @@ Item {
viewMode: SettingsData.spotlightModalViewMode
gridColumns: SettingsData.appLauncherGridColumns
onAppLaunched: () => {
if (parentModal)
parentModal.hide()
if (SettingsData.spotlightCloseNiriOverview && NiriService.inOverview) {
NiriService.toggleOverview()
}
}
if (parentModal)
parentModal.hide();
if (SettingsData.spotlightCloseNiriOverview && NiriService.inOverview) {
NiriService.toggleOverview();
}
}
onViewModeSelected: mode => {
SettingsData.set("spotlightModalViewMode", mode)
}
SettingsData.set("spotlightModalViewMode", mode);
}
}
FileSearchController {
id: fileSearchController
onFileOpened: () => {
if (parentModal)
parentModal.hide()
if (SettingsData.spotlightCloseNiriOverview && NiriService.inOverview) {
NiriService.toggleOverview()
}
}
if (parentModal)
parentModal.hide();
if (SettingsData.spotlightCloseNiriOverview && NiriService.inOverview) {
NiriService.toggleOverview();
}
}
}
Column {
@@ -216,34 +213,33 @@ Item {
keyForwardTargets: [spotlightKeyHandler]
onTextChanged: {
if (searchMode === "apps") {
appLauncher.searchQuery = text
appLauncher.searchQuery = text;
}
}
onTextEdited: {
updateSearchMode()
updateSearchMode();
}
Keys.onPressed: event => {
if (event.key === Qt.Key_Escape) {
if (parentModal)
parentModal.hide()
if (event.key === Qt.Key_Escape) {
if (parentModal)
parentModal.hide();
event.accepted = true
} else if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length > 0) {
if (searchMode === "apps") {
if (appLauncher.keyboardNavigationActive && appLauncher.model.count > 0)
appLauncher.launchSelected()
else if (appLauncher.model.count > 0)
appLauncher.launchApp(appLauncher.model.get(0))
} else if (searchMode === "files") {
if (fileSearchController.model.count > 0)
fileSearchController.openSelected()
}
event.accepted = true
} else if (event.key === Qt.Key_Down || event.key === Qt.Key_Up || event.key === Qt.Key_Left || event.key === Qt.Key_Right || event.key === Qt.Key_Tab || event.key
=== Qt.Key_Backtab || ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length === 0)) {
event.accepted = false
}
}
event.accepted = true;
} else if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length > 0) {
if (searchMode === "apps") {
if (appLauncher.keyboardNavigationActive && appLauncher.model.count > 0)
appLauncher.launchSelected();
else if (appLauncher.model.count > 0)
appLauncher.launchApp(appLauncher.model.get(0));
} else if (searchMode === "files") {
if (fileSearchController.model.count > 0)
fileSearchController.openSelected();
}
event.accepted = true;
} else if (event.key === Qt.Key_Down || event.key === Qt.Key_Up || event.key === Qt.Key_Left || event.key === Qt.Key_Right || event.key === Qt.Key_Tab || event.key === Qt.Key_Backtab || ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length === 0)) {
event.accepted = false;
}
}
}
Row {
@@ -271,8 +267,8 @@ Item {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: () => {
appLauncher.setViewMode("list")
}
appLauncher.setViewMode("list");
}
}
}
@@ -296,8 +292,8 @@ Item {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: () => {
appLauncher.setViewMode("grid")
}
appLauncher.setViewMode("grid");
}
}
}
}
@@ -329,22 +325,22 @@ Item {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: () => {
fileSearchController.searchField = "filename"
}
fileSearchController.searchField = "filename";
}
onEntered: {
filenameTooltipLoader.active = true
filenameTooltipLoader.active = true;
Qt.callLater(() => {
if (filenameTooltipLoader.item) {
const p = mapToItem(null, width / 2, height + Theme.spacingXS)
filenameTooltipLoader.item.show(I18n.tr("Search filenames"), p.x, p.y, null)
}
})
if (filenameTooltipLoader.item) {
const p = mapToItem(null, width / 2, height + Theme.spacingXS);
filenameTooltipLoader.item.show(I18n.tr("Search filenames"), p.x, p.y, null);
}
});
}
onExited: {
if (filenameTooltipLoader.item)
filenameTooltipLoader.item.hide()
filenameTooltipLoader.item.hide();
filenameTooltipLoader.active = false
filenameTooltipLoader.active = false;
}
}
}
@@ -371,22 +367,22 @@ Item {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: () => {
fileSearchController.searchField = "body"
}
fileSearchController.searchField = "body";
}
onEntered: {
contentTooltipLoader.active = true
contentTooltipLoader.active = true;
Qt.callLater(() => {
if (contentTooltipLoader.item) {
const p = mapToItem(null, width / 2, height + Theme.spacingXS)
contentTooltipLoader.item.show(I18n.tr("Search file contents"), p.x, p.y, null)
}
})
if (contentTooltipLoader.item) {
const p = mapToItem(null, width / 2, height + Theme.spacingXS);
contentTooltipLoader.item.show(I18n.tr("Search file contents"), p.x, p.y, null);
}
});
}
onExited: {
if (contentTooltipLoader.item)
contentTooltipLoader.item.hide()
contentTooltipLoader.item.hide();
contentTooltipLoader.active = false
contentTooltipLoader.active = false;
}
}
}
@@ -426,8 +422,8 @@ Item {
visible: contextMenu.visible
z: 999
onClicked: () => {
contextMenu.hide()
}
contextMenu.hide();
}
MouseArea {

View File

@@ -11,48 +11,65 @@ Scope {
property bool searchActive: false
property string searchActiveScreen: ""
property bool overlayActive: NiriService.inOverview && !(PopoutService.spotlightModal?.spotlightOpen ?? false)
property bool isClosing: false
property bool overlayActive: (NiriService.inOverview && !(PopoutService.spotlightModal?.spotlightOpen ?? false)) || searchActive
function showSpotlight(screenName) {
searchActive = true
searchActiveScreen = screenName
isClosing = false;
searchActive = true;
searchActiveScreen = screenName;
}
function hideSpotlight() {
searchActive = false
searchActiveScreen = ""
if (!searchActive)
return;
isClosing = true;
}
function completeHide() {
searchActive = false;
searchActiveScreen = "";
isClosing = false;
}
Connections {
target: NiriService
function onInOverviewChanged() {
if (!NiriService.inOverview) {
hideSpotlight()
} else {
searchActive = false
searchActiveScreen = ""
if (searchActive) {
isClosing = true;
return;
}
closeOverviewAfterAnim = false;
searchActive = false;
searchActiveScreen = "";
isClosing = false;
return;
}
searchActive = false;
searchActiveScreen = "";
isClosing = false;
}
function onCurrentOutputChanged() {
if (NiriService.inOverview && searchActive && searchActiveScreen !== "" && searchActiveScreen !== NiriService.currentOutput) {
hideSpotlight()
}
if (!NiriService.inOverview || !searchActive || searchActiveScreen === "" || searchActiveScreen === NiriService.currentOutput)
return;
hideSpotlight();
}
}
Connections {
target: PopoutService.spotlightModal
function onSpotlightOpenChanged() {
if (PopoutService.spotlightModal?.spotlightOpen && searchActive) {
hideSpotlight()
}
if (!PopoutService.spotlightModal?.spotlightOpen || !searchActive)
return;
hideSpotlight();
}
}
Loader {
id: niriOverlayLoader
active: overlayActive
active: overlayActive || isClosing
asynchronous: false
sourceComponent: Variants {
@@ -65,29 +82,34 @@ Scope {
readonly property real dpr: CompositorService.getScreenScale(screen)
readonly property bool isActiveScreen: screen.name === NiriService.currentOutput
readonly property bool shouldShowSpotlight: niriOverviewScope.searchActive && screen.name === niriOverviewScope.searchActiveScreen
readonly property bool shouldShowSpotlight: niriOverviewScope.searchActive && screen.name === niriOverviewScope.searchActiveScreen && !niriOverviewScope.isClosing
readonly property bool isSpotlightScreen: screen.name === niriOverviewScope.searchActiveScreen
screen: modelData
visible: NiriService.inOverview
visible: NiriService.inOverview || niriOverviewScope.isClosing
color: "transparent"
WlrLayershell.namespace: "dms:niri-overview-spotlight"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: {
if (!NiriService.inOverview) return WlrKeyboardFocus.None
if (!isActiveScreen) return WlrKeyboardFocus.None
return WlrKeyboardFocus.Exclusive
if (!NiriService.inOverview)
return WlrKeyboardFocus.None;
if (!isActiveScreen)
return WlrKeyboardFocus.None;
if (niriOverviewScope.isClosing)
return WlrKeyboardFocus.None;
return WlrKeyboardFocus.Exclusive;
}
mask: Region {
item: shouldShowSpotlight ? spotlightContainer : null
item: spotlightContainer.visible ? spotlightContainer : null
}
onShouldShowSpotlightChanged: {
if (!shouldShowSpotlight && isActiveScreen) {
Qt.callLater(() => keyboardFocusScope.forceActiveFocus())
}
if (shouldShowSpotlight || !isActiveScreen)
return;
Qt.callLater(() => keyboardFocusScope.forceActiveFocus());
}
anchors {
@@ -97,61 +119,62 @@ Scope {
bottom: true
}
FocusScope {
id: keyboardFocusScope
anchors.fill: parent
focus: true
Keys.onPressed: event => {
if (!overlayWindow.shouldShowSpotlight) {
if ([Qt.Key_Escape, Qt.Key_Return].includes(event.key)) {
NiriService.toggleOverview()
event.accepted = true
return
}
if (event.key === Qt.Key_Left) {
NiriService.moveColumnLeft()
event.accepted = true
return
}
if (event.key === Qt.Key_Right) {
NiriService.moveColumnRight()
event.accepted = true
return
}
if (event.key === Qt.Key_Up) {
NiriService.moveWorkspaceUp()
event.accepted = true
return
}
if (event.key === Qt.Key_Down) {
NiriService.moveWorkspaceDown()
event.accepted = true
return
}
if (event.modifiers & (Qt.ControlModifier | Qt.MetaModifier) || [Qt.Key_Delete, Qt.Key_Backspace].includes(event.key)) {
event.accepted = false
return
}
if (!event.isAutoRepeat && event.text) {
niriOverviewScope.showSpotlight(overlayWindow.screen.name)
if (spotlightContent?.searchField) {
spotlightContent.searchField.text = event.text.trim()
if (spotlightContent.appLauncher) {
spotlightContent.appLauncher.searchQuery = event.text.trim()
}
Qt.callLater(() => spotlightContent.searchField.forceActiveFocus())
}
event.accepted = true
}
if (overlayWindow.shouldShowSpotlight || niriOverviewScope.isClosing)
return;
if ([Qt.Key_Escape, Qt.Key_Return].includes(event.key)) {
NiriService.toggleOverview();
event.accepted = true;
return;
}
if (event.key === Qt.Key_Left) {
NiriService.moveColumnLeft();
event.accepted = true;
return;
}
if (event.key === Qt.Key_Right) {
NiriService.moveColumnRight();
event.accepted = true;
return;
}
if (event.key === Qt.Key_Up) {
NiriService.moveWorkspaceUp();
event.accepted = true;
return;
}
if (event.key === Qt.Key_Down) {
NiriService.moveWorkspaceDown();
event.accepted = true;
return;
}
if (event.modifiers & (Qt.ControlModifier | Qt.MetaModifier) || [Qt.Key_Delete, Qt.Key_Backspace].includes(event.key)) {
event.accepted = false;
return;
}
if (event.isAutoRepeat || !event.text)
return;
if (!spotlightContent?.searchField)
return;
const trimmedText = event.text.trim();
spotlightContainer.waitingForResults = true;
spotlightContent.searchField.text = trimmedText;
if (spotlightContent.appLauncher) {
spotlightContent.appLauncher.searchQuery = trimmedText;
}
niriOverviewScope.showSpotlight(overlayWindow.screen.name);
Qt.callLater(() => spotlightContent.searchField.forceActiveFocus());
event.accepted = true;
}
}
@@ -162,28 +185,35 @@ Scope {
width: Theme.px(500, overlayWindow.dpr)
height: Theme.px(600, overlayWindow.dpr)
property real scaleValue: 0.96
readonly property bool animatingOut: niriOverviewScope.isClosing && overlayWindow.isSpotlightScreen
property bool waitingForResults: false
scale: scaleValue
opacity: overlayWindow.shouldShowSpotlight ? 1 : 0
Connections {
target: spotlightContent.appLauncher?.model ?? null
function onCountChanged() {
spotlightContainer.waitingForResults = false;
}
}
scale: (overlayWindow.shouldShowSpotlight && !waitingForResults) ? 1.0 : 0.96
opacity: (overlayWindow.shouldShowSpotlight && !waitingForResults) ? 1 : 0
visible: (overlayWindow.shouldShowSpotlight && !waitingForResults) || animatingOut
enabled: overlayWindow.shouldShowSpotlight
layer.enabled: true
layer.smooth: false
layer.textureSize: Qt.size(Math.round(width * overlayWindow.dpr), Math.round(height * overlayWindow.dpr))
Connections {
target: overlayWindow
function onShouldShowSpotlightChanged() {
spotlightContainer.scaleValue = overlayWindow.shouldShowSpotlight ? 1.0 : 0.96
}
}
Behavior on scaleValue {
Behavior on scale {
NumberAnimation {
duration: Theme.expressiveDurations.expressiveDefaultSpatial
easing.type: Easing.BezierSpline
easing.bezierCurve: niriOverviewScope.searchActive ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized
easing.bezierCurve: spotlightContainer.visible ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized
onRunningChanged: {
if (running || !spotlightContainer.animatingOut)
return;
niriOverviewScope.completeHide();
}
}
}
@@ -191,7 +221,7 @@ Scope {
NumberAnimation {
duration: Theme.expressiveDurations.expressiveDefaultSpatial
easing.type: Easing.BezierSpline
easing.bezierCurve: niriOverviewScope.searchActive ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized
easing.bezierCurve: spotlightContainer.visible ? Theme.expressiveCurves.expressiveDefaultSpatial : Theme.expressiveCurves.emphasized
}
}
@@ -209,17 +239,14 @@ Scope {
anchors.margins: 0
property var fakeParentModal: QtObject {
property bool spotlightOpen: overlayWindow.shouldShowSpotlight
property bool spotlightOpen: spotlightContainer.visible
function hide() {
niriOverviewScope.hideSpotlight()
if (overlayWindow.isActiveScreen) {
Qt.callLater(() => keyboardFocusScope.forceActiveFocus())
}
niriOverviewScope.hideSpotlight();
}
}
Component.onCompleted: {
parentModal = fakeParentModal
parentModal = fakeParentModal;
}
}
}