mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
refactor(niri): use native C++ Niri IPC module instead of QML socket
This commit is contained in:
+113
-355
@@ -1,7 +1,6 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Niri
|
||||||
import Quickshell.Wayland
|
|
||||||
import qs.Commons
|
import qs.Commons
|
||||||
import qs.Services.Keyboard
|
import qs.Services.Keyboard
|
||||||
|
|
||||||
@@ -27,231 +26,117 @@ Item {
|
|||||||
property var workspaceCache: ({})
|
property var workspaceCache: ({})
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
niriEventStream.connected = true;
|
Niri.refreshOutputs();
|
||||||
niriCommandSocket.connected = true;
|
Niri.refreshWorkspaces();
|
||||||
|
Niri.refreshWindows();
|
||||||
|
|
||||||
startEventStream();
|
Qt.callLater(() => {
|
||||||
updateOutputs();
|
safeUpdateOutputs();
|
||||||
updateWorkspaces();
|
safeUpdateWorkspaces();
|
||||||
updateWindows();
|
safeUpdateWindows();
|
||||||
queryDisplayScales();
|
queryDisplayScales();
|
||||||
|
});
|
||||||
|
|
||||||
Logger.i("NiriService", "Service started");
|
Logger.i("NiriService", "Service started");
|
||||||
}
|
}
|
||||||
|
|
||||||
// command from https://yalter.github.io/niri/niri_ipc/enum.Request.html
|
// Connections to the C++ Niri IPC module
|
||||||
function sendSocketCommand(sock, command) {
|
Connections {
|
||||||
sock.write(JSON.stringify(command) + "\n");
|
target: Niri
|
||||||
sock.flush();
|
function onWorkspacesUpdated() {
|
||||||
|
safeUpdateWorkspaces();
|
||||||
|
workspaceChanged();
|
||||||
|
}
|
||||||
|
function onWindowsUpdated() {
|
||||||
|
safeUpdateWindows();
|
||||||
|
windowListChanged();
|
||||||
|
activeWindowChanged();
|
||||||
|
}
|
||||||
|
function onOutputsUpdated() {
|
||||||
|
safeUpdateOutputs();
|
||||||
|
queryDisplayScales();
|
||||||
|
}
|
||||||
|
function onOverviewActiveChanged() {
|
||||||
|
overviewActive = Niri.overviewActive;
|
||||||
|
}
|
||||||
|
function onKeyboardLayoutsChanged() {
|
||||||
|
keyboardLayouts = Niri.keyboardLayoutNames;
|
||||||
|
const layoutName = Niri.currentKeyboardLayoutName;
|
||||||
|
if (layoutName) {
|
||||||
|
KeyboardLayoutService.setCurrentLayout(layoutName);
|
||||||
|
}
|
||||||
|
Logger.d("NiriService", "Keyboard layouts changed:", keyboardLayouts.toString());
|
||||||
|
}
|
||||||
|
function onKeyboardLayoutSwitched() {
|
||||||
|
const layoutName = Niri.currentKeyboardLayoutName;
|
||||||
|
if (layoutName) {
|
||||||
|
KeyboardLayoutService.setCurrentLayout(layoutName);
|
||||||
|
}
|
||||||
|
Logger.d("NiriService", "Keyboard layout switched:", layoutName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function startEventStream() {
|
function safeUpdateOutputs() {
|
||||||
sendSocketCommand(niriEventStream, "EventStream");
|
const niriOutputs = Niri.outputs.values;
|
||||||
}
|
|
||||||
|
|
||||||
function updateOutputs() {
|
|
||||||
sendSocketCommand(niriCommandSocket, "Outputs");
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateWorkspaces() {
|
|
||||||
sendSocketCommand(niriCommandSocket, "Workspaces");
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateWindows() {
|
|
||||||
sendSocketCommand(niriCommandSocket, "Windows");
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: workspaceUpdateTimer
|
|
||||||
interval: 50
|
|
||||||
repeat: false
|
|
||||||
onTriggered: updateWorkspaces()
|
|
||||||
}
|
|
||||||
|
|
||||||
function queryDisplayScales() {
|
|
||||||
sendSocketCommand(niriCommandSocket, "Outputs");
|
|
||||||
}
|
|
||||||
|
|
||||||
function recollectOutputs(outputsData) {
|
|
||||||
const scales = {};
|
|
||||||
outputCache = {};
|
outputCache = {};
|
||||||
|
|
||||||
for (const outputName in outputsData) {
|
for (var i = 0; i < niriOutputs.length; i++) {
|
||||||
const output = outputsData[outputName];
|
const output = niriOutputs[i];
|
||||||
if (output && output.name) {
|
outputCache[output.name] = {
|
||||||
const isConnected = output.logical !== null && output.current_mode !== null;
|
|
||||||
const logical = output.logical || {};
|
|
||||||
const currentModeIdx = output.current_mode ?? 0;
|
|
||||||
const modes = output.modes || [];
|
|
||||||
const currentMode = modes[currentModeIdx] || {};
|
|
||||||
|
|
||||||
const outputData = {
|
|
||||||
"name": output.name,
|
"name": output.name,
|
||||||
"connected": isConnected,
|
"connected": output.connected,
|
||||||
"scale": logical.scale || 1.0,
|
"scale": output.scale,
|
||||||
"width": logical.width || 0,
|
"width": output.width,
|
||||||
"height": logical.height || 0,
|
"height": output.height,
|
||||||
"x": logical.x || 0,
|
"x": output.x,
|
||||||
"y": logical.y || 0,
|
"y": output.y,
|
||||||
"physical_width": (output.physical_size && output.physical_size[0]) || 0,
|
"physical_width": output.physicalWidth,
|
||||||
"physical_height": (output.physical_size && output.physical_size[1]) || 0,
|
"physical_height": output.physicalHeight,
|
||||||
"refresh_rate": currentMode.refresh_rate || 0,
|
"refresh_rate": output.refreshRate,
|
||||||
"vrr_supported": output.vrr_supported || false,
|
"vrr_supported": output.vrrSupported,
|
||||||
"vrr_enabled": output.vrr_enabled || false,
|
"vrr_enabled": output.vrrEnabled,
|
||||||
"transform": logical.transform || "Normal"
|
"transform": output.transform
|
||||||
};
|
};
|
||||||
|
|
||||||
outputCache[output.name] = outputData;
|
|
||||||
scales[output.name] = outputData;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CompositorService && CompositorService.onDisplayScalesUpdated) {
|
function safeUpdateWorkspaces() {
|
||||||
CompositorService.onDisplayScalesUpdated(scales);
|
const niriWorkspaces = Niri.workspaces.values;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function recollectWorkspaces(workspacesData) {
|
|
||||||
const workspacesList = [];
|
|
||||||
workspaceCache = {};
|
workspaceCache = {};
|
||||||
|
|
||||||
for (const ws of workspacesData) {
|
const workspacesList = [];
|
||||||
|
for (var i = 0; i < niriWorkspaces.length; i++) {
|
||||||
|
const ws = niriWorkspaces[i];
|
||||||
const wsData = {
|
const wsData = {
|
||||||
"id": ws.id,
|
"id": ws.id,
|
||||||
"idx": ws.idx,
|
"idx": ws.idx,
|
||||||
"name": ws.name || "",
|
"name": ws.name,
|
||||||
"output": ws.output || "",
|
"output": ws.output,
|
||||||
"isFocused": ws.is_focused === true,
|
"isFocused": ws.focused,
|
||||||
"isActive": ws.is_active === true,
|
"isActive": ws.active,
|
||||||
"isUrgent": ws.is_urgent === true,
|
"isUrgent": ws.urgent,
|
||||||
"isOccupied": ws.active_window_id ? true : false
|
"isOccupied": ws.occupied
|
||||||
};
|
};
|
||||||
|
|
||||||
workspacesList.push(wsData);
|
workspacesList.push(wsData);
|
||||||
workspaceCache[ws.id] = wsData;
|
workspaceCache[ws.id] = wsData;
|
||||||
}
|
}
|
||||||
|
|
||||||
workspacesList.sort((a, b) => {
|
// Workspaces come pre-sorted from C++ (by output then idx)
|
||||||
if (a.output !== b.output) {
|
|
||||||
return a.output.localeCompare(b.output);
|
|
||||||
}
|
|
||||||
return a.idx - b.idx;
|
|
||||||
});
|
|
||||||
|
|
||||||
workspaces.clear();
|
workspaces.clear();
|
||||||
for (var i = 0; i < workspacesList.length; i++) {
|
for (var j = 0; j < workspacesList.length; j++) {
|
||||||
workspaces.append(workspacesList[i]);
|
workspaces.append(workspacesList[j]);
|
||||||
}
|
|
||||||
|
|
||||||
workspaceChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket {
|
|
||||||
id: niriCommandSocket
|
|
||||||
path: Quickshell.env("NIRI_SOCKET")
|
|
||||||
connected: false
|
|
||||||
|
|
||||||
parser: SplitParser {
|
|
||||||
onRead: function (line) {
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(line);
|
|
||||||
|
|
||||||
if (data && data.Ok) {
|
|
||||||
const res = data.Ok;
|
|
||||||
if (res.Windows) {
|
|
||||||
recollectWindows(res.Windows);
|
|
||||||
} else if (res.Outputs) {
|
|
||||||
recollectOutputs(res.Outputs);
|
|
||||||
} else if (res.Workspaces) {
|
|
||||||
recollectWorkspaces(res.Workspaces);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Logger.e("NiriService", "Niri returned an error:", data.Err, line);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Failed to parse data from socket:", e, line);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket {
|
|
||||||
id: niriEventStream
|
|
||||||
path: Quickshell.env("NIRI_SOCKET")
|
|
||||||
connected: false
|
|
||||||
|
|
||||||
parser: SplitParser {
|
|
||||||
onRead: data => {
|
|
||||||
try {
|
|
||||||
const event = JSON.parse(data.trim());
|
|
||||||
|
|
||||||
if (event.WorkspacesChanged) {
|
|
||||||
recollectWorkspaces(event.WorkspacesChanged.workspaces);
|
|
||||||
} else if (event.WindowOpenedOrChanged) {
|
|
||||||
handleWindowOpenedOrChanged(event.WindowOpenedOrChanged);
|
|
||||||
} else if (event.WindowClosed) {
|
|
||||||
handleWindowClosed(event.WindowClosed);
|
|
||||||
} else if (event.WindowsChanged) {
|
|
||||||
handleWindowsChanged(event.WindowsChanged);
|
|
||||||
} else if (event.WorkspaceActivated) {
|
|
||||||
workspaceUpdateTimer.restart();
|
|
||||||
} else if (event.WindowFocusChanged) {
|
|
||||||
handleWindowFocusChanged(event.WindowFocusChanged);
|
|
||||||
} else if (event.WindowLayoutsChanged) {
|
|
||||||
handleWindowLayoutsChanged(event.WindowLayoutsChanged);
|
|
||||||
} else if (event.OverviewOpenedOrClosed) {
|
|
||||||
handleOverviewOpenedOrClosed(event.OverviewOpenedOrClosed);
|
|
||||||
} else if (event.OutputsChanged) {
|
|
||||||
queryDisplayScales();
|
|
||||||
} else if (event.ConfigLoaded) {
|
|
||||||
queryDisplayScales();
|
|
||||||
} else if (event.KeyboardLayoutsChanged) {
|
|
||||||
handleKeyboardLayoutsChanged(event.KeyboardLayoutsChanged);
|
|
||||||
} else if (event.KeyboardLayoutSwitched) {
|
|
||||||
handleKeyboardLayoutSwitched(event.KeyboardLayoutSwitched);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Error parsing event stream:", e, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWindowPosition(layout) {
|
|
||||||
if (layout.pos_in_scrolling_layout) {
|
|
||||||
return {
|
|
||||||
"x": layout.pos_in_scrolling_layout[0],
|
|
||||||
"y": layout.pos_in_scrolling_layout[1]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
"x": floatingWindowPosition,
|
|
||||||
"y": floatingWindowPosition
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWindowOutput(win) {
|
function getWindowOutput(win) {
|
||||||
for (var i = 0; i < workspaces.count; i++) {
|
for (var i = 0; i < workspaces.count; i++) {
|
||||||
if (workspaces.get(i).id === win.workspace_id) {
|
if (workspaces.get(i).id === win.workspaceId) {
|
||||||
return workspaces.get(i).output;
|
return workspaces.get(i).output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWindowData(win) {
|
|
||||||
return {
|
|
||||||
"id": win.id,
|
|
||||||
"title": win.title || "",
|
|
||||||
"appId": win.app_id || "",
|
|
||||||
"workspaceId": win.workspace_id || -1,
|
|
||||||
"isFocused": win.is_focused === true,
|
|
||||||
"output": getWindowOutput(win) || "",
|
|
||||||
"position": getWindowPosition(win.layout)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function toSortedWindowList(windowList) {
|
function toSortedWindowList(windowList) {
|
||||||
return windowList.map(win => {
|
return windowList.map(win => {
|
||||||
const workspace = workspaceCache[win.workspaceId];
|
const workspace = workspaceCache[win.workspaceId];
|
||||||
@@ -287,15 +172,31 @@ Item {
|
|||||||
}).map(info => info.window);
|
}).map(info => info.window);
|
||||||
}
|
}
|
||||||
|
|
||||||
function recollectWindows(windowsData) {
|
function safeUpdateWindows() {
|
||||||
|
const niriWindows = Niri.windows.values;
|
||||||
const windowsList = [];
|
const windowsList = [];
|
||||||
for (const win of windowsData) {
|
|
||||||
windowsList.push(getWindowData(win));
|
|
||||||
}
|
|
||||||
windows = toSortedWindowList(windowsList);
|
|
||||||
windowListChanged();
|
|
||||||
|
|
||||||
// Find focused window index in the SORTED windows array
|
for (var i = 0; i < niriWindows.length; i++) {
|
||||||
|
const win = niriWindows[i];
|
||||||
|
windowsList.push({
|
||||||
|
"id": win.id,
|
||||||
|
"title": win.title || "",
|
||||||
|
"appId": win.appId || "",
|
||||||
|
"workspaceId": win.workspaceId || -1,
|
||||||
|
"isFocused": win.focused,
|
||||||
|
"output": win.output || getWindowOutput(win) || "",
|
||||||
|
"position": {
|
||||||
|
"x": win.isFloating ? floatingWindowPosition : win.positionX,
|
||||||
|
"y": win.isFloating ? floatingWindowPosition : win.positionY
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
windows = toSortedWindowList(windowsList);
|
||||||
|
safeUpdateFocusedWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeUpdateFocusedWindow() {
|
||||||
focusedWindowIndex = -1;
|
focusedWindowIndex = -1;
|
||||||
for (var i = 0; i < windows.length; i++) {
|
for (var i = 0; i < windows.length; i++) {
|
||||||
if (windows[i].isFocused) {
|
if (windows[i].isFocused) {
|
||||||
@@ -303,154 +204,17 @@ Item {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
activeWindowChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleWindowOpenedOrChanged(eventData) {
|
function queryDisplayScales() {
|
||||||
try {
|
if (CompositorService && CompositorService.onDisplayScalesUpdated) {
|
||||||
const windowData = eventData.window;
|
CompositorService.onDisplayScalesUpdated(outputCache);
|
||||||
const existingIndex = windows.findIndex(w => w.id === windowData.id);
|
|
||||||
const newWindow = getWindowData(windowData);
|
|
||||||
|
|
||||||
// Find the previously focused window ID before any modifications
|
|
||||||
const previouslyFocusedId = focusedWindowIndex >= 0 && focusedWindowIndex < windows.length ? windows[focusedWindowIndex].id : null;
|
|
||||||
|
|
||||||
if (existingIndex >= 0) {
|
|
||||||
windows[existingIndex] = newWindow;
|
|
||||||
} else {
|
|
||||||
windows.push(newWindow);
|
|
||||||
}
|
|
||||||
windows = toSortedWindowList(windows);
|
|
||||||
|
|
||||||
if (newWindow.isFocused) {
|
|
||||||
focusedWindowIndex = windows.findIndex(w => w.id === windowData.id);
|
|
||||||
|
|
||||||
// Clear focus on the previously focused window by ID (not index, since list was re-sorted)
|
|
||||||
if (previouslyFocusedId !== null && previouslyFocusedId !== windowData.id) {
|
|
||||||
const oldFocusedWindow = windows.find(w => w.id === previouslyFocusedId);
|
|
||||||
if (oldFocusedWindow) {
|
|
||||||
oldFocusedWindow.isFocused = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
activeWindowChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
windowListChanged();
|
|
||||||
workspaceUpdateTimer.restart();
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Error handling WindowOpenedOrChanged:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleWindowClosed(eventData) {
|
|
||||||
try {
|
|
||||||
const windowId = eventData.id;
|
|
||||||
const windowIndex = windows.findIndex(w => w.id === windowId);
|
|
||||||
|
|
||||||
if (windowIndex >= 0) {
|
|
||||||
if (windowIndex === focusedWindowIndex) {
|
|
||||||
focusedWindowIndex = -1;
|
|
||||||
activeWindowChanged();
|
|
||||||
} else if (focusedWindowIndex > windowIndex) {
|
|
||||||
focusedWindowIndex--;
|
|
||||||
}
|
|
||||||
|
|
||||||
windows.splice(windowIndex, 1);
|
|
||||||
windowListChanged();
|
|
||||||
workspaceUpdateTimer.restart();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Error handling WindowClosed:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleWindowsChanged(eventData) {
|
|
||||||
try {
|
|
||||||
const windowsData = eventData.windows;
|
|
||||||
recollectWindows(windowsData);
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Error handling WindowsChanged:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleWindowFocusChanged(eventData) {
|
|
||||||
try {
|
|
||||||
const focusedId = eventData.id;
|
|
||||||
|
|
||||||
if (windows[focusedWindowIndex]) {
|
|
||||||
windows[focusedWindowIndex].isFocused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (focusedId) {
|
|
||||||
const newIndex = windows.findIndex(w => w.id === focusedId);
|
|
||||||
|
|
||||||
if (newIndex >= 0 && newIndex < windows.length) {
|
|
||||||
windows[newIndex].isFocused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
focusedWindowIndex = newIndex >= 0 ? newIndex : -1;
|
|
||||||
} else {
|
|
||||||
focusedWindowIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
activeWindowChanged();
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Error handling WindowFocusChanged:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleWindowLayoutsChanged(eventData) {
|
|
||||||
try {
|
|
||||||
for (const change of eventData.changes) {
|
|
||||||
const windowId = change[0];
|
|
||||||
const layout = change[1];
|
|
||||||
const window = windows.find(w => w.id === windowId);
|
|
||||||
if (window) {
|
|
||||||
window.position = getWindowPosition(layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
windows = toSortedWindowList(windows);
|
|
||||||
|
|
||||||
windowListChanged();
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Error handling WindowLayoutChanged:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleOverviewOpenedOrClosed(eventData) {
|
|
||||||
try {
|
|
||||||
overviewActive = eventData.is_open;
|
|
||||||
Logger.d("NiriService", "Overview opened or closed:", eventData.is_open);
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Error handling OverviewOpenedOrClosed:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleKeyboardLayoutsChanged(eventData) {
|
|
||||||
try {
|
|
||||||
keyboardLayouts = eventData.keyboard_layouts.names;
|
|
||||||
const layoutName = keyboardLayouts[eventData.keyboard_layouts.current_idx];
|
|
||||||
KeyboardLayoutService.setCurrentLayout(layoutName);
|
|
||||||
Logger.d("NiriService", "Keyboard layouts changed:", keyboardLayouts.toString());
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Error handling keyboardLayoutsChanged:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleKeyboardLayoutSwitched(eventData) {
|
|
||||||
try {
|
|
||||||
const layoutName = keyboardLayouts[eventData.idx];
|
|
||||||
KeyboardLayoutService.setCurrentLayout(layoutName);
|
|
||||||
Logger.d("NiriService", "Keyboard layout switched:", layoutName);
|
|
||||||
} catch (e) {
|
|
||||||
Logger.e("NiriService", "Error handling KeyboardLayoutSwitched:", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchToWorkspace(workspace) {
|
function switchToWorkspace(workspace) {
|
||||||
try {
|
try {
|
||||||
Quickshell.execDetached(["niri", "msg", "action", "focus-workspace", workspace.idx.toString()]);
|
Niri.dispatch(["focus-workspace", workspace.idx.toString()]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.e("NiriService", "Failed to switch workspace:", e);
|
Logger.e("NiriService", "Failed to switch workspace:", e);
|
||||||
}
|
}
|
||||||
@@ -459,7 +223,7 @@ Item {
|
|||||||
function scrollWorkspaceContent(direction) {
|
function scrollWorkspaceContent(direction) {
|
||||||
try {
|
try {
|
||||||
var action = direction < 0 ? "focus-column-left" : "focus-column-right";
|
var action = direction < 0 ? "focus-column-left" : "focus-column-right";
|
||||||
Quickshell.execDetached(["niri", "msg", "action", action]);
|
Niri.dispatch([action]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.e("NiriService", "Failed to scroll workspace content:", e);
|
Logger.e("NiriService", "Failed to scroll workspace content:", e);
|
||||||
}
|
}
|
||||||
@@ -467,7 +231,7 @@ Item {
|
|||||||
|
|
||||||
function focusWindow(window) {
|
function focusWindow(window) {
|
||||||
try {
|
try {
|
||||||
Quickshell.execDetached(["niri", "msg", "action", "focus-window", "--id", window.id.toString()]);
|
Niri.dispatch(["focus-window", "--id", window.id.toString()]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.e("NiriService", "Failed to switch window:", e);
|
Logger.e("NiriService", "Failed to switch window:", e);
|
||||||
}
|
}
|
||||||
@@ -475,7 +239,7 @@ Item {
|
|||||||
|
|
||||||
function closeWindow(window) {
|
function closeWindow(window) {
|
||||||
try {
|
try {
|
||||||
Quickshell.execDetached(["niri", "msg", "action", "close-window", "--id", window.id.toString()]);
|
Niri.dispatch(["close-window", "--id", window.id.toString()]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.e("NiriService", "Failed to close window:", e);
|
Logger.e("NiriService", "Failed to close window:", e);
|
||||||
}
|
}
|
||||||
@@ -483,7 +247,7 @@ Item {
|
|||||||
|
|
||||||
function turnOffMonitors() {
|
function turnOffMonitors() {
|
||||||
try {
|
try {
|
||||||
Quickshell.execDetached(["niri", "msg", "action", "power-off-monitors"]);
|
Niri.dispatch(["power-off-monitors"]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.e("NiriService", "Failed to turn off monitors:", e);
|
Logger.e("NiriService", "Failed to turn off monitors:", e);
|
||||||
}
|
}
|
||||||
@@ -491,7 +255,7 @@ Item {
|
|||||||
|
|
||||||
function turnOnMonitors() {
|
function turnOnMonitors() {
|
||||||
try {
|
try {
|
||||||
Quickshell.execDetached(["niri", "msg", "action", "power-on-monitors"]);
|
Niri.dispatch(["power-on-monitors"]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.e("NiriService", "Failed to turn on monitors:", e);
|
Logger.e("NiriService", "Failed to turn on monitors:", e);
|
||||||
}
|
}
|
||||||
@@ -499,7 +263,7 @@ Item {
|
|||||||
|
|
||||||
function logout() {
|
function logout() {
|
||||||
try {
|
try {
|
||||||
Quickshell.execDetached(["niri", "msg", "action", "quit", "--skip-confirmation"]);
|
Niri.dispatch(["quit", "--skip-confirmation"]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.e("NiriService", "Failed to logout:", e);
|
Logger.e("NiriService", "Failed to logout:", e);
|
||||||
}
|
}
|
||||||
@@ -507,7 +271,7 @@ Item {
|
|||||||
|
|
||||||
function cycleKeyboardLayout() {
|
function cycleKeyboardLayout() {
|
||||||
try {
|
try {
|
||||||
Quickshell.execDetached(["niri", "msg", "action", "switch-layout", "next"]);
|
Niri.dispatch(["switch-layout", "next"]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.e("NiriService", "Failed to cycle keyboard layout:", e);
|
Logger.e("NiriService", "Failed to cycle keyboard layout:", e);
|
||||||
}
|
}
|
||||||
@@ -516,19 +280,13 @@ Item {
|
|||||||
function getFocusedScreen() {
|
function getFocusedScreen() {
|
||||||
// On niri the code below only works when you have an actual app selected on that screen.
|
// On niri the code below only works when you have an actual app selected on that screen.
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// const activeToplevel = ToplevelManager.activeToplevel;
|
|
||||||
// if (activeToplevel && activeToplevel.screens && activeToplevel.screens.length > 0) {
|
|
||||||
// return activeToplevel.screens[0];
|
|
||||||
// }
|
|
||||||
// return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function spawn(command) {
|
function spawn(command) {
|
||||||
try {
|
try {
|
||||||
const niriCommand = ["niri", "msg", "action", "spawn", "--"].concat(command);
|
const niriArgs = ["spawn", "--"].concat(command);
|
||||||
Logger.d("NiriService", "Calling niri spawn: " + niriCommand.join(" "));
|
Logger.d("NiriService", "Calling niri spawn: niri msg action " + niriArgs.join(" "));
|
||||||
Quickshell.execDetached(niriCommand);
|
Niri.dispatch(niriArgs);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.e("NiriService", "Failed to spawn command:", e);
|
Logger.e("NiriService", "Failed to spawn command:", e);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user