feat(plugins): full-screen (immersive) plugin screens via manifest opt-in (#590)

DAW-style plugin UIs (e.g. a practice studio) need the whole viewport, not a
scrolling content page below the v3 topbar — embedded in the shell they get
cut off at the bottom with excess padding up top.

Add an opt-in top-level `"fullscreen": true` plugin.json field, surfaced as the
`fullscreen` boolean on /api/plugins (mirrors the settings_category plumbing in
plugins/__init__.py). When a fullscreen plugin's screen is active, static/v3/
shell.js toggles `html.fb-immersive` from syncActive() so it tracks every
navigation incl. deep-link; static/v3/v3.css then hides the topbar, collapses
the sidebar to a functional icon rail (kept reachable — Escape is bound only on
player/settings scopes, so a fully hidden sidebar would trap the user), and
lets the active plugin screen fill #v3-main. Mirrors the existing
ss-follower-pre chrome-hide pattern. Additive + opt-in: plugins without the
flag are unaffected.

Test: tests/test_plugins.py::test_fullscreen_flag_parsed_from_manifest


Claude-Session: https://claude.ai/code/session_01BmWopMsRjdZyD6RwmZAQBv

Signed-off-by: ChrisBeWithYou <christian.a.cowan@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: byrongamatos <xasiklas@gmail.com>
This commit is contained in:
ChrisBeWithYou
2026-06-25 00:02:16 +02:00
committed by GitHub
co-authored by Claude Opus 4.8 byrongamatos
parent 8b4c9b0050
commit 4c3ec2ff66
5 changed files with 106 additions and 2 deletions
+36
View File
@@ -1074,3 +1074,39 @@ body.font-display { font-family: Rubik, system-ui, sans-serif; }
}
.fb-settings-note { font-size: .75rem; color: #64748b; margin-top: 1rem; }
.fb-tabpanel-empty { font-size: .8rem; color: #64748b; padding: .5rem 0; }
/* ── Immersive (full-screen) plugin screens ──────────────────────────────────
A plugin that declares `"fullscreen": true` in its manifest gets the whole
content area when its screen is active. shell.js toggles `html.fb-immersive`
on navigation (see syncActive). DAW-style plugin UIs (e.g. a practice studio)
need the viewport, not a scrolling content page below the topbar — the cause
of the "cut off at the bottom / too much top padding" reports on the embedded
layout. Mirrors the proven chrome-hide pattern in static/v3/index.html
(`html.ss-follower-pre …`), but keeps the sidebar as a functional icon rail
so the user is never trapped (Escape is bound only on player/settings
scopes, not plugin screens). */
html.fb-immersive #v3-topbar { display: none !important; }
/* Sidebar → icon rail: narrow it, drop the wordmark + group headers + labels,
center the remaining icons. The .v3-nav-label / .v3-nav-group hooks are added
by shell.js so these rules don't depend on Tailwind utility class strings. */
html.fb-immersive #v3-sidebar { width: 4.5rem; }
html.fb-immersive #v3-brand { display: none; }
html.fb-immersive #v3-nav { padding-left: .5rem; padding-right: .5rem; }
html.fb-immersive #v3-nav .v3-nav-group,
html.fb-immersive #v3-nav .v3-nav-label { display: none; }
html.fb-immersive #v3-nav a {
justify-content: center;
gap: 0;
padding-left: 0;
padding-right: 0;
}
/* The active plugin screen fills the now-topbar-less content area. #v3-main is
position:relative, so pinning the screen avoids relying on the auto-height
block flow that made a 100vh plugin overflow #v3-main and force a scroll. */
html.fb-immersive #v3-main > .screen.active {
position: absolute;
inset: 0;
overflow: hidden;
}