Profiles: fixes from trying them on the live desktop

- KWin 6.2's scripts have no maximize mode: a window counts as maximized
  when it fills its output's maximize area.
- A late event for a window that just closed brought it back into
  ft-floatd's table, so a profile "found" it open, floated a window that no
  longer existed, and held a slot. The script doesn't report deleted
  windows, and ft-floatd ignores events for ids it has seen close.
- Docking a window that came from a screen that's hidden now puts it on the
  first screen that shows instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DeeJanuzandClaude Opus 5.5 committed 2026-09-30 22:37:50 -06:00
1 parent 858dbe1562
commit a699540d95
3 files changed
+27 -3

No files matched your search

+16 -1
View File
@@ -280,6 +280,7 @@ class Daemon:
self.slots = [Slot(k, args.screens) for k in range(args.slots)]
self.floats = {} # window id -> Float
self.windows = {} # window id -> last info from the script
self.gone = set() # ids of windows that closed (KWin's ids aren't reused)
self.pending = [] # commands for the script
self.waiter = None # (reply callback, timeout source) while the script waits
self.screens = Screens(args.control)
@@ -354,7 +355,10 @@ class Daemon:
# The script reports every window after "config"; spares nothing floats on are off.
GLib.timeout_add(1500, self.disable_unused)
return
if wid in self.gone:
return # an event that came after the window closed (it would bring it back)
if kind == "removed":
self.gone.add(wid)
self.windows.pop(wid, None)
if wid in self.floats:
log(f"{wid[:9]} closed")
@@ -639,7 +643,18 @@ class Daemon:
saved = f.saved or {"output": "WL-0", "frame": dict(f.frame or {"x": 100, "y": 100, "w": 800, "h": 600}),
"onAllDesktops": False}
fr = frame or saved["frame"]
output = output or saved["output"]
if not output:
output = saved["output"]
m = re.match(r"WL-(\d+)$", output)
hidden = self.concealed()
if m and int(m.group(1)) + 1 in hidden:
# It came from a screen that's hidden now: onto the first one that shows.
shown = [i for i in range(self.screens_n) if i + 1 not in hidden]
if shown:
x0, y0, ow, oh = output_rects().get(f"WL-{shown[0]}", (0, 0, 0, 0))
output = f"WL-{shown[0]}"
w, h = min(fr["w"], ow or fr["w"]), min(fr["h"], oh or fr["h"])
fr = {"x": x0 + max(0, (ow - w) / 2), "y": y0 + max(0, (oh - h) / 2), "w": w, "h": h}
log(f"{f.id[:9]} back to {output}")
self.command(cmd="place", id=f.id, output=output, x=fr["x"], y=fr["y"], w=fr["w"], h=fr["h"],
onAllDesktops=bool(saved.get("onAllDesktops")), maximized=maximized)