mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-31 00:42:50 -05:00
niri: track open modals in modal manager for focus transfers
This commit is contained in:
@@ -8,6 +8,9 @@ Singleton {
|
|||||||
id: modalManager
|
id: modalManager
|
||||||
|
|
||||||
signal closeAllModalsExcept(var excludedModal)
|
signal closeAllModalsExcept(var excludedModal)
|
||||||
|
signal modalChanged
|
||||||
|
|
||||||
|
property var currentModalsByScreen: ({})
|
||||||
|
|
||||||
function openModal(modal) {
|
function openModal(modal) {
|
||||||
if (!modal.allowStacking) {
|
if (!modal.allowStacking) {
|
||||||
@@ -17,5 +20,17 @@ Singleton {
|
|||||||
PopoutManager.closeAllPopouts();
|
PopoutManager.closeAllPopouts();
|
||||||
}
|
}
|
||||||
TrayMenuManager.closeAllMenus();
|
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() {
|
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() {
|
function getEffectiveTimeFormat() {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
@@ -11,61 +10,20 @@ Singleton {
|
|||||||
|
|
||||||
property var settingsRoot: null
|
property var settingsRoot: null
|
||||||
|
|
||||||
function detectIcons() {
|
|
||||||
systemDefaultDetectionProcess.running = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function detectQtTools() {
|
function detectQtTools() {
|
||||||
qtToolsDetectionProcess.running = true
|
qtToolsDetectionProcess.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectFprintd() {
|
function detectFprintd() {
|
||||||
fprintdDetectionProcess.running = true
|
fprintdDetectionProcess.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkPluginSettings() {
|
function checkPluginSettings() {
|
||||||
pluginSettingsCheckProcess.running = true
|
pluginSettingsCheckProcess.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkDefaultSettings() {
|
function checkDefaultSettings() {
|
||||||
defaultSettingsCheckProcess.running = true
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property var qtToolsDetectionProcess: Process {
|
property var qtToolsDetectionProcess: Process {
|
||||||
@@ -74,7 +32,8 @@ Singleton {
|
|||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
if (!settingsRoot) return;
|
if (!settingsRoot)
|
||||||
|
return;
|
||||||
if (text && text.trim()) {
|
if (text && text.trim()) {
|
||||||
var lines = text.trim().split('\n');
|
var lines = text.trim().split('\n');
|
||||||
for (var i = 0; i < lines.length; i++) {
|
for (var i = 0; i < lines.length; i++) {
|
||||||
@@ -95,8 +54,9 @@ Singleton {
|
|||||||
property var defaultSettingsCheckProcess: Process {
|
property var defaultSettingsCheckProcess: Process {
|
||||||
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"]
|
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
|
running: false
|
||||||
onExited: function(exitCode) {
|
onExited: function (exitCode) {
|
||||||
if (!settingsRoot) return;
|
if (!settingsRoot)
|
||||||
|
return;
|
||||||
if (exitCode === 0) {
|
if (exitCode === 0) {
|
||||||
console.info("Copied default-settings.json to settings.json");
|
console.info("Copied default-settings.json to settings.json");
|
||||||
if (settingsRoot.settingsFile) {
|
if (settingsRoot.settingsFile) {
|
||||||
@@ -113,8 +73,9 @@ Singleton {
|
|||||||
property var fprintdDetectionProcess: Process {
|
property var fprintdDetectionProcess: Process {
|
||||||
command: ["sh", "-c", "command -v fprintd-list >/dev/null 2>&1"]
|
command: ["sh", "-c", "command -v fprintd-list >/dev/null 2>&1"]
|
||||||
running: false
|
running: false
|
||||||
onExited: function(exitCode) {
|
onExited: function (exitCode) {
|
||||||
if (!settingsRoot) return;
|
if (!settingsRoot)
|
||||||
|
return;
|
||||||
settingsRoot.fprintdAvailable = (exitCode === 0);
|
settingsRoot.fprintdAvailable = (exitCode === 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,8 +84,9 @@ Singleton {
|
|||||||
command: ["test", "-f", settingsRoot?.pluginSettingsPath || ""]
|
command: ["test", "-f", settingsRoot?.pluginSettingsPath || ""]
|
||||||
running: false
|
running: false
|
||||||
|
|
||||||
onExited: function(exitCode) {
|
onExited: function (exitCode) {
|
||||||
if (!settingsRoot) return;
|
if (!settingsRoot)
|
||||||
|
return;
|
||||||
settingsRoot.pluginSettingsFileExists = (exitCode === 0);
|
settingsRoot.pluginSettingsFileExists = (exitCode === 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ Item {
|
|||||||
function close() {
|
function close() {
|
||||||
shouldBeVisible = false;
|
shouldBeVisible = false;
|
||||||
shouldHaveFocus = false;
|
shouldHaveFocus = false;
|
||||||
|
ModalManager.closeModal(root);
|
||||||
closeTimer.restart();
|
closeTimer.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +91,7 @@ Item {
|
|||||||
animationsEnabled = false;
|
animationsEnabled = false;
|
||||||
shouldBeVisible = false;
|
shouldBeVisible = false;
|
||||||
shouldHaveFocus = false;
|
shouldHaveFocus = false;
|
||||||
|
ModalManager.closeModal(root);
|
||||||
closeTimer.stop();
|
closeTimer.stop();
|
||||||
contentWindow.visible = false;
|
contentWindow.visible = false;
|
||||||
if (useBackgroundWindow)
|
if (useBackgroundWindow)
|
||||||
|
|||||||
@@ -10,15 +10,11 @@ import qs.Modules.Settings.Widgets
|
|||||||
Item {
|
Item {
|
||||||
id: themeColorsTab
|
id: themeColorsTab
|
||||||
|
|
||||||
property var cachedIconThemes: []
|
property var cachedIconThemes: SettingsData.availableIconThemes
|
||||||
property var cachedMatugenSchemes: []
|
property var cachedMatugenSchemes: Theme.availableMatugenSchemes.map(option => option.label)
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
SettingsData.detectAvailableIconThemes();
|
SettingsData.detectAvailableIconThemes();
|
||||||
cachedIconThemes = SettingsData.availableIconThemes;
|
|
||||||
cachedMatugenSchemes = Theme.availableMatugenSchemes.map(function (option) {
|
|
||||||
return option.label;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DankFlickable {
|
DankFlickable {
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ Scope {
|
|||||||
readonly property bool shouldShowSpotlight: niriOverviewScope.searchActive && screen.name === niriOverviewScope.searchActiveScreen && !niriOverviewScope.isClosing
|
readonly property bool shouldShowSpotlight: niriOverviewScope.searchActive && screen.name === niriOverviewScope.searchActiveScreen && !niriOverviewScope.isClosing
|
||||||
readonly property bool isSpotlightScreen: screen.name === niriOverviewScope.searchActiveScreen
|
readonly property bool isSpotlightScreen: screen.name === niriOverviewScope.searchActiveScreen
|
||||||
property bool hasActivePopout: !!PopoutManager.currentPopoutsByScreen[screen.name]
|
property bool hasActivePopout: !!PopoutManager.currentPopoutsByScreen[screen.name]
|
||||||
|
property bool hasActiveModal: !!ModalManager.currentModalsByScreen[screen.name]
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: PopoutManager
|
target: PopoutManager
|
||||||
@@ -100,6 +101,13 @@ Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ModalManager
|
||||||
|
function onModalChanged() {
|
||||||
|
overlayWindow.hasActiveModal = !!ModalManager.currentModalsByScreen[overlayWindow.screen.name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
screen: modelData
|
screen: modelData
|
||||||
visible: NiriService.inOverview || niriOverviewScope.isClosing
|
visible: NiriService.inOverview || niriOverviewScope.isClosing
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
@@ -114,7 +122,7 @@ Scope {
|
|||||||
return WlrKeyboardFocus.None;
|
return WlrKeyboardFocus.None;
|
||||||
if (niriOverviewScope.releaseKeyboard)
|
if (niriOverviewScope.releaseKeyboard)
|
||||||
return WlrKeyboardFocus.None;
|
return WlrKeyboardFocus.None;
|
||||||
if (hasActivePopout)
|
if (hasActivePopout || hasActiveModal)
|
||||||
return WlrKeyboardFocus.None;
|
return WlrKeyboardFocus.None;
|
||||||
return WlrKeyboardFocus.Exclusive;
|
return WlrKeyboardFocus.Exclusive;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user