Plasma window joins the glass_layout.cfg no-frame list
The desktop plasma window (L4PLASMAWIN, "BattleTech - Plasma") is created by a
different TU than the per-display panels, so it couldn't be a gWins[] entry and
sat outside the sticky-layout / ,noframe system. Add a tiny extern-window
registry to L4GLASSWIN so it rides the same glass_layout.cfg:
- BTGlassLayout_QueryWindow(title, rect, noframe) -- read a title's saved rect
and ,noframe flag (used by the plasma on creation, BEFORE sizing, since
WS_POPUP's frame extent differs from the framed tool window).
- BTGlassLayout_RegisterExtern(hwnd, title) -- register an externally-created
window so SaveLayout writes its line (with a last-known-rect cache so a
teardown before the save still preserves the line).
- BTGlassLayout_Save() -- public save trigger the plasma WndProc calls on
WM_EXITSIZEMOVE / teardown.
L4PLASMAWIN now reads its saved rect+flag on create (WS_POPUP when ,noframe,
position restored), registers itself, and saves on finished-drag/teardown. All
BT_GLASS-gated; the pod is untouched. The plasma blits directly every frame, so
it has no WM_TIMER focus-throttle.
Verified: Release links clean; drag wrote "BattleTech - Plasma=321,222,528,167",
reload with ,noframe brought it up WS_POPUP (WS_CAPTION absent) at 321,222.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -451,6 +451,91 @@ static GWin *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//###########################################################################
|
||||
// External windows that ride glass_layout.cfg (2026-08-04). A window created
|
||||
// by ANOTHER TU -- the plasma window (L4PLASMAWIN) -- can register here so it
|
||||
// shares the SAME position + ",noframe" persistence as the per-display windows:
|
||||
// it queries its saved rect/flag on creation, and Save() writes its line too.
|
||||
// Tiny (HWND + title + last-known rect); no dynamic state.
|
||||
//###########################################################################
|
||||
|
||||
struct ExternWin
|
||||
{
|
||||
HWND hwnd;
|
||||
char title[64];
|
||||
int noFrame;
|
||||
RECT last;
|
||||
int haveLast;
|
||||
};
|
||||
static ExternWin gExtern[4];
|
||||
static int gExternCount = 0;
|
||||
|
||||
// Read the saved rect + ",noframe" flag for a title (glass window OR extern).
|
||||
// Returns 1 if the title has a line in the cfg. rect / noframe may be NULL.
|
||||
int
|
||||
BTGlassLayout_QueryWindow(const char *title, RECT *rect, int *noframe)
|
||||
{
|
||||
if (title == NULL || GlassLayoutMode() == LayoutOff)
|
||||
return 0;
|
||||
FILE *f = fopen(layoutFileName, "rt");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
|
||||
int found = 0;
|
||||
char line[256];
|
||||
while (fgets(line, sizeof(line), f) != NULL)
|
||||
{
|
||||
char *s = line;
|
||||
while (*s == ' ' || *s == '\t') ++s;
|
||||
if (*s == '#' || *s == '\r' || *s == '\n' || *s == '\0')
|
||||
continue;
|
||||
char *eq = strchr(s, '=');
|
||||
if (eq == NULL)
|
||||
continue;
|
||||
*eq = '\0';
|
||||
char *end = eq;
|
||||
while (end > s && (end[-1] == ' ' || end[-1] == '\t')) --end;
|
||||
*end = '\0';
|
||||
if (strcmp(s, title) != 0)
|
||||
continue;
|
||||
|
||||
int x = 0, y = 0, w = 0, h = 0;
|
||||
if (sscanf(eq + 1, "%d,%d,%d,%d", &x, &y, &w, &h) < 2)
|
||||
continue;
|
||||
int nf = 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) { nf = 1; break; }
|
||||
}
|
||||
if (rect) { rect->left = x; rect->top = y; rect->right = x + w; rect->bottom = y + h; }
|
||||
if (noframe) *noframe = nf;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
fclose(f);
|
||||
return found;
|
||||
}
|
||||
|
||||
// Register an externally-created window so Save() writes its line. Loads its
|
||||
// current ",noframe" flag from the cfg so a save round-trips the flag.
|
||||
void
|
||||
BTGlassLayout_RegisterExtern(HWND hwnd, const char *title)
|
||||
{
|
||||
if (hwnd == NULL || title == NULL)
|
||||
return;
|
||||
if (gExternCount >= (int)(sizeof(gExtern) / sizeof(gExtern[0])))
|
||||
return;
|
||||
ExternWin &e = gExtern[gExternCount++];
|
||||
e.hwnd = hwnd;
|
||||
strncpy(e.title, title, sizeof(e.title) - 1);
|
||||
e.title[sizeof(e.title) - 1] = '\0';
|
||||
e.noFrame = 0;
|
||||
e.haveLast = 0;
|
||||
BTGlassLayout_QueryWindow(title, NULL, &e.noFrame);
|
||||
}
|
||||
|
||||
// Restore saved positions over the just-computed pod-faithful defaults. Called
|
||||
// from Create AFTER ComputeLayout, so any window not named in the file keeps its
|
||||
// computed spot. Restored windows are flagged so the WM_TIMER re-snap (which
|
||||
@@ -547,7 +632,8 @@ static void
|
||||
"# 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",
|
||||
"# back. Saves preserve it. The 'BattleTech - Plasma' window is in\n"
|
||||
"# this list too -- it can be dragged, remembered and set ,noframe.\n",
|
||||
f);
|
||||
int wrote = 0;
|
||||
for (int i = 0; i < gWinCount; ++i)
|
||||
@@ -564,11 +650,41 @@ static void
|
||||
gw.noFrame ? ",noframe" : ""); // keep the hand-added option
|
||||
++wrote;
|
||||
}
|
||||
// External windows (the plasma window) ride the same file. Cache the last
|
||||
// good rect so a window torn down before this save still keeps its line.
|
||||
for (int i = 0; i < gExternCount; ++i)
|
||||
{
|
||||
ExternWin &e = gExtern[i];
|
||||
RECT r;
|
||||
if (e.hwnd != NULL && IsWindow(e.hwnd) && GetWindowRect(e.hwnd, &r))
|
||||
{
|
||||
e.last = r; e.haveLast = 1;
|
||||
}
|
||||
else if (e.haveLast)
|
||||
{
|
||||
r = e.last; // window gone -> preserve its last-known line
|
||||
}
|
||||
else
|
||||
continue;
|
||||
fprintf(f, "%s=%ld,%ld,%ld,%ld%s\n", e.title,
|
||||
(long)r.left, (long)r.top,
|
||||
(long)(r.right - r.left), (long)(r.bottom - r.top),
|
||||
e.noFrame ? ",noframe" : "");
|
||||
++wrote;
|
||||
}
|
||||
fclose(f);
|
||||
DEBUG_STREAM << "[glasswin] saved " << wrote << " window position(s) to "
|
||||
<< layoutFileName << "\n" << std::flush;
|
||||
}
|
||||
|
||||
// Public save trigger for registered external windows -- their WndProc calls
|
||||
// this on WM_EXITSIZEMOVE / teardown. No-op unless BT_GLASS_LAYOUT=save.
|
||||
void
|
||||
BTGlassLayout_Save()
|
||||
{
|
||||
SaveLayout();
|
||||
}
|
||||
|
||||
//###########################################################################
|
||||
// Painting
|
||||
//###########################################################################
|
||||
|
||||
Reference in New Issue
Block a user