qs: better niri service

This commit is contained in:
2026-03-16 02:57:39 +01:00
parent 16c279f14f
commit 8ea3875d5a
4 changed files with 77 additions and 46 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
screenshot-path "~/Pictures/Screenshots/niri_screenshot_%Y-%m-%d_%H-%M-%S.png" screenshot-path "~/Pictures/Screenshots/niri_screenshot_%Y-%m-%d_%H-%M-%S.png"
debug { debug {
render-drm-device "/dev/dri/renderD129" render-drm-device "/dev/dri/renderD128"
} }
// gestures { // gestures {
+1 -5
View File
@@ -1,5 +1 @@
environment {
__NV_PRIME_RENDER_OFFLOAD "1"
__VK_LAYER_NV_optimus "NVIDIA_only"
__GLX_VENDOR_LIBRARY_NAME "nvidia"
}
@@ -11,7 +11,9 @@ Singleton {
property int floatingWindowPosition: Number.MAX_SAFE_INTEGER property int floatingWindowPosition: Number.MAX_SAFE_INTEGER
property ListModel workspaces property ListModel workspaces
property var windows: [] property var windows: []
property bool hasFocusedWindow: focusedWindowIndex >= 0 && focusedWindowIndex < windows.length property var windowIndexCache: ({
})
property bool hasFocusedWindow: focusedWindowIndex >= 0
property int focusedWindowIndex: -1 property int focusedWindowIndex: -1
property string focusedWindowAppId: hasFocusedWindow ? windows[focusedWindowIndex].appId : "" property string focusedWindowAppId: hasFocusedWindow ? windows[focusedWindowIndex].appId : ""
property string focusedWindowTitle: hasFocusedWindow ? windows[focusedWindowIndex].title : "" property string focusedWindowTitle: hasFocusedWindow ? windows[focusedWindowIndex].title : ""
@@ -215,30 +217,56 @@ Singleton {
}); });
} }
function _rebuildWindowIndexCache() {
const cache = {
};
for (var i = 0; i < windows.length; i++) {
cache[windows[i].id] = i;
}
windowIndexCache = cache;
}
function _syncFocusedWindowIndex(preferredWindowId) {
var nextIndex = -1;
if (preferredWindowId !== undefined && preferredWindowId !== null) {
const cachedIndex = windowIndexCache[preferredWindowId];
if (cachedIndex !== undefined)
nextIndex = cachedIndex;
}
if (nextIndex < 0 && focusedWindowIndex >= 0 && focusedWindowIndex < windows.length && windows[focusedWindowIndex].isFocused)
nextIndex = focusedWindowIndex;
if (nextIndex < 0)
nextIndex = windows.findIndex((w) => {
return w.isFocused;
});
const hasChanged = nextIndex !== focusedWindowIndex;
focusedWindowIndex = nextIndex;
return hasChanged;
}
function recollectWindows(windowsData) { function recollectWindows(windowsData) {
const windowsList = []; const windowsList = [];
for (const win of windowsData) { for (const win of windowsData) {
windowsList.push(getWindowData(win)); windowsList.push(getWindowData(win));
} }
windows = toSortedWindowList(windowsList); windows = toSortedWindowList(windowsList);
_rebuildWindowIndexCache();
const focusedChanged = _syncFocusedWindowIndex();
windowListChanged(); windowListChanged();
// Find focused window index in the SORTED windows array if (focusedChanged)
focusedWindowIndex = -1;
for (var i = 0; i < windows.length; i++) {
if (windows[i].isFocused) {
focusedWindowIndex = i;
break;
}
}
activeWindowChanged(); activeWindowChanged();
} }
function _handleWindowOpenedOrChanged(eventData) { function _handleWindowOpenedOrChanged(eventData) {
try { try {
const windowData = eventData.window; const windowData = eventData.window;
const existingIndex = windows.findIndex((w) => { const cachedIndex = windowIndexCache[windowData.id];
return w.id === windowData.id; const existingIndex = cachedIndex !== undefined ? cachedIndex : -1;
});
const newWindow = getWindowData(windowData); const newWindow = getWindowData(windowData);
// Find the previously focused window ID before any modifications // Find the previously focused window ID before any modifications
const previouslyFocusedId = focusedWindowIndex >= 0 && focusedWindowIndex < windows.length ? windows[focusedWindowIndex].id : null; const previouslyFocusedId = focusedWindowIndex >= 0 && focusedWindowIndex < windows.length ? windows[focusedWindowIndex].id : null;
@@ -247,20 +275,20 @@ Singleton {
else else
windows.push(newWindow); windows.push(newWindow);
windows = toSortedWindowList(windows); windows = toSortedWindowList(windows);
_rebuildWindowIndexCache();
const focusedChanged = _syncFocusedWindowIndex(newWindow.isFocused ? windowData.id : null);
if (newWindow.isFocused) { if (newWindow.isFocused) {
focusedWindowIndex = windows.findIndex((w) => {
return w.id === windowData.id;
});
// Clear focus on the previously focused window by ID (not index, since list was re-sorted) // Clear focus on the previously focused window by ID (not index, since list was re-sorted)
if (previouslyFocusedId !== null && previouslyFocusedId !== windowData.id) { if (previouslyFocusedId !== null && previouslyFocusedId !== windowData.id) {
const oldFocusedWindow = windows.find((w) => { const oldFocusedIndex = windowIndexCache[previouslyFocusedId];
return w.id === previouslyFocusedId; const oldFocusedWindow = oldFocusedIndex !== undefined ? windows[oldFocusedIndex] : null;
});
if (oldFocusedWindow) if (oldFocusedWindow)
oldFocusedWindow.isFocused = false; oldFocusedWindow.isFocused = false;
} }
activeWindowChanged(); activeWindowChanged();
} else if (focusedChanged) {
activeWindowChanged();
} }
windowListChanged(); windowListChanged();
workspaceUpdateTimer.restart(); workspaceUpdateTimer.restart();
@@ -272,17 +300,15 @@ Singleton {
function _handleWindowClosed(eventData) { function _handleWindowClosed(eventData) {
try { try {
const windowId = eventData.id; const windowId = eventData.id;
const windowIndex = windows.findIndex((w) => { const cachedIndex = windowIndexCache[windowId];
return w.id === windowId; const windowIndex = cachedIndex !== undefined ? cachedIndex : -1;
});
if (windowIndex >= 0) { if (windowIndex >= 0) {
if (windowIndex === focusedWindowIndex) { const wasFocused = windows[windowIndex].isFocused;
focusedWindowIndex = -1;
activeWindowChanged();
} else if (focusedWindowIndex > windowIndex) {
focusedWindowIndex--;
}
windows.splice(windowIndex, 1); windows.splice(windowIndex, 1);
_rebuildWindowIndexCache();
if (_syncFocusedWindowIndex() || wasFocused)
activeWindowChanged();
windowListChanged(); windowListChanged();
workspaceUpdateTimer.restart(); workspaceUpdateTimer.restart();
} }
@@ -303,21 +329,20 @@ Singleton {
function _handleWindowFocusChanged(eventData) { function _handleWindowFocusChanged(eventData) {
try { try {
const focusedId = eventData.id; const focusedId = eventData.id;
if (windows[focusedWindowIndex]) const previousFocusedId = focusedWindowIndex >= 0 && focusedWindowIndex < windows.length ? windows[focusedWindowIndex].id : null;
if (focusedWindowIndex >= 0 && focusedWindowIndex < windows.length)
windows[focusedWindowIndex].isFocused = false; windows[focusedWindowIndex].isFocused = false;
if (focusedId) { if (focusedId) {
const newIndex = windows.findIndex((w) => { const cachedIndex = windowIndexCache[focusedId];
return w.id === focusedId; const newIndex = cachedIndex !== undefined ? cachedIndex : -1;
});
if (newIndex >= 0 && newIndex < windows.length) if (newIndex >= 0 && newIndex < windows.length)
windows[newIndex].isFocused = true; windows[newIndex].isFocused = true;
focusedWindowIndex = newIndex >= 0 ? newIndex : -1;
} else {
focusedWindowIndex = -1;
} }
if (_syncFocusedWindowIndex(focusedId) || previousFocusedId !== focusedId)
activeWindowChanged(); activeWindowChanged();
} catch (e) { } catch (e) {
Logger.e("NiriService", "Error handling WindowFocusChanged:", e); Logger.e("NiriService", "Error handling WindowFocusChanged:", e);
} }
@@ -325,17 +350,27 @@ Singleton {
function _handleWindowLayoutsChanged(eventData) { function _handleWindowLayoutsChanged(eventData) {
try { try {
const previousFocusedId = focusedWindowIndex >= 0 && focusedWindowIndex < windows.length ? windows[focusedWindowIndex].id : null;
var hasMatchedWindow = false;
for (const change of eventData.changes) { for (const change of eventData.changes) {
const windowId = change[0]; const windowId = change[0];
const layout = change[1]; const layout = change[1];
const window = windows.find((w) => { const windowIndex = windowIndexCache[windowId];
return w.id === windowId; const window = windowIndex !== undefined ? windows[windowIndex] : null;
});
if (window) if (window)
window.position = getWindowPosition(layout); window.position = getWindowPosition(layout);
hasMatchedWindow = hasMatchedWindow || window !== null;
} }
if (!hasMatchedWindow)
return ;
windows = toSortedWindowList(windows); windows = toSortedWindowList(windows);
_rebuildWindowIndexCache();
if (_syncFocusedWindowIndex(previousFocusedId))
activeWindowChanged();
windowListChanged(); windowListChanged();
} catch (e) { } catch (e) {
Logger.e("NiriService", "Error handling WindowLayoutChanged:", e); Logger.e("NiriService", "Error handling WindowLayoutChanged:", e);
+1 -1
View File
@@ -9,7 +9,7 @@
# Constants # Constants
niri_config_file="$HOME/.config/niri/config/misc.kdl" niri_config_file="$HOME/.config/niri/config/misc.kdl"
prefer_order=(nvidia intel) prefer_order=(intel nvidia)
# Get vendor and path of each GPU # Get vendor and path of each GPU
default_card_path="$(find /dev/dri/card* 2>/dev/null | head -n 1)" default_card_path="$(find /dev/dri/card* 2>/dev/null | head -n 1)"