From b2b1cbc9946805bcbb865f5d007616fc9aef67cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D0=BC=D0=B8=D1=80=20=D0=A8?= =?UTF-8?q?=D0=BC=D0=B0=D0=BD?= Date: Sat, 15 Aug 2026 00:58:54 +0300 Subject: [PATCH 1/4] Redesign the UI as a tiling window system Replaces the tab strip with the workspace the design handoff specifies: a title bar, a window opener, a tiling area of resizable panes, and a status bar, over eleven windows. The layering is the point, and it is what makes this testable: tokens.py the design tokens; the stylesheet is generated from them layout.py the pane tree and the moves over it -- pure, tested models.py what each window shows, as plain data -- pure, tested registry.py the one list of windows the shell derives from state.py one poll, one snapshot, per-client workspace state kit.py the primitives; Quasar is bypassed, not overridden shell.py the chrome, and how a window survives a retile windows/ eleven renderers, none of which read a ledger directly `layout.py` and `models.py` import nothing from NiceGUI, so the interesting half of the UI is tested with the extra uninstalled. `shell.py` is tested by building a real element tree in a `Client`, which is how three of the bugs below were found. Three places the implementation leaves NiceGUI's model, each deliberate: * **Pane dragging is client-side.** A mousemove that asked Python for a new width would run at the speed of the socket. `ui/static/tiling.js` writes `--grad-fraction` straight onto the DOM and emits only the settled fractions on mouseup. * **A window's root is moved, not rebuilt.** `Element.move()` reparents into a hidden attic and back, so a retile does not wipe the chat transcript. * **The Lab iframe lives in a fixed overlay.** Browsers destroy and recreate an `