Stage 3a: wrap the app in 7.css's .window.glass.active frame
The app rendered a bare .title-bar with no .window around it, which is why the Aero frame, glass and drop shadow were missing and the title-bar controls sat permanently in their inactive colours: EVERY control-glyph rule in 7.css is keyed on `.title-bar.active` / `.window.active .title-bar`, and nothing ever set .active. - app.html's root is now `.window.glass`, so it picks up the 6px radius, the 1px frame, the `inset 0 0 0 1px #fff9` highlight, the drop shadow and the backdrop-filter glass layer. - The content below the title bar moved into `.window-body`, 7.css's recessed inner panel (6px inset + its own border) — the thing that gives a Win7 window its depth. - `.active` binds to a new `windowFocused` signal, seeded from document.hasFocus() and updated from window focus/blur. The webview receives those when the NATIVE window's focus changes, so no RPC is needed. Harness renders the shell focused and unfocused: active shows the red close button and crisp glyphs, inactive desaturates, matching the reference. Native window transparency (for the drop shadow and rounded corners to fall outside the window rather than being clipped by an opaque surface) is deliberately NOT in this commit — it is a native flag with a real chance of misbehaving on Linux, so it gets its own change and a real-app check. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+13
-4
@@ -51,9 +51,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</figure>
|
</figure>
|
||||||
<figure class="cell" style="margin:0">
|
<figure class="cell" style="margin:0">
|
||||||
<figcaption>ours — bare .title-bar, no wrapper</figcaption>
|
<figcaption>ours — app.html shell (active above, inactive below)</figcaption>
|
||||||
<div class="stage">
|
<div class="stage">
|
||||||
<div style="width: 320px">
|
<div class="window glass active" style="width: 320px">
|
||||||
<div class="title-bar">
|
<div class="title-bar">
|
||||||
<div class="title-bar-text">miniSCP</div>
|
<div class="title-bar-text">miniSCP</div>
|
||||||
<div class="title-bar-controls">
|
<div class="title-bar-controls">
|
||||||
@@ -62,9 +62,18 @@
|
|||||||
<button aria-label="Close"></button>
|
<button aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="background: var(--w7-surface); padding: 10px">
|
<div class="window-body"><p style="margin:0">Focused window.</p></div>
|
||||||
<p style="margin:0">No frame, no shadow, no glass.</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="window glass" style="width: 320px; margin-top: 12px">
|
||||||
|
<div class="title-bar">
|
||||||
|
<div class="title-bar-text">miniSCP</div>
|
||||||
|
<div class="title-bar-controls">
|
||||||
|
<button aria-label="Minimize"></button>
|
||||||
|
<button aria-label="Maximize"></button>
|
||||||
|
<button aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="window-body"><p style="margin:0">Unfocused — chrome desaturates.</p></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</figure>
|
</figure>
|
||||||
|
|||||||
+10
-2
@@ -1,4 +1,7 @@
|
|||||||
<div class="flex h-screen flex-col bg-background text-foreground">
|
<!-- .window.glass is 7.css's Aero frame (radius, 1px border, inset highlight,
|
||||||
|
drop shadow, backdrop blur); .active is what un-greys the title bar and its
|
||||||
|
control glyphs — every .title-bar-controls rule is keyed on it. -->
|
||||||
|
<div class="window glass flex h-screen flex-col" [class.active]="windowFocused()">
|
||||||
@if (!rpc.available) {
|
@if (!rpc.available) {
|
||||||
<div class="flex flex-1 items-center justify-center">
|
<div class="flex flex-1 items-center justify-center">
|
||||||
<div class="max-w-sm rounded-lg border border-border bg-card p-6 text-center shadow-sm">
|
<div class="max-w-sm rounded-lg border border-border bg-card p-6 text-center shadow-sm">
|
||||||
@@ -10,8 +13,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
} @else {
|
} @else {
|
||||||
<!-- win7 skin only: the window is frameless, so this IS the chrome -->
|
<!-- the window is frameless, so this IS the chrome -->
|
||||||
<app-title-bar [title]="appName" (closeRequested)="closeWindow()" />
|
<app-title-bar [title]="appName" (closeRequested)="closeWindow()" />
|
||||||
|
|
||||||
|
<!-- 7.css's .window-body: the recessed inner panel, with the 6px inset and
|
||||||
|
its own border that give a Win7 window its depth. -->
|
||||||
|
<div class="window-body flex min-h-0 flex-1 flex-col overflow-hidden">
|
||||||
<app-tab-bar />
|
<app-tab-bar />
|
||||||
|
|
||||||
<main class="flex min-h-0 flex-1 divide-x divide-border">
|
<main class="flex min-h-0 flex-1 divide-x divide-border">
|
||||||
@@ -21,6 +28,7 @@
|
|||||||
|
|
||||||
<app-transfer-bar />
|
<app-transfer-bar />
|
||||||
<app-status-bar />
|
<app-status-bar />
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- modal block: the connection-manager window owns the app until closed -->
|
<!-- modal block: the connection-manager window owns the app until closed -->
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ import { UpdaterService } from './updater.service';
|
|||||||
host: {
|
host: {
|
||||||
'(window:keydown)': 'onWindowKeydown($event)',
|
'(window:keydown)': 'onWindowKeydown($event)',
|
||||||
'(window:contextmenu)': 'blockContextMenu($event)',
|
'(window:contextmenu)': 'blockContextMenu($event)',
|
||||||
|
// Aero greys an inactive window's title bar and controls. The webview gets
|
||||||
|
// DOM focus/blur when the native window's focus changes, so this needs no
|
||||||
|
// RPC — see the `active` binding on .window in app.html.
|
||||||
|
'(window:focus)': 'windowFocused.set(true)',
|
||||||
|
'(window:blur)': 'windowFocused.set(false)',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export class App {
|
export class App {
|
||||||
@@ -62,6 +67,9 @@ export class App {
|
|||||||
/** The connection-manager window is open — this window is modal-blocked. */
|
/** The connection-manager window is open — this window is modal-blocked. */
|
||||||
readonly managerOpen = signal(false);
|
readonly managerOpen = signal(false);
|
||||||
|
|
||||||
|
/** Drives `.window.active`: Aero desaturates an unfocused window's chrome. */
|
||||||
|
readonly windowFocused = signal(document.hasFocus());
|
||||||
|
|
||||||
/** Shown in the win7 title bar (no native titlebar to carry it). */
|
/** Shown in the win7 title bar (no native titlebar to carry it). */
|
||||||
readonly appName = BRANDING.appName;
|
readonly appName = BRANDING.appName;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user