From f5f4c6c19821e60c3db5a13ab0d49b6c9987817b Mon Sep 17 00:00:00 2001 From: Cyd Date: Wed, 29 Jul 2026 10:57:00 -0500 Subject: [PATCH 1/2] glass_layout.cfg: ",noframe" per-line option strips a window's title bar Append it to a window's line and that window becomes a bare WS_POPUP -- no caption, no border, just the display and its buttons -- for a multi-monitor wall where the chrome is only noise: Heat MFD=1920,0,657,539,noframe Options are comma-separated after the four 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). TWO THINGS THAT WOULD HAVE MADE IT A TRAP, both handled: - 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, HTCLIENT over one. Buttons stay clickable, and because Windows drives the move the drag still ends in WM_EXITSIZEMOVE -- so it still saves. - 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. Ordering: the flag is read BEFORE frame sizing (a quiet LoadLayout pre-pass, then the normal pass after ComputeLayout), because AdjustWindowRect -- and therefore the ring placement -- depends on whether a window carries chrome. The pre-pass is quiet so the restore still logs exactly once. Verified live: two flagged windows came up with WS_CAPTION clear while the other five kept it (read back with GetWindowLong(GWL_STYLE)); a click still dispatched on the frameless radar (CLICK 'Secondary / Radar' addr=0x18); and a WM_EXITSIZEMOVE save round-tripped both flags back into the rewritten file. surround / exploded / layout=off / pod / dev all boot and simulate clean. Co-Authored-By: Claude Opus 5 (1M context) --- context/glass-cockpit.md | 28 ++++++++++ docs/GLASS_COCKPIT.md | 33 ++++++++++++ engine/MUNGA_L4/L4GLASSWIN.cpp | 95 +++++++++++++++++++++++++++++----- game/btl4main.cpp | 6 +++ 4 files changed, 149 insertions(+), 13 deletions(-) diff --git a/context/glass-cockpit.md b/context/glass-cockpit.md index 88daf0d..bcf1dbc 100644 --- a/context/glass-cockpit.md +++ b/context/glass-cockpit.md @@ -139,6 +139,34 @@ at exactly 777,333 after the re-snap fired). Save fires on `WM_EXITSIZEMOVE` (su since it writes as soon as a drag finishes) with a teardown write as backstop. This is the native analogue of TeslaRel410 `emulator/pod-launch`'s per-rig `--bridge-pos`/`--layout` placement args. +### `,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: + +``` +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. + +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. + +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. + +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 +finished-drag save round-tripped both flags back into the file. + **Verified 2026-07-26 [T2]:** `BT_RIOBANK_LOG=1` dumps every bank's rects; `scratchpad/checkbank.py` reports the per-bank census and proves no address is SHADOWED (has a point no earlier button covers); `scratchpad/clickbank.py` then posts a real click at every diff --git a/docs/GLASS_COCKPIT.md b/docs/GLASS_COCKPIT.md index 2208e71..dec9238 100644 --- a/docs/GLASS_COCKPIT.md +++ b/docs/GLASS_COCKPIT.md @@ -764,3 +764,36 @@ per-rig `--bridge-pos`/`--layout` args. - round-trip: relaunched `load` against the game-written cfg → after 12 s (past the re-snap) the *Flight Controls* window was physically at (777,333), all 7 at their saved coords — the re-snap guard held. + +## 2026-07-29 — glass_layout.cfg gains a per-line ",noframe" option + +Requested: strip a window's title bar from the layout file. Appending `,noframe` to a window's +line makes that window a bare `WS_POPUP` -- no caption, no border, nothing but the display and its +buttons -- for a multi-monitor wall where the chrome is only noise. + + Heat MFD=1920,0,657,539,noframe + +Options are comma-separated after the four 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). 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. + +### Ordering +The flag is read BEFORE frame sizing (`LoadLayout(quiet)` pre-pass, then the normal pass after +`ComputeLayout`): `AdjustWindowRect` -- and therefore the ring placement -- depends on whether a +window carries chrome. The pre-pass is quiet so the restore still logs exactly once. + +### Verified live +- Two flagged windows (`Heat MFD`, `Secondary / Radar`) came up with `WS_CAPTION` CLEAR while the + other five kept it -- read back out of the live windows with `GetWindowLong(GWL_STYLE)`. +- A click still dispatched on the frameless radar: `[glasswin] CLICK 'Secondary / Radar' addr=0x18`. +- A finished-drag save (`WM_EXITSIZEMOVE`) round-tripped BOTH flags back into the rewritten file, + header comment and all. +- surround / exploded / layout=off / pod / dev: boot + simulate, zero faults. diff --git a/engine/MUNGA_L4/L4GLASSWIN.cpp b/engine/MUNGA_L4/L4GLASSWIN.cpp index b17f096..fd05659 100644 --- a/engine/MUNGA_L4/L4GLASSWIN.cpp +++ b/engine/MUNGA_L4/L4GLASSWIN.cpp @@ -114,6 +114,7 @@ struct GWin int frameW, frameH; int wantX, wantY; int restored; // wantX/wantY came from glass_layout.cfg -> don't re-snap + int noFrame; // ",noframe" in the cfg -> WS_POPUP, drag by the surface }; static GWin gWins[8]; @@ -379,12 +380,38 @@ static void // a later geometry change can't distort an old save. Windows carry WS_CAPTION // in every mode, so they are always draggable -- the gate only controls whether // a drag STICKS. +// +// 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. +// +// 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. //########################################################################### enum { LayoutOff = 0, LayoutLoad = 1, LayoutSave = 2 }; static const char *layoutFileName = "glass_layout.cfg"; +// A framed window is a normal tool window; ",noframe" makes it a bare +// WS_POPUP -- no caption, no border, nothing but the display and its buttons. +static DWORD + GlassWindowStyle(const GWin &w) +{ + return w.noFrame + ? (DWORD)WS_POPUP + : (DWORD)(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); +} + static int GlassLayoutMode() { @@ -424,7 +451,7 @@ static GWin * // computed spot. Restored windows are flagged so the WM_TIMER re-snap (which // re-runs ComputeLayout once the main window appears) leaves them alone. static void - LoadLayout() + LoadLayout(int quiet) { if (GlassLayoutMode() == LayoutOff) return; @@ -432,8 +459,9 @@ static void FILE *f = fopen(layoutFileName, "rt"); if (f == NULL) { - DEBUG_STREAM << "[glasswin] no " << layoutFileName - << " yet (using computed placement)\n" << std::flush; + if (!quiet) + DEBUG_STREAM << "[glasswin] no " << layoutFileName + << " yet (using computed placement)\n" << std::flush; return; } @@ -459,17 +487,34 @@ static void if (sscanf(eq + 1, "%d,%d,%d,%d", &x, &y, &w, &h) < 2) continue; + // Trailing options after the numbers, comma-separated. Unknown ones + // are ignored (so an older build reading a newer file just loses the + // option, never the line) -- the bindings.txt grammar rule. + int noframe = 0; + for (const char *opt = strchr(eq + 1, ','); opt != NULL; opt = strchr(opt + 1, ',')) + { + const char *t = opt + 1; + while (*t == ' ' || *t == '\t') ++t; + if (_strnicmp(t, "noframe", 7) == 0) + { + noframe = 1; + break; + } + } + GWin *gw = FindGWinByTitle(s); if (gw == NULL) continue; gw->wantX = x; gw->wantY = y; + gw->noFrame = noframe; gw->restored = 1; ++restored; } fclose(f); - DEBUG_STREAM << "[glasswin] restored " << restored << " window position(s) from " - << layoutFileName << "\n" << std::flush; + if (!quiet) + DEBUG_STREAM << "[glasswin] restored " << restored << " window position(s) from " + << layoutFileName << "\n" << std::flush; } // Write every window's current on-screen frame rect. Whole-file rewrite (it is @@ -490,7 +535,10 @@ static void } fputs("# BT411 glass cockpit window layout (BT_GLASS_LAYOUT=save writes this\n" - "# on finished-drag/exit; =load restores it). =<x>,<y>,<w>,<h>\n", + "# on finished-drag/exit; =load restores it). <title>=<x>,<y>,<w>,<h>\n" + "# Append ,noframe to a line to drop that window's title bar and border;\n" + "# a frameless window is dragged by its SURFACE instead (buttons still\n" + "# click). Hand-edit to add it -- saves preserve it.\n", f); int wrote = 0; for (int i = 0; i < gWinCount; ++i) @@ -501,9 +549,10 @@ static void RECT r; if (!GetWindowRect(gw.hwnd, &r)) continue; - fprintf(f, "%s=%ld,%ld,%ld,%ld\n", gw.title, + fprintf(f, "%s=%ld,%ld,%ld,%ld%s\n", gw.title, (long)r.left, (long)r.top, - (long)(r.right - r.left), (long)(r.bottom - r.top)); + (long)(r.right - r.left), (long)(r.bottom - r.top), + gw.noFrame ? ",noframe" : ""); // keep the hand-added option ++wrote; } fclose(f); @@ -793,6 +842,24 @@ static LRESULT CALLBACK case WM_ERASEBKGND: return 1; // PaintGlass fills the frame (double-buffered) + // + // ",noframe" windows have no title bar, so the SURFACE is the drag handle: + // report HTCAPTION anywhere that is not a button and Windows moves the + // window for us -- including the WM_EXITSIZEMOVE at the end, so a drag + // still sticks in save mode. Over a button we report HTCLIENT so the + // press reaches WM_LBUTTONDOWN as usual. + // + case WM_NCHITTEST: + if (w != NULL && w->noFrame) + { + POINT p; + p.x = (int)(short)LOWORD(lparam); + p.y = (int)(short)HIWORD(lparam); + ScreenToClient(window, &p); + return (HitTest(w, p.x, p.y) >= 0) ? HTCLIENT : HTCAPTION; + } + break; + case WM_TIMER: if (wparam == RepaintTimerId) { @@ -926,18 +993,20 @@ void wc.lpszClassName = L"BTGlassWin"; RegisterClassW(&wc); - DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + // The ",noframe" flag is per WINDOW and arrives with the layout file, so + // read that FIRST -- the frame size (and therefore ComputeLayout's ring + // placement) depends on which windows carry chrome. + LoadLayout(1); // quiet: this pass only needs the ",noframe" flags - // Frame sizes first (ComputeLayout positions by frame dims). for (int i = 0; i < gWinCount; ++i) { RECT fr = { 0, 0, gWins[i].clientW, gWins[i].clientH }; - AdjustWindowRect(&fr, style, FALSE); + AdjustWindowRect(&fr, GlassWindowStyle(gWins[i]), FALSE); gWins[i].frameW = fr.right - fr.left; gWins[i].frameH = fr.bottom - fr.top; } ComputeLayout(); - LoadLayout(); // BT_GLASS_LAYOUT=load/save: restore saved positions over the ring + LoadLayout(0); // re-apply saved positions over the computed ring for (int i = 0; i < gWinCount; ++i) { @@ -951,7 +1020,7 @@ void // of the game's D3D swap chain, ending GDI-vs-D3D presentation strobing. w.hwnd = CreateWindowExW( WS_EX_TOPMOST | WS_EX_LAYERED, - L"BTGlassWin", wtitle, style, + L"BTGlassWin", wtitle, GlassWindowStyle(w), w.wantX, w.wantY, w.frameW, w.frameH, NULL, NULL, GetModuleHandleW(NULL), NULL); if (w.hwnd == NULL) diff --git a/game/btl4main.cpp b/game/btl4main.cpp index 6a34957..ec57ebe 100644 --- a/game/btl4main.cpp +++ b/game/btl4main.cpp @@ -297,6 +297,12 @@ static const char *kEnvironIniDefault = "# load restore the saved layout but never change it (read-only)\n" "# The positions live in glass_layout.cfg beside this file -- delete it to go\n" "# back to the pod ring. Windows not in the file keep their computed spot.\n" +"#\n" +"# In that file you can also append ,noframe to a window's line to strip its\n" +"# title bar and border -- handy on a multi-monitor wall where the chrome is\n" +"# just noise. A frameless window is dragged by its SURFACE instead (the\n" +"# buttons still click), and saves keep the flag:\n" +"# Heat MFD=1920,0,657,539,noframe\n" "#BT_GLASS_LAYOUT=save\n" "\n" "# Size of the secondary displays in the cockpit surround, as a percentage of\n" From aa788bc56df42efad7fb9b8f41368cdf53a2249e Mon Sep 17 00:00:00 2001 From: Cyd <cyd@falloutshelterarcade.com> Date: Wed, 29 Jul 2026 11:26:11 -0500 Subject: [PATCH 2/2] noframe: drop the drag-by-surface -- it is a finishing step, not a mode Author's correction to the shape of yesterday's option. The intended workflow is: place the displays where you want them WITH their frames, quit, then edit glass_layout.cfg to turn the frame off. So a ,noframe window should be pinned, not draggable -- removed the WM_NCHITTEST -> HTCAPTION handler that made the surface a drag handle. The arrangement being finished is the point: with no caption there is nothing to drag it by, which is exactly what you want on a wall of monitors. Delete the flag to get the frame (and the dragging) back. Unchanged and still needed: SaveLayout writes the flag back, because any later drag of a FRAMED window rewrites the whole file and would otherwise strip it. Re-verified live: - Heat MFD comes up with WS_CAPTION clear and answers WM_NCHITTEST on its surface with HTCLIENT (pinned) -- no window reports HTCAPTION any more. - Comm MFD (unflagged) keeps its caption. - A framed window's WM_EXITSIZEMOVE rewrote the file and BOTH ,noframe flags survived, with the new header explaining the arrange-first workflow. - surround / exploded / pod / dev boot and simulate clean. Docs updated to describe the two-stage workflow rather than surface dragging: the file's own header, environ.ini's BT_GLASS_LAYOUT block, context/ glass-cockpit.md and the ledger (which records the removed behaviour so the next reader does not re-add it). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --- context/glass-cockpit.md | 30 ++++++++++---------- docs/GLASS_COCKPIT.md | 23 +++++++++++----- engine/MUNGA_L4/L4GLASSWIN.cpp | 50 ++++++++++++++-------------------- game/btl4main.cpp | 9 +++--- 4 files changed, 57 insertions(+), 55 deletions(-) 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). <title>=<x>,<y>,<w>,<h>\n" - "# Append ,noframe to a line to drop that window's title bar and border;\n" - "# a frameless window is dragged by its SURFACE instead (buttons still\n" - "# click). Hand-edit to add it -- saves preserve it.\n", + "#\n" + "# Happy with where everything sits? Quit, then append ,noframe to any\n" + "# line to bring that window up with no title bar or border:\n" + "# Heat MFD=1920,0,657,539,noframe\n" + "# A frameless window is also PINNED (no caption = nothing to drag it\n" + "# by), so do the arranging first. Delete the flag to get the frame\n" + "# back. Saves preserve it.\n", f); int wrote = 0; for (int i = 0; i < gWinCount; ++i) @@ -842,23 +849,6 @@ static LRESULT CALLBACK case WM_ERASEBKGND: return 1; // PaintGlass fills the frame (double-buffered) - // - // ",noframe" windows have no title bar, so the SURFACE is the drag handle: - // report HTCAPTION anywhere that is not a button and Windows moves the - // window for us -- including the WM_EXITSIZEMOVE at the end, so a drag - // still sticks in save mode. Over a button we report HTCLIENT so the - // press reaches WM_LBUTTONDOWN as usual. - // - case WM_NCHITTEST: - if (w != NULL && w->noFrame) - { - POINT p; - p.x = (int)(short)LOWORD(lparam); - p.y = (int)(short)HIWORD(lparam); - ScreenToClient(window, &p); - return (HitTest(w, p.x, p.y) >= 0) ? HTCLIENT : HTCAPTION; - } - break; case WM_TIMER: if (wparam == RepaintTimerId) diff --git a/game/btl4main.cpp b/game/btl4main.cpp index ec57ebe..664a1b9 100644 --- a/game/btl4main.cpp +++ b/game/btl4main.cpp @@ -298,11 +298,12 @@ static const char *kEnvironIniDefault = "# The positions live in glass_layout.cfg beside this file -- delete it to go\n" "# back to the pod ring. Windows not in the file keep their computed spot.\n" "#\n" -"# In that file you can also append ,noframe to a window's line to strip its\n" -"# title bar and border -- handy on a multi-monitor wall where the chrome is\n" -"# just noise. A frameless window is dragged by its SURFACE instead (the\n" -"# buttons still click), and saves keep the flag:\n" +"# Once everything is where you want it, quit and append ,noframe to any line\n" +"# in that file to bring that window up with no title bar or border -- handy\n" +"# on a multi-monitor wall where the chrome is just noise:\n" "# Heat MFD=1920,0,657,539,noframe\n" +"# Arrange FIRST: a frameless window is also pinned (no caption means nothing\n" +"# to drag it by). Delete the flag to get the frame back.\n" "#BT_GLASS_LAYOUT=save\n" "\n" "# Size of the secondary displays in the cockpit surround, as a percentage of\n"