mirror of
https://github.com/HeyPuter/puter.git
synced 2026-08-23 22:47:19 +00:00
Dashboard: fix minimized apps getting permanently buried under the dashboard (#3429)
* Dashboard: fix minimized apps getting permanently buried under the dashboard Fullpage/dashboard app windows are created stay_on_top in the 99999999+ z band, but showWindow's restore path demoted them to a plain counter z-index — and since focusWindow deliberately never raises stay_on_top windows, the demotion stuck: one dashboard focus after a minimize/restore buried the app permanently (URL and tab title still naming an app the user could no longer see). Restore now re-raises stay-on-top windows into their band. Also make the control pill focus its window on mousedown, as the titlebar it replaces did. The document-level activation handler works off mouseover_window, which only mousemove refreshes — a tap with no intervening mousemove (touch, restored windows) would activate the stale window and could re-raise the dashboard over the app. Deferred a tick so it runs after that handler and wins. * Dashboard: restored windows come back with the pill collapsed The restore re-played the open intro (expand + auto-retract). A restore should bring back the app, not the chrome — the user already met the controls on open, and they just USED them to minimize. showWindow now forces the pill shut instead, which also covers the Back-button minimize path, where the window hides without touching pill state. * Dashboard pill: left-align the title against the icon The pill is asymmetric — one icon on the left, two buttons on the right — so a title centered in its fixed box landed off the pill's true center and read as misaligned. Left-aligned, icon + title cluster as the identity on the left and the controls cluster on the right.
This commit is contained in:
@@ -3904,6 +3904,16 @@ $.fn.showWindow = async function (options) {
|
||||
// show window
|
||||
const el_window = this;
|
||||
|
||||
// Stay-on-top windows (every fullpage/dashboard app window) are
|
||||
// CREATED in the 99999999+ z band; restore must re-raise them
|
||||
// into that same band. A plain counter z would demote the window
|
||||
// below whatever gets focused next — and focusWindow deliberately
|
||||
// never raises stay_on_top windows, so the demotion would stick
|
||||
// (a dashboard-mode app would sit buried under the dashboard).
|
||||
const raised_zindex = () => ($(el_window).attr('data-stay_on_top') === 'true'
|
||||
? 99999999 + (++window.last_window_zindex)
|
||||
: ++window.last_window_zindex);
|
||||
|
||||
// A window minimized with no taskbar to animate toward (dashboard
|
||||
// mode) was hidden in place by hideWindow — its geometry was
|
||||
// never disturbed. If the app's tile is visible on the Apps tab's
|
||||
@@ -3917,7 +3927,7 @@ $.fn.showWindow = async function (options) {
|
||||
'data-is_minimized': false,
|
||||
'data-minimized_in_place': '0',
|
||||
});
|
||||
$(el_window).css('z-index', ++window.last_window_zindex);
|
||||
$(el_window).css('z-index', raised_zindex());
|
||||
const reduce_motion = window.matchMedia
|
||||
&& window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
// Skip the morph while another morph still owns the window's
|
||||
@@ -3946,9 +3956,10 @@ $.fn.showWindow = async function (options) {
|
||||
if ( ! morphed && was_hidden ) $(el_window).hide();
|
||||
}
|
||||
if ( ! morphed ) $(el_window).fadeIn(150);
|
||||
// Re-introduce the control pill on restore (headless
|
||||
// dashboard windows only; no-op otherwise).
|
||||
el_window._dashboard_pill_flash?.();
|
||||
// Restores come back with the control pill collapsed —
|
||||
// whatever state it was minimized in (headless dashboard
|
||||
// windows only; no-op otherwise).
|
||||
el_window._dashboard_pill_collapse?.();
|
||||
// A restore re-claims the URL for this app — except when
|
||||
// the restore was DRIVEN by a history traversal (popstate
|
||||
// passes no_history: the entry is already current).
|
||||
@@ -3970,7 +3981,7 @@ $.fn.showWindow = async function (options) {
|
||||
width: `${$(el_window).attr('data-orig-width') }px`,
|
||||
height: `${$(el_window).attr('data-orig-height') }px`,
|
||||
});
|
||||
$(el_window).css('z-index', ++window.last_window_zindex);
|
||||
$(el_window).css('z-index', raised_zindex());
|
||||
|
||||
$(el_window).attr({
|
||||
'data-is_minimized': false,
|
||||
@@ -4296,8 +4307,8 @@ function attach_dashboard_app_pill (el_window, options) {
|
||||
clearTimeout(collapse_timer);
|
||||
collapse_timer = setTimeout(collapse, ms);
|
||||
};
|
||||
// Expand + auto-collapse: played on open and again on restore, so the
|
||||
// controls introduce themselves without permanently costing pixels.
|
||||
// Expand + auto-collapse: played once on open, so the controls
|
||||
// introduce themselves without permanently costing pixels.
|
||||
const flash = () => {
|
||||
expand();
|
||||
schedule_collapse(2600);
|
||||
@@ -4311,6 +4322,16 @@ function attach_dashboard_app_pill (el_window, options) {
|
||||
$pill.on('focusin', () => expand());
|
||||
$pill.on('focusout', () => schedule_collapse(1100));
|
||||
|
||||
// Pressing the pill activates its window, as pressing a titlebar
|
||||
// would — the pill took over the head's job. Deferred a tick because
|
||||
// the document-level activation handler (initgui's mousedown →
|
||||
// mouseover_window) runs after this one on hover bookkeeping that only
|
||||
// mousemove refreshes; a tap with no mousemove since a dashboard click
|
||||
// (touch, restored windows) would re-raise the dashboard OVER the app.
|
||||
$pill.on('mousedown', () => {
|
||||
setTimeout(() => $(el_window).focusWindow(), 0);
|
||||
});
|
||||
|
||||
// A click anywhere on the collapsed pill (incl. its invisible touch
|
||||
// halo) expands it; the toggle also collapses an expanded pill for an
|
||||
// explicit dismiss. Buttons are pointer-events:none while collapsed,
|
||||
@@ -4344,8 +4365,11 @@ function attach_dashboard_app_pill (el_window, options) {
|
||||
$(el_window).close();
|
||||
});
|
||||
|
||||
// showWindow re-plays the intro when the window is restored.
|
||||
el_window._dashboard_pill_flash = flash;
|
||||
// showWindow forces the pill shut when the window is restored — the
|
||||
// intro already ran on open, and a restore should bring back the app,
|
||||
// not the chrome. (Minimize collapses too, but the Back-button path
|
||||
// hides the window without touching the pill.)
|
||||
el_window._dashboard_pill_collapse = collapse;
|
||||
|
||||
$(el_window).append($pill);
|
||||
flash();
|
||||
|
||||
@@ -4334,14 +4334,17 @@ body.dashboard-mode .window-dashboard-headless .window-body-app {
|
||||
text-overflow: ellipsis;
|
||||
/* FIXED title box (not a cap): every app's pill is the same width, so
|
||||
the minimize/close buttons sit at the same screen position in every
|
||||
app — they're operated by muscle memory. Short titles center in
|
||||
the box like a classic titlebar. The collapse animation still
|
||||
drives max-width to 0. */
|
||||
app — they're operated by muscle memory. Left-aligned against the
|
||||
icon: the pill is asymmetric (one icon left, two buttons right), so
|
||||
a centered title lands off the pill's true center and reads as
|
||||
misaligned. Icon + title cluster as the identity on the left, the
|
||||
controls cluster on the right. The collapse animation still drives
|
||||
max-width to 0. */
|
||||
flex: none;
|
||||
width: 150px;
|
||||
max-width: 150px;
|
||||
text-align: center;
|
||||
margin: 0 6px 0 4px;
|
||||
text-align: left;
|
||||
margin: 0 6px 0 8px;
|
||||
transition: max-width 0.22s ease, opacity 0.15s ease, margin 0.22s ease;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user