1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

niri: track open modals in modal manager for focus transfers

This commit is contained in:
bbedward
2025-12-17 20:21:34 -05:00
parent 18231ed324
commit 2e4d56728b
6 changed files with 79 additions and 61 deletions

View File

@@ -8,6 +8,9 @@ Singleton {
id: modalManager
signal closeAllModalsExcept(var excludedModal)
signal modalChanged
property var currentModalsByScreen: ({})
function openModal(modal) {
if (!modal.allowStacking) {
@@ -17,5 +20,17 @@ Singleton {
PopoutManager.closeAllPopouts();
}
TrayMenuManager.closeAllMenus();
const screenName = modal.effectiveScreen?.name ?? "unknown";
currentModalsByScreen[screenName] = modal;
modalChanged();
}
function closeModal(modal) {
const screenName = modal.effectiveScreen?.name ?? "unknown";
if (currentModalsByScreen[screenName] === modal) {
delete currentModalsByScreen[screenName];
modalChanged();
}
}
}

View File

@@ -715,7 +715,42 @@ Singleton {
}
function detectAvailableIconThemes() {
Processes.detectIcons();
const xdgDataDirs = Quickshell.env("XDG_DATA_DIRS") || "";
const localData = Paths.strip(StandardPaths.writableLocation(StandardPaths.GenericDataLocation));
const homeDir = Paths.strip(StandardPaths.writableLocation(StandardPaths.HomeLocation));
const dataDirs = xdgDataDirs.trim() !== "" ? xdgDataDirs.split(":").concat([localData]) : ["/usr/share", "/usr/local/share", localData];
const iconPaths = dataDirs.map(d => d + "/icons").concat([homeDir + "/.icons"]);
const pathsArg = iconPaths.join(" ");
const script = `
echo "SYSDEFAULT:$(gsettings get org.gnome.desktop.interface icon-theme 2>/dev/null | sed "s/'//g" || echo '')"
for dir in ${pathsArg}; do
[ -d "$dir" ] || continue
for theme in "$dir"/*/; do
[ -d "$theme" ] || continue
basename "$theme"
done
done | grep -v '^icons$' | grep -v '^default$' | grep -v '^hicolor$' | grep -v '^locolor$' | sort -u
`;
Proc.runCommand("detectIconThemes", ["sh", "-c", script], (output, exitCode) => {
const themes = ["System Default"];
if (output && output.trim()) {
const lines = output.trim().split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.startsWith("SYSDEFAULT:")) {
systemDefaultIconTheme = line.substring(11).trim();
continue;
}
if (line)
themes.push(line);
}
}
availableIconThemes = themes;
});
}
function getEffectiveTimeFormat() {

View File

@@ -1,5 +1,4 @@
pragma Singleton
pragma ComponentBehavior: Bound
import QtQuick
@@ -11,61 +10,20 @@ Singleton {
property var settingsRoot: null
function detectIcons() {
systemDefaultDetectionProcess.running = true
}
function detectQtTools() {
qtToolsDetectionProcess.running = true
qtToolsDetectionProcess.running = true;
}
function detectFprintd() {
fprintdDetectionProcess.running = true
fprintdDetectionProcess.running = true;
}
function checkPluginSettings() {
pluginSettingsCheckProcess.running = true
pluginSettingsCheckProcess.running = true;
}
function checkDefaultSettings() {
defaultSettingsCheckProcess.running = true
}
property var systemDefaultDetectionProcess: Process {
command: ["sh", "-c", "gsettings get org.gnome.desktop.interface icon-theme 2>/dev/null | sed \"s/'//g\" || echo ''"]
running: false
onExited: function(exitCode) {
if (!settingsRoot) return;
if (exitCode === 0 && stdout && stdout.length > 0) {
settingsRoot.systemDefaultIconTheme = stdout.trim();
} else {
settingsRoot.systemDefaultIconTheme = "";
}
iconThemeDetectionProcess.running = true;
}
}
property var iconThemeDetectionProcess: Process {
command: ["sh", "-c", "find /usr/share/icons ~/.local/share/icons ~/.icons -maxdepth 1 -type d 2>/dev/null | sed 's|.*/||' | grep -v '^icons$' | sort -u"]
running: false
stdout: StdioCollector {
onStreamFinished: {
if (!settingsRoot) return
var detectedThemes = ["System Default"]
if (text && text.trim()) {
var themes = text.trim().split('\n')
for (var i = 0; i < themes.length; i++) {
var theme = themes[i].trim()
if (theme && theme !== "" && theme !== "default" && theme !== "hicolor" && theme !== "locolor") {
detectedThemes.push(theme)
}
}
}
settingsRoot.availableIconThemes = detectedThemes
}
}
defaultSettingsCheckProcess.running = true;
}
property var qtToolsDetectionProcess: Process {
@@ -74,7 +32,8 @@ Singleton {
stdout: StdioCollector {
onStreamFinished: {
if (!settingsRoot) return;
if (!settingsRoot)
return;
if (text && text.trim()) {
var lines = text.trim().split('\n');
for (var i = 0; i < lines.length; i++) {
@@ -96,7 +55,8 @@ Singleton {
command: ["sh", "-c", "CONFIG_DIR=\"" + (settingsRoot?._configDir || "") + "/DankMaterialShell\"; if [ -f \"$CONFIG_DIR/default-settings.json\" ] && [ ! -f \"$CONFIG_DIR/settings.json\" ]; then cp --no-preserve=mode \"$CONFIG_DIR/default-settings.json\" \"$CONFIG_DIR/settings.json\" && echo 'copied'; else echo 'not_found'; fi"]
running: false
onExited: function (exitCode) {
if (!settingsRoot) return;
if (!settingsRoot)
return;
if (exitCode === 0) {
console.info("Copied default-settings.json to settings.json");
if (settingsRoot.settingsFile) {
@@ -114,7 +74,8 @@ Singleton {
command: ["sh", "-c", "command -v fprintd-list >/dev/null 2>&1"]
running: false
onExited: function (exitCode) {
if (!settingsRoot) return;
if (!settingsRoot)
return;
settingsRoot.fprintdAvailable = (exitCode === 0);
}
}
@@ -124,7 +85,8 @@ Singleton {
running: false
onExited: function (exitCode) {
if (!settingsRoot) return;
if (!settingsRoot)
return;
settingsRoot.pluginSettingsFileExists = (exitCode === 0);
}
}

View File

@@ -83,6 +83,7 @@ Item {
function close() {
shouldBeVisible = false;
shouldHaveFocus = false;
ModalManager.closeModal(root);
closeTimer.restart();
}
@@ -90,6 +91,7 @@ Item {
animationsEnabled = false;
shouldBeVisible = false;
shouldHaveFocus = false;
ModalManager.closeModal(root);
closeTimer.stop();
contentWindow.visible = false;
if (useBackgroundWindow)

View File

@@ -10,15 +10,11 @@ import qs.Modules.Settings.Widgets
Item {
id: themeColorsTab
property var cachedIconThemes: []
property var cachedMatugenSchemes: []
property var cachedIconThemes: SettingsData.availableIconThemes
property var cachedMatugenSchemes: Theme.availableMatugenSchemes.map(option => option.label)
Component.onCompleted: {
SettingsData.detectAvailableIconThemes();
cachedIconThemes = SettingsData.availableIconThemes;
cachedMatugenSchemes = Theme.availableMatugenSchemes.map(function (option) {
return option.label;
});
}
DankFlickable {

View File

@@ -92,6 +92,7 @@ Scope {
readonly property bool shouldShowSpotlight: niriOverviewScope.searchActive && screen.name === niriOverviewScope.searchActiveScreen && !niriOverviewScope.isClosing
readonly property bool isSpotlightScreen: screen.name === niriOverviewScope.searchActiveScreen
property bool hasActivePopout: !!PopoutManager.currentPopoutsByScreen[screen.name]
property bool hasActiveModal: !!ModalManager.currentModalsByScreen[screen.name]
Connections {
target: PopoutManager
@@ -100,6 +101,13 @@ Scope {
}
}
Connections {
target: ModalManager
function onModalChanged() {
overlayWindow.hasActiveModal = !!ModalManager.currentModalsByScreen[overlayWindow.screen.name];
}
}
screen: modelData
visible: NiriService.inOverview || niriOverviewScope.isClosing
color: "transparent"
@@ -114,7 +122,7 @@ Scope {
return WlrKeyboardFocus.None;
if (niriOverviewScope.releaseKeyboard)
return WlrKeyboardFocus.None;
if (hasActivePopout)
if (hasActivePopout || hasActiveModal)
return WlrKeyboardFocus.None;
return WlrKeyboardFocus.Exclusive;
}