Skip to content
28 changes: 22 additions & 6 deletions assets/css/window-states.css
Original file line number Diff line number Diff line change
Expand Up @@ -364,16 +364,27 @@
}

/*
* Minimized state — fade + scale down.
* Uses opacity + pointer-events instead of display: none so the
* CSS transition can animate the change. The window is invisible
* and non-interactive but stays in the DOM for a smooth restore.
* Minimized state — window is hidden and non-interactive at the dock.
* Uses opacity + pointer-events + transition: none so neither state
* changes nor WAAPI animation teardown trigger accidental transitions.
*/
.os-window--minimized {
opacity: 0;
transform: scale(0.92) translateY(16px);
pointer-events: none;
will-change: transform, opacity;
transition: none !important;
}

/*
* Genie helpers — active only during the WAAPI flight to/from the
* dock. Disable the base `left/top/width/height/transform/opacity`
* transition so the CSS transition doesn't fight the WAAPI
* `element.animate()` that drives the scale-to-dock motion. The
* minimized class is applied AFTER the minimizing flight lands, and
* the restoring class is removed AFTER the restoring flight lands.
*/
.os-window--minimizing,
.os-window--restoring {
transition: none !important;
}

/*
Expand Down Expand Up @@ -418,6 +429,11 @@
.os-window--opening {
animation-duration: 0.01ms !important;
}
.os-window--minimizing,
.os-window--restoring {
animation: none !important;
transition: none !important;
}
}

/*
Expand Down
13 changes: 13 additions & 0 deletions src/dock.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**

Check warning on line 1 in src/dock.ts

View workflow job for this annotation

GitHub Actions / Lint · Types · Vitest

This file is 2914 lines — past the 1000-line comfort zone. Be smart, build robust software: modules of ~300–600 lines are easier to read, test, review and reuse. Consider splitting this one along its natural seams — future you will say thanks
* OpenStation — Dock.
*
* Renders the icon-only dock on the left edge of the desktop.
Expand Down Expand Up @@ -1264,6 +1264,10 @@
);
tile.className = filteredClasses.join( ' ' );
tile.dataset.systemId = item.id;
// Genie minimize: Window looks for its dock tile via
// `[data-os-window-base-id="…"]` so the animation can fly to
// the correct icon. System tiles are keyed by their own id.
( tile.dataset as unknown as Record< string, string > ).osWindowBaseId = item.id;
// The constellation resolves a flyout from this attribute the
// way it resolves a menu one from `data-menu-slug`, and
// `dock-peek` stands down on it for the same reason it stands
Expand Down Expand Up @@ -1429,6 +1433,10 @@
// the peek card never appears even when the native window
// is open.
const baseId = this.resolveItemBaseId( item );
// Genie minimize: Window looks for `[data-os-window-base-id="…"]`
// so the animation can fly to the exact icon. Must be set before
// the `DOCK_TILE_ELEMENT` filter in case a decorator wraps the tile.
( tile.dataset as unknown as Record< string, string > ).osWindowBaseId = baseId;
const teardown = attachDockPeek( {
tile,
item: {
Expand Down Expand Up @@ -2448,7 +2456,12 @@
if ( item.windowId && ! item.url ) {
const existing = this.windowManager.getById( item.windowId );
if ( existing ) {
// Read before focus() — restore() mutates state to 'normal'.
const wasMinimized = existing.state === 'minimized';
this.windowManager.focus( existing );
if ( wasMinimized ) {
existing.restore();
}
return;
}
const wp = ( window as unknown as {
Expand Down
Loading
Loading