Description
The app crashes when the total number of terminal panes across all tabs exceeds approximately 4-6. The maxPanes config is enforced per-tab (capped at 4), but there is no global limit across tabs.
Reproduction
- Open 2 tabs, each with 2 split panes (4 terminals total — works fine)
- Create a 3rd tab and split it into 2 panes (6 terminals total)
- App crashes
Root Cause
Each Pane loads a WebglAddon for xterm.js rendering, consuming a GPU WebGL context. Hidden tabs do not release their WebGL contexts when switched away from (the addon stays loaded). Tauri's WebKit webview has a lower WebGL context limit than Chromium (~8-16), so 6+ simultaneous contexts can exhaust the limit.
The try/catch in pane.ts:289-304 handles WebGL loading failures gracefully, but does not protect against mid-session context exhaustion or native-layer crashes.
Possible Fixes
- Dispose WebGL addon on
tab.hide() and re-create it on tab.show() — keeps only the active tab's panes using WebGL
- Add a global pane counter that caps total panes across all tabs (not just per-tab)
- Lazy-load WebGL only for the active tab, fall back to canvas renderer for background tabs
- Dispose the
ImageAddon on hidden tabs as well (it may also consume a WebGL context)
Environment
- macOS (Darwin 25.1.0)
- Tauri v2 (WebKit webview)
Reported by @axel
Description
The app crashes when the total number of terminal panes across all tabs exceeds approximately 4-6. The
maxPanesconfig is enforced per-tab (capped at 4), but there is no global limit across tabs.Reproduction
Root Cause
Each
Paneloads aWebglAddonfor xterm.js rendering, consuming a GPU WebGL context. Hidden tabs do not release their WebGL contexts when switched away from (the addon stays loaded). Tauri's WebKit webview has a lower WebGL context limit than Chromium (~8-16), so 6+ simultaneous contexts can exhaust the limit.The try/catch in
pane.ts:289-304handles WebGL loading failures gracefully, but does not protect against mid-session context exhaustion or native-layer crashes.Possible Fixes
tab.hide()and re-create it ontab.show()— keeps only the active tab's panes using WebGLImageAddonon hidden tabs as well (it may also consume a WebGL context)Environment
Reported by @axel