From 0a48c5c75dd2f7a5033f48ba685ca499fc6e4b2d Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Tue, 15 Sep 2026 10:41:34 +0200 Subject: [PATCH] ui: in tab mode, pause/resume emulator when show/hide emulator tab --- README.md | 21 ++++++++++++--------- src/ide/layout.ts | 6 ++++++ src/ide/ui.ts | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index db01165d..d0a61e84 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,6 @@ Bleeding edge (built from HEAD): * Export ROMs, save screenshots/videos, share playable links, and sync projects to GitHub -Read the [IDE documentation](src/docs/index.md) for a guided tour. - ## Install Locally Requirements: @@ -68,6 +66,14 @@ TypeScript and lezer grammars, and runs esbuild. To use GitHub integration locally, download the Firebase config file, e.g. https://8bitworkshop.com/v[version]/config.js +### Develop with VSCode + +To fix TypeScript errors in VSCode: +* Open any TypeScript file +* Open the command palette (Cmd+Shift+P) +* Select "TypeScript: Select TypeScript Version" +* Select "Use Workspace Version" + ### Start Local Web Server Start a web server on http://localhost:8000/ while TypeScript compiles @@ -241,21 +247,18 @@ distributable replacement images are included — see licenses. To use your own firmware, add it to the project as a binary file named -`.rom` (for example `c64.rom`); the IDE loads it as the +`.rom` (for example `apple2.rom`); the IDE loads it as the BIOS at startup. Only freely distributable firmware should be shared. -* http://www.virtualdub.org/altirra.html +* http://www.virtualdub.org/altirra.html (GPL-2) * https://github.com/MEGA65/open-roms (LGPL-3.0) -* https://sourceforge.net/projects/cbios/ -* https://www.pledgebank.com/opense +* https://sourceforge.net/projects/cbios/ (BSD) ### Related Projects -* https://github.com/sehugg/8bitworkshop-compilers * https://github.com/sehugg/8bit-tools (CC0-1.0) * https://github.com/sehugg/awesome-8bitgamedev (Public Domain) -* https://github.com/sehugg?tab=repositories (CC0-1.0) - +* https://github.com/sehugg/8bitworkshop-compilers ## Tool Server (experimental) diff --git a/src/ide/layout.ts b/src/ide/layout.ts index 3c04c9a8..d039c13b 100644 --- a/src/ide/layout.ts +++ b/src/ide/layout.ts @@ -26,6 +26,8 @@ export interface LayoutHooks { hasLocalStorage: boolean; resizePlatform(): void; resizeWindows(): void; + // tab mode only: the visible pane changed (e.g. 'sidebar', 'editor', 'emulator') + onTabChanged?(tab: string): void; } var hooks: LayoutHooks = null; @@ -77,6 +79,8 @@ function setActiveTabClass(tab: string) { $("#sidebar,#workspace,#emulator").removeClass("active"); var sel = activeTab === 'sidebar' ? '#sidebar' : activeTab === 'emulator' ? '#emulator' : '#workspace'; $(sel).addClass("active"); + // only meaningful in tab mode; on desktop all panes stay visible + if (tabMode && hooks && hooks.onTabChanged) hooks.onTabChanged(activeTab); } function setTabMode(on: boolean) { @@ -109,6 +113,8 @@ function updateSplitLayout() { // leaving tab mode: restore the side-by-side panes and their sizes setTabMode(false); $("#sidebar,#workspace,#emulator").removeClass("active"); + // all panes are visible again; let the emulator resume if a tab hid it + if (hooks && hooks.onTabChanged) hooks.onTabChanged('emulator'); createSplit(desktopSizes || [12, 44, 44]); hooks.resizePlatform(); hooks.resizeWindows(); diff --git a/src/ide/ui.ts b/src/ide/ui.ts index 27179b75..4140fe11 100644 --- a/src/ide/ui.ts +++ b/src/ide/ui.ts @@ -86,6 +86,7 @@ var toolbar = $("#controls_top"); var uitoolbar: Toolbar; var stateRecorder: StateRecorderImpl; var userPaused: boolean; // did user explicitly pause? +var tabPausedEmulator = false; // did a tab switch (mobile tab mode) pause the emulator? var debugSessionActive: boolean; // has the user entered a debug session? (drives debug shortcut chips) var current_output: any; // current ROM (or other object) var current_preset: Preset; // current preset object (if selected) @@ -2475,6 +2476,20 @@ export async function startUI() { hasLocalStorage: hasLocalStorage, resizePlatform: () => { if (platform && platform.resize) platform.resize(); }, resizeWindows: () => { if (projectWindows) projectWindows.resize(); }, + // in tab mode only one pane is visible; pause the emulator when the + // emulator tab isn't on screen, and resume it when it comes back + onTabChanged: (tab) => { + if (!isPlatformReady()) return; + if (tab !== 'emulator') { + if (platform.isRunning()) { + _pause(); + tabPausedEmulator = true; // remember it was us, not the user + } + } else if (tabPausedEmulator) { + tabPausedEmulator = false; + if (!platform.isRunning()) _resume(); + } + }, }); // get store ID, repo id or platform id store_id = repo_id || getBasePlatform(platform_id);