mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
feat(SwayService): add workspaceId to extractWindowData via ipc
This commit is contained in:
@@ -23,6 +23,9 @@ Item {
|
||||
// I3-specific properties
|
||||
property bool initialized: false
|
||||
|
||||
// Cache for window-to-workspace mapping
|
||||
property var windowWorkspaceMap: ({})
|
||||
|
||||
// Debounce timer for updates
|
||||
Timer {
|
||||
id: updateTimer
|
||||
@@ -40,7 +43,7 @@ Item {
|
||||
I3.dispatch('(["input"])');
|
||||
Qt.callLater(() => {
|
||||
safeUpdateWorkspaces();
|
||||
safeUpdateWindows();
|
||||
queryWindowWorkspaces();
|
||||
queryDisplayScales();
|
||||
queryKeyboardLayout();
|
||||
});
|
||||
@@ -51,6 +54,93 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// Query window-to-workspace mapping via IPC
|
||||
function queryWindowWorkspaces() {
|
||||
swayTreeProcess.running = true;
|
||||
}
|
||||
|
||||
// Sway tree process for getting window workspace information
|
||||
Process {
|
||||
id: swayTreeProcess
|
||||
running: false
|
||||
command: ["swaymsg", "-t", "get_tree", "-r"]
|
||||
|
||||
property string accumulatedOutput: ""
|
||||
|
||||
stdout: SplitParser {
|
||||
onRead: function (line) {
|
||||
swayTreeProcess.accumulatedOutput += line;
|
||||
}
|
||||
}
|
||||
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode !== 0 || !accumulatedOutput) {
|
||||
Logger.e("SwayService", "Failed to query tree, exit code:", exitCode);
|
||||
accumulatedOutput = "";
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const treeData = JSON.parse(accumulatedOutput);
|
||||
const newMap = {};
|
||||
|
||||
// Recursively find all windows and their workspaces
|
||||
function traverseTree(node, workspaceNum) {
|
||||
if (!node) return;
|
||||
|
||||
// If this is a workspace node, update the workspace number
|
||||
if (node.type === "workspace" && node.num !== undefined) {
|
||||
workspaceNum = node.num;
|
||||
}
|
||||
|
||||
// If this is a container with app_id or class (i.e., a window)
|
||||
if (node.type === "con" && (node.app_id || node.window_properties)) {
|
||||
const appId = node.app_id ||
|
||||
(node.window_properties ? node.window_properties.class : null);
|
||||
const title = node.name || "";
|
||||
const id = node.id;
|
||||
|
||||
if (appId && workspaceNum !== undefined && workspaceNum >= 0) {
|
||||
// Create a key based on app_id and title for matching
|
||||
const key = `${appId}:${title}`;
|
||||
newMap[key] = workspaceNum;
|
||||
|
||||
// Also store by ID if available
|
||||
if (id) {
|
||||
newMap[`id:${id}`] = workspaceNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse children
|
||||
if (node.nodes && node.nodes.length > 0) {
|
||||
for (const child of node.nodes) {
|
||||
traverseTree(child, workspaceNum);
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse floating nodes
|
||||
if (node.floating_nodes && node.floating_nodes.length > 0) {
|
||||
for (const child of node.floating_nodes) {
|
||||
traverseTree(child, workspaceNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
traverseTree(treeData, -1);
|
||||
windowWorkspaceMap = newMap;
|
||||
|
||||
// Update windows with new workspace information
|
||||
Qt.callLater(safeUpdateWindows);
|
||||
|
||||
} catch (e) {
|
||||
Logger.e("SwayService", "Failed to parse tree:", e);
|
||||
} finally {
|
||||
accumulatedOutput = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Query display scales
|
||||
function queryDisplayScales() {
|
||||
swayOutputsProcess.running = true;
|
||||
@@ -167,9 +257,8 @@ Item {
|
||||
|
||||
// Safe update wrapper
|
||||
function safeUpdate() {
|
||||
safeUpdateWindows();
|
||||
queryWindowWorkspaces();
|
||||
safeUpdateWorkspaces();
|
||||
windowListChanged();
|
||||
}
|
||||
|
||||
// Safe workspace update
|
||||
@@ -214,6 +303,7 @@ Item {
|
||||
if (!ToplevelManager.toplevels || !ToplevelManager.toplevels.values) {
|
||||
windows = [];
|
||||
focusedWindowIndex = -1;
|
||||
windowListChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -240,6 +330,8 @@ Item {
|
||||
focusedWindowIndex = newFocusedIndex;
|
||||
activeWindowChanged();
|
||||
}
|
||||
|
||||
windowListChanged();
|
||||
} catch (e) {
|
||||
Logger.e("SwayService", "Error updating windows:", e);
|
||||
}
|
||||
@@ -256,10 +348,28 @@ Item {
|
||||
const title = safeGetProperty(toplevel, "title", "");
|
||||
const focused = toplevel.activated === true;
|
||||
|
||||
// Try to find workspace ID from our cached map
|
||||
let workspaceId = -1;
|
||||
|
||||
// Try matching by app_id:title
|
||||
const key = `${appId}:${title}`;
|
||||
if (windowWorkspaceMap[key] !== undefined) {
|
||||
const workspaceNum = windowWorkspaceMap[key];
|
||||
|
||||
for (var i = 0; i < workspaces.count; i++) {
|
||||
const ws = workspaces.get(i);
|
||||
if (ws && ws.idx === workspaceNum) {
|
||||
workspaceId = ws.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
"title": title,
|
||||
"appId": appId,
|
||||
"isFocused": focused,
|
||||
"workspaceId": workspaceId,
|
||||
"handle": toplevel
|
||||
};
|
||||
} catch (e) {
|
||||
@@ -342,6 +452,11 @@ Item {
|
||||
if (event.type == "get_inputs") {
|
||||
handleInputEvent(event.data);
|
||||
}
|
||||
|
||||
// Query window workspaces on relevant events
|
||||
if (event.type === "window" || event.type === "workspace") {
|
||||
Qt.callLater(queryWindowWorkspaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user