mirror of
https://github.com/HeyPuter/puter.git
synced 2026-08-23 22:47:19 +00:00
Dashboard: an app launched by another app takes over the tab
In dashboard mode apps are full-tab experiences, but an app launched by another app (puter.ui.launchApp) opened as a floating titlebar window over its full-tab parent: the parent stayed on screen around its edges, couldn't be raised (focusWindow never raises stay_on_top windows), and a child with no Apps-tab tile had no switcher to come back to once minimized. Give child launches the same treatment as tile launches — maximized, so they get the headless chrome and control drawer — and minimize the parent behind them, iOS-style. State only: the parent's /app/<name> history entry already sits beneath the child's, so Back from the child (and the child's close, which consumes its own entry) lands on the parent's entry and the existing popstate handler restores it. The parent keeps running while hidden, so parent/child IPC is unaffected. Explorer keeps its windowed form, background apps don't minimize their parent, and an explicit `maximized` option still wins. Desktop mode is untouched: both changes are gated on is_dashboard_mode, so an app launching an app there still gets a floating child over a visible parent.
This commit is contained in:
@@ -271,6 +271,16 @@ const launch_app = async (options) => {
|
||||
if ( app_info.maximize_on_start ) {
|
||||
options.maximized = 1;
|
||||
}
|
||||
// Dashboard mode: apps are full-tab experiences (headless chrome,
|
||||
// control drawer, tile/Back switching), so every app launch defaults
|
||||
// to maximized — matching tile launches. Without this, an app launched
|
||||
// by another app (puter.ui.launchApp) opened as a floating titlebar
|
||||
// window over the full-tab parent, with no tile to switch back to.
|
||||
// Explorer keeps its windowed form; an explicit option still wins.
|
||||
if ( window.is_dashboard_mode && options.maximized === undefined
|
||||
&& options.name !== 'explorer' && options.name !== 'trash' ) {
|
||||
options.maximized = 1;
|
||||
}
|
||||
//-----------------------------------
|
||||
// if opened a file, sign it
|
||||
//-----------------------------------
|
||||
@@ -701,6 +711,21 @@ const launch_app = async (options) => {
|
||||
const el = await el_win;
|
||||
process.references.el_win = el;
|
||||
|
||||
// Dashboard mode: an app launched from another app takes over the tab,
|
||||
// iOS-style — the parent app minimizes behind it. State only: the
|
||||
// parent's /app/<name> history entry already sits beneath the child's,
|
||||
// so Back from the child (and the child's close, which consumes its
|
||||
// entry) lands on the parent's entry and the popstate handler restores
|
||||
// it. The parent keeps running while hidden — parent/child IPC works.
|
||||
if ( window.is_dashboard_mode && options.parent_instance_id
|
||||
&& options.maximized && !app_info.background && el ) {
|
||||
const el_parent_win = window.window_for_app_instance(options.parent_instance_id);
|
||||
const parent_minimized = $(el_parent_win).attr('data-is_minimized');
|
||||
if ( el_parent_win && parent_minimized !== '1' && parent_minimized !== 'true' ) {
|
||||
$(el_parent_win).hideWindow();
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! options.launched_by_exec_service ) {
|
||||
process.onchange('ipc_status', value => {
|
||||
if ( value !== PROCESS_IPC_ATTACHED ) return;
|
||||
|
||||
Reference in New Issue
Block a user