diff --git a/context/glass-cockpit.md b/context/glass-cockpit.md index bcf1dbc..d19f9e5 100644 --- a/context/glass-cockpit.md +++ b/context/glass-cockpit.md @@ -141,27 +141,29 @@ analogue of TeslaRel410 `emulator/pod-launch`'s per-rig `--bridge-pos`/`--layout ### `,noframe` — per-window chrome removal (2026-07-29) [T2 live] -Append it to a window's line and that window loses its title bar and border (`WS_POPUP`) — for a -multi-monitor wall where the chrome is just noise: +Append it to a window's line and that window comes up with no title bar or border (`WS_POPUP`) — +for a multi-monitor wall where the chrome is just noise: ``` Heat MFD=1920,0,657,539,noframe ``` -Hand-edited (the file is otherwise machine-written). Options are comma-separated after the -numbers and **unknown ones are ignored**, so an older build reading a newer file loses the option -but never the line — the `bindings.txt` grammar rule applied here. +**The workflow is deliberately two-stage, and this is the last step:** run with +`BT_GLASS_LAYOUT=save` and drag the windows where you want them (they have title bars, so it is +the normal sticky-layout flow) → quit → hand-edit the cfg and append `,noframe` to the ones you +want bare. From then on those windows are frameless **and pinned** — with no caption there is +nothing to drag them by, which is the point: the arrangement is finished. Delete the flag to get +the frame back. -Two consequences it has to carry, or the option would be a trap: -- **A frameless window has no title bar to drag** — which is the entire sticky-layout workflow. - So a `noframe` window is dragged **by its surface**: `WM_NCHITTEST` returns `HTCAPTION` - anywhere that is not a button and `HTCLIENT` over one, so buttons stay clickable and the drag - still ends in `WM_EXITSIZEMOVE` and still saves. -- **`SaveLayout` rewrites the whole file**, so it writes the flag back — otherwise the first save - after a drag would silently strip it. +Options are comma-separated after the numbers and **unknown ones are ignored**, so an older build +reading a newer file loses the option but never the line — the `bindings.txt` grammar rule +applied here. -The flag is read BEFORE frame sizing (a `LoadLayout(quiet)` pre-pass), because `AdjustWindowRect` -and therefore `ComputeLayout`'s ring placement depend on whether a window carries chrome. +The one thing it must not do is eat itself: **`SaveLayout` rewrites the WHOLE file** (any later +drag of a framed window triggers it), so it writes the flag back for every window carrying it. +And the flag is read BEFORE frame sizing (a `LoadLayout(quiet)` pre-pass), because +`AdjustWindowRect` — and therefore `ComputeLayout`'s ring placement — depends on whether a window +carries chrome. Verified live: two flagged windows came up caption-less while the other five kept theirs, a click still dispatched on the frameless radar (`CLICK 'Secondary / Radar' addr=0x18`), and a diff --git a/docs/GLASS_COCKPIT.md b/docs/GLASS_COCKPIT.md index dec9238..d39ed72 100644 --- a/docs/GLASS_COCKPIT.md +++ b/docs/GLASS_COCKPIT.md @@ -777,13 +777,22 @@ Options are comma-separated after the four numbers and unknown ones are IGNORED, reading a newer file loses the option but never the line (the bindings.txt grammar rule applied here). Hand-edited; the file is otherwise machine-written. -### The two things that would have made it a trap -1. **A frameless window has no title bar to drag** -- which is the entire point of the sticky - layout. So a noframe window is dragged BY ITS SURFACE: `WM_NCHITTEST` returns `HTCAPTION` - anywhere that is not a button and `HTCLIENT` over one. Buttons stay clickable, and because - Windows drives the move, the drag still ends in `WM_EXITSIZEMOVE` -- so it still SAVES. -2. **SaveLayout rewrites the whole file**, so it writes the flag back. Without that the first - finished-drag after adding the option would have silently stripped it. +### The workflow is two-stage, on purpose +Arrange FIRST, strip chrome LAST: + 1. run with `BT_GLASS_LAYOUT=save` and drag the windows where you want them (they have title + bars -- this is just the normal sticky-layout flow), + 2. quit, + 3. hand-edit the cfg and append `,noframe` to the ones you want bare. + +From then on those windows come up frameless AND PINNED -- with no caption there is nothing to +drag them by, which is the point: the arrangement is finished. Delete the flag to re-frame. + +(An earlier cut made noframe windows draggable by their surface via `WM_NCHITTEST`->`HTCAPTION`. +Removed at the author's direction: it is not an interactive mode, it is the finishing step.) + +The one thing it must not do is eat itself: **SaveLayout rewrites the WHOLE file** -- any later +drag of a FRAMED window triggers it -- so it writes the flag back for every window that carries +one. Without that, the first drag after adding the option would silently strip it. ### Ordering The flag is read BEFORE frame sizing (`LoadLayout(quiet)` pre-pass, then the normal pass after diff --git a/engine/MUNGA_L4/L4GLASSWIN.cpp b/engine/MUNGA_L4/L4GLASSWIN.cpp index fd05659..6c1e816 100644 --- a/engine/MUNGA_L4/L4GLASSWIN.cpp +++ b/engine/MUNGA_L4/L4GLASSWIN.cpp @@ -383,19 +383,22 @@ static void // // PER-LINE OPTION ",noframe" (2026-07-29): append it to a window's line and // that window loses its title bar and border (WS_POPUP) -- for a clean -// multi-monitor wall where the chrome is just noise. Hand-edited; the file -// is otherwise machine-written. +// multi-monitor wall where the chrome is just noise. // // Heat MFD=1920,0,657,539,noframe // -// Two consequences it has to carry, or the option would be a trap: -// - a frameless window has NO TITLE BAR TO DRAG, which is how the whole -// sticky-layout workflow works. So a noframe window is draggable BY ITS -// SURFACE (WM_NCHITTEST -> HTCAPTION anywhere that is not a button); the -// buttons stay clickable, and the drag still ends in WM_EXITSIZEMOVE so it -// still saves. -// - SaveLayout rewrites the whole file, so it must WRITE THE FLAG BACK or the -// first save after a drag would silently strip it. +// THE WORKFLOW IS DELIBERATELY TWO-STAGE, and the option is the last step: +// 1. run with BT_GLASS_LAYOUT=save and DRAG the windows where you want them +// (they have title bars, so this is the normal sticky-layout flow), +// 2. quit, +// 3. hand-edit the cfg and append ,noframe to the ones you want bare. +// From then on those windows come up frameless AND PINNED -- with no caption +// there is nothing to drag them by, which is the point: the arrangement is +// finished. Re-frame a window by deleting the flag. +// +// The one thing it must not do is eat itself: SaveLayout rewrites the WHOLE +// file (any later drag of a FRAMED window triggers it), so it writes the flag +// back for every window that carries it. //########################################################################### enum { LayoutOff = 0, LayoutLoad = 1, LayoutSave = 2 }; @@ -536,9 +539,13 @@ static void fputs("# BT411 glass cockpit window layout (BT_GLASS_LAYOUT=save writes this\n" "# on finished-drag/exit; =load restores it).