mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 03:00:06 +02:00
Merge profiles fixes into experimental
This commit is contained in:
commit
81b64302aa
3 files changed
+27
-3
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# Profiles (plan)
|
# Profiles (plan)
|
||||||
|
|
||||||
Status: design settled with the user on 2026-09-30, and built the same day on the branch `profiles`, which builds on `screen-hide` (screens hidden one at a time). Tested offline: saving, renaming, and deleting profiles with their launcher entries, against a stand-in ft-floatd. Still to try on the desktop: capturing and opening real apps, and starting the desktop in a profile.
|
Status: design settled with the user on 2026-09-30, and built the same day on the branch `profiles`, which builds on `screen-hide` (screens hidden one at a time). Tried on the live desktop the same day (headset off). A profile with a maximized Dolphin on screen 1, a floating Konsole, and screen 3 hidden saved correctly. Opened from nothing, it launched both into place. Opened over moved windows, it moved them back without launching anything. `ft-layout start` with `FT_PROFILE` and `ft-layout open` worked as well. Not yet tried: starting the desktop in a profile from its launcher entry or `default_profile` (needs a desktop restart), and the relay's `profile:NAME` action (the running relay is another branch's).
|
||||||
|
|
||||||
A profile is a named layout that also opens apps. It holds:
|
A profile is a named layout that also opens apps. It holds:
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -48,11 +48,20 @@ function info(w) {
|
|||||||
frame: rect(w.frameGeometry), client: rect(w.clientGeometry), popup: w.popupWindow,
|
frame: rect(w.frameGeometry), client: rect(w.clientGeometry), popup: w.popupWindow,
|
||||||
transient: w.transient, parent: w.transientFor ? String(w.transientFor.internalId) : "",
|
transient: w.transient, parent: w.transientFor ? String(w.transientFor.internalId) : "",
|
||||||
normal: w.normalWindow, dialog: w.dialog, fullScreen: w.fullScreen, minimized: w.minimized,
|
normal: w.normalWindow, dialog: w.dialog, fullScreen: w.fullScreen, minimized: w.minimized,
|
||||||
onAllDesktops: w.onAllDesktops, maximized: w.maximizeMode === 3
|
onAllDesktops: w.onAllDesktops, maximized: isMaximized(w)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KWin 6.2's scripts have no maximize mode to read: a window is maximized when it fills its
|
||||||
|
// output's maximize area.
|
||||||
|
function isMaximized(w) {
|
||||||
|
if (!w.normalWindow || !w.output) return false;
|
||||||
|
const a = workspace.clientArea(KWin.MaximizeArea, w), g = w.frameGeometry;
|
||||||
|
return g.x === a.x && g.y === a.y && g.width === a.width && g.height === a.height;
|
||||||
|
}
|
||||||
|
|
||||||
function report(type, w) {
|
function report(type, w) {
|
||||||
|
if (w.deleted) return; // a window on its way out still changes output and size
|
||||||
const ev = info(w);
|
const ev = info(w);
|
||||||
ev.ev = type;
|
ev.ev = type;
|
||||||
send(ev);
|
send(ev);
|
||||||
|
|||||||
+16
-1
@@ -280,6 +280,7 @@ class Daemon:
|
|||||||
self.slots = [Slot(k, args.screens) for k in range(args.slots)]
|
self.slots = [Slot(k, args.screens) for k in range(args.slots)]
|
||||||
self.floats = {} # window id -> Float
|
self.floats = {} # window id -> Float
|
||||||
self.windows = {} # window id -> last info from the script
|
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.pending = [] # commands for the script
|
||||||
self.waiter = None # (reply callback, timeout source) while the script waits
|
self.waiter = None # (reply callback, timeout source) while the script waits
|
||||||
self.screens = Screens(args.control)
|
self.screens = Screens(args.control)
|
||||||
@@ -354,7 +355,10 @@ class Daemon:
|
|||||||
# The script reports every window after "config"; spares nothing floats on are off.
|
# The script reports every window after "config"; spares nothing floats on are off.
|
||||||
GLib.timeout_add(1500, self.disable_unused)
|
GLib.timeout_add(1500, self.disable_unused)
|
||||||
return
|
return
|
||||||
|
if wid in self.gone:
|
||||||
|
return # an event that came after the window closed (it would bring it back)
|
||||||
if kind == "removed":
|
if kind == "removed":
|
||||||
|
self.gone.add(wid)
|
||||||
self.windows.pop(wid, None)
|
self.windows.pop(wid, None)
|
||||||
if wid in self.floats:
|
if wid in self.floats:
|
||||||
log(f"{wid[:9]} closed")
|
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}),
|
saved = f.saved or {"output": "WL-0", "frame": dict(f.frame or {"x": 100, "y": 100, "w": 800, "h": 600}),
|
||||||
"onAllDesktops": False}
|
"onAllDesktops": False}
|
||||||
fr = frame or saved["frame"]
|
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}")
|
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"],
|
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)
|
onAllDesktops=bool(saved.get("onAllDesktops")), maximized=maximized)
|
||||||
|
|||||||
Reference in new issue
Block a user