diff --git a/system/public/aesthetic.computer/bios.mjs b/system/public/aesthetic.computer/bios.mjs index 70453a619d..7a7d3a4d6c 100644 --- a/system/public/aesthetic.computer/bios.mjs +++ b/system/public/aesthetic.computer/bios.mjs @@ -816,6 +816,7 @@ async function boot(parsed, bpm = 60, resolution, debug) { preservedParams = {}; if (resolution.gap === 0) preservedParams.nogap = "true"; // gap: 0 means nogap was true if (resolution.nolabel === true) preservedParams.nolabel = "true"; + if (resolution.shellhtml === true) preservedParams.shellhtml = "true"; if (resolution.tv === true) preservedParams.tv = "true"; if (resolution.device === true) preservedParams.device = "true"; if (resolution.solo === true) preservedParams.solo = "true"; @@ -13866,6 +13867,9 @@ async function boot(parsed, bpm = 60, resolution, debug) { if (preservedParams.nolabel) { currentUrl.searchParams.set("nolabel", preservedParams.nolabel); } + if (preservedParams.shellhtml) { + currentUrl.searchParams.set("shellhtml", preservedParams.shellhtml); + } if (preservedParams.duration) { currentUrl.searchParams.set("duration", preservedParams.duration); } diff --git a/system/public/aesthetic.computer/boot.mjs b/system/public/aesthetic.computer/boot.mjs index 85a8699f3b..6ed3db1c97 100644 --- a/system/public/aesthetic.computer/boot.mjs +++ b/system/public/aesthetic.computer/boot.mjs @@ -528,7 +528,7 @@ if (window.max?.outlet) { // List of legitimate query parameters that should be preserved const LEGITIMATE_PARAMS = [ 'icon', 'preview', 'signup', 'supportSignUp', 'success', 'code', - 'supportForgotPassword', 'message', 'vscode', 'nogap', 'nolabel', + 'supportForgotPassword', 'message', 'vscode', 'nogap', 'nolabel', 'shellhtml', 'density', 'zoom', 'duration', 'session-aesthetic', 'session-sotce', 'notice', 'tv', 'highlight', 'noauth', 'nocache', 'daw', 'width', 'height', 'desktop', 'device', 'perf', 'auto-scale', 'solo', 'crossfade', 'maxfps' @@ -1109,6 +1109,10 @@ const nogap = params.has("nogap") || params.has("desktop") || location.search.in // Check for nolabel parameter (no localStorage persistence) const nolabel = params.has("nolabel") || params.has("desktop") || location.search.includes("nolabel"); +// π shellhtml β an HTML shell (prompt.ac) hosts the runtime and owns the +// prompt/corner chrome in DOM; the composited equivalents stand down. +const shellhtml = params.has("shellhtml") || location.search.includes("shellhtml"); + // Check for desktop mode (Electron app) - combines nogap + nolabel const desktop = params.has("desktop") || location.search.includes("desktop"); @@ -1237,7 +1241,7 @@ if (window.acVSCODE) { // Pass the parameters directly without stripping them bootLog(`booting: ${parsed?.text || 'prompt'}`); -boot(parsed, bpm, { gap: nogap ? 0 : undefined, nolabel, density, zoom, duration, tv, highlight, desktop, device, perf, autoScale, solo, maxfps, spoofaudio }, debug); +boot(parsed, bpm, { gap: nogap ? 0 : undefined, nolabel, shellhtml, density, zoom, duration, tv, highlight, desktop, device, perf, autoScale, solo, maxfps, spoofaudio }, debug); // Start processing any early kidlisp messages that arrived before boot completed processEarlyKidlispQueue(); diff --git a/system/public/aesthetic.computer/lib/disk.mjs b/system/public/aesthetic.computer/lib/disk.mjs index e6297bc780..ab055aa19c 100644 --- a/system/public/aesthetic.computer/lib/disk.mjs +++ b/system/public/aesthetic.computer/lib/disk.mjs @@ -970,6 +970,10 @@ function fillExpandedWithFadePixels(screen, width, height, oldWidth, oldHeight, } const projectionMode = location.search.indexOf("nolabel") > -1; // Skip loading noise. +// π shellhtml mode β the runtime is hosted by an HTML shell (prompt.ac) that +// owns the prompt + return-to-prompt chrome in crisp DOM above the pixel +// buffer. The composited typable prompt and corner label stand down here. +const shellHTMLMode = location.search.indexOf("shellhtml") > -1; import { setDebug } from "../disks/common/debug.mjs"; import { customAlphabet } from "../dep/nanoid/nanoid.js"; @@ -3675,6 +3679,9 @@ const $commonApi = { data: {}, }, system: { + // π True when an HTML shell (prompt.ac) hosts the runtime and owns the + // prompt / corner chrome in DOM β pieces skip their own low-res chrome. + shellhtml: shellHTMLMode, // prompt: { input: undefined }, Gets set in `prompt_boot`. // π΅ ac-electron drag-drop: set when a file is dropped onto the app // (Dock icon or running window). Pieces (notably `play`) read this on @@ -9662,7 +9669,7 @@ async function load( sim = ($) => { module.sim?.($); - prompt.prompt_sim($); + if (!shellHTMLMode) prompt.prompt_sim($); }; paint = ($) => { @@ -9675,7 +9682,9 @@ async function load( noPaint = true; } - const promptPainted = prompt.prompt_paint($); + // shellhtml: the host page's DOM bar IS the prompt β never composite + // the low-res typable input over the buffer. + const promptPainted = shellHTMLMode ? false : prompt.prompt_paint($); return noPaint || promptPainted; }; @@ -9683,7 +9692,7 @@ async function load( act = ($) => { module.act?.($); - prompt.prompt_act($); + if (!shellHTMLMode) prompt.prompt_act($); // shell DOM owns typing }; leave = ($) => { @@ -9884,6 +9893,7 @@ async function load( const searchParams = new URLSearchParams(parsed.search); if (searchParams.has("nolabel")) hideLabel = true; } + if (shellHTMLMode) hideLabel = true; // the shell's DOM corner overlay replaces it currentColon = colon; currentParams = params; diff --git a/system/public/aesthetic.computer/lib/parse.mjs b/system/public/aesthetic.computer/lib/parse.mjs index f33c56b75c..d63cdcdc8d 100644 --- a/system/public/aesthetic.computer/lib/parse.mjs +++ b/system/public/aesthetic.computer/lib/parse.mjs @@ -18,6 +18,7 @@ const LEGITIMATE_PARAMS = [ "vscode", "nogap", "nolabel", + "shellhtml", "noboot", "density", "zoom", diff --git a/system/public/prompt.ac/index.html b/system/public/prompt.ac/index.html index 232172b13d..03739f6958 100644 --- a/system/public/prompt.ac/index.html +++ b/system/public/prompt.ac/index.html @@ -50,6 +50,22 @@ } .loading.gone { opacity: 0; } + /* ββ DOM corner overlay β the crisp return-to-prompt chip that replaces the + runtime's composited corner label while in shellhtml mode. βββββββββββββ */ + .corner { + position: absolute; top: 8px; left: 8px; z-index: 2; + display: none; align-items: center; gap: 6px; + padding: 4px 9px; cursor: pointer; user-select: none; + background: color-mix(in srgb, var(--bar) 82%, transparent); + border: 1px solid var(--edge); border-radius: 6px; + color: var(--text); font-family: var(--font); font-size: 13px; + backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); + text-shadow: 0 1px 2px rgba(0,0,0,.6); + } + .corner.on { display: flex; } + .corner:hover { border-color: var(--accent); } + .corner .back { color: var(--accent); font-weight: 700; } + /* token colors (for the suggestion/echo line, shared class names with moat) */ .t-handle { color: #ffb0a0; } .t-kidlisp { color: #ff8cc8; } .t-clock { color: #ffd24b; } @@ -63,6 +79,7 @@