kwin: emit window fullscreen info + refactor helper script

The helper script was also refactored to minimize the amount of callbacks added and the memory used. There's no need to keep callbacks attached for non-active windows, which happened before.

Also it should be more efficient and simpler to send info over with just a single DBus call (also if more fields were to be added).

Both the script and the helper app will send/print info only if it changed since the previous one. Otherwise we'd keep spamming fullscreen false update when navigating the desktop and so on.
This commit is contained in:
p0358
2026-02-19 22:29:57 +01:00
committed by dec05eba
parent 636eca0d0e
commit 52afad5824
4 changed files with 87 additions and 57 deletions

View File

@@ -1,52 +1,51 @@
const DAEMON_DBUS_NAME = "com.dec05eba.gpu_screen_recorder";
// utils
function sendNewActiveWindowTitle(title) {
function dbusSendUpdateActiveWindow(title, isFullscreen) {
callDBus(
DAEMON_DBUS_NAME, "/", DAEMON_DBUS_NAME,
"setActiveWindowTitle", title
"updateActiveWindow",
title, isFullscreen,
);
}
function sendNewActiveWindowFullscreen(isFullscreen) {
callDBus(
DAEMON_DBUS_NAME, "/", DAEMON_DBUS_NAME,
"setActiveWindowFullscreen", isFullscreen
);
let prevWindow = null;
let prevEmitActiveWindowUpdate = null;
let prevCaption = null;
let prevFullScreen = null;
function emitActiveWindowUpdate(window) {
if (workspace.activeWindow === window) {
let caption = window.caption || "";
let fullScreen = window.fullScreen || false;
if (caption !== prevCaption || fullScreen !== prevFullScreen) {
dbusSendUpdateActiveWindow(caption, fullScreen);
prevCaption = caption;
prevFullScreen = fullScreen;
}
}
}
// track handlers to avoid duplicates
const windowEventHandlers = new Map();
function subscribeToClient(client) {
if (!client || windowEventHandlers.has(client)) return;
const emitActiveTitle = () => {
if (workspace.activeWindow === client) {
sendNewActiveWindowTitle(client.caption || "");
function subscribeToWindow(window) {
if (!window) return;
if (prevWindow !== window) {
if (prevWindow !== null) {
prevWindow.captionChanged.disconnect(prevEmitActiveWindowUpdate);
prevWindow.fullScreenChanged.disconnect(prevEmitActiveWindowUpdate);
}
};
const emitActiveFullscreen = () => {
if (workspace.activeWindow === client) {
sendNewActiveWindowFullscreen(client.fullScreen);
}
};
windowEventHandlers.set(client, {
title: emitActiveTitle,
fs: emitActiveFullscreen,
});
client.captionChanged.connect(emitActiveTitle);
client.fullScreenChanged.connect(emitActiveFullscreen);
let emitActiveWindowUpdateBound = emitActiveWindowUpdate.bind(null, window);
window.captionChanged.connect(emitActiveWindowUpdateBound);
window.fullScreenChanged.connect(emitActiveWindowUpdateBound);
prevWindow = window;
prevEmitActiveWindowUpdate = emitActiveWindowUpdateBound;
}
}
function updateActiveWindow(client) {
if (!client) return;
sendNewActiveWindowTitle(client.caption || "");
sendNewActiveWindowFullscreen(client.fullScreen);
subscribeToClient(client);
function updateActiveWindow(window) {
if (!window) return;
if (window.resourceName === "gsr-ui" || window.resourceName === "gsr-notify") return; // ignore the overlay and notification
emitActiveWindowUpdate(window);
subscribeToWindow(window);
}
// handle window focus changes
@@ -55,4 +54,4 @@ workspace.windowActivated.connect(updateActiveWindow);
// handle initial state
if (workspace.activeWindow) {
updateActiveWindow(workspace.activeWindow);
}
}