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:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user