mirror of
https://github.com/stablyai/orca
synced 2026-04-21 14:17:16 +00:00
fix: free WebGL contexts for hidden worktrees to prevent terminal dying (#777)
This commit is contained in:
parent
9962655492
commit
2d755ba386
3 changed files with 22 additions and 4 deletions
|
|
@ -21,6 +21,7 @@ const EditorPanel = lazy(() => import('../editor/EditorPanel'))
|
|||
export default function TabGroupPanel({
|
||||
groupId,
|
||||
worktreeId,
|
||||
isWorktreeActive,
|
||||
isFocused,
|
||||
hasSplitGroups,
|
||||
reserveClosedExplorerToggleSpace,
|
||||
|
|
@ -30,6 +31,7 @@ export default function TabGroupPanel({
|
|||
}: {
|
||||
groupId: string
|
||||
worktreeId: string
|
||||
isWorktreeActive: boolean
|
||||
isFocused: boolean
|
||||
hasSplitGroups: boolean
|
||||
reserveClosedExplorerToggleSpace: boolean
|
||||
|
|
@ -281,8 +283,15 @@ export default function TabGroupPanel({
|
|||
// Why: in multi-group splits, the active terminal in each group
|
||||
// must remain visible (display:flex) so the user sees its output,
|
||||
// but only the focused group's terminal should receive keyboard
|
||||
// input. isVisible controls rendering; isActive controls focus.
|
||||
isVisible={activeTab?.id === item.id && activeTab.contentType === 'terminal'}
|
||||
// input. Hidden worktrees stay mounted offscreen, so `isVisible`
|
||||
// must also respect worktree visibility or those detached panes
|
||||
// keep their WebGL renderers alive and exhaust Chromium's context
|
||||
// budget across worktrees.
|
||||
isVisible={
|
||||
isWorktreeActive &&
|
||||
activeTab?.id === item.id &&
|
||||
activeTab.contentType === 'terminal'
|
||||
}
|
||||
onPtyExit={(ptyId) => {
|
||||
if (commands.consumeSuppressedPtyExit(ptyId)) {
|
||||
return
|
||||
|
|
@ -319,9 +328,14 @@ export default function TabGroupPanel({
|
|||
<div
|
||||
key={bt.id}
|
||||
className="absolute inset-0 flex min-h-0 min-w-0"
|
||||
style={{ display: activeBrowserTab?.id === bt.id ? undefined : 'none' }}
|
||||
style={{
|
||||
display: isWorktreeActive && activeBrowserTab?.id === bt.id ? undefined : 'none'
|
||||
}}
|
||||
>
|
||||
<BrowserPane browserTab={bt} isActive={activeBrowserTab?.id === bt.id} />
|
||||
<BrowserPane
|
||||
browserTab={bt}
|
||||
isActive={isWorktreeActive && activeBrowserTab?.id === bt.id}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ describe('TabGroupSplitLayout', () => {
|
|||
return tabGroupPanelElement.props as {
|
||||
groupId: string
|
||||
worktreeId: string
|
||||
isWorktreeActive: boolean
|
||||
isFocused: boolean
|
||||
hasSplitGroups: boolean
|
||||
reserveClosedExplorerToggleSpace: boolean
|
||||
|
|
@ -56,6 +57,7 @@ describe('TabGroupSplitLayout', () => {
|
|||
expect.objectContaining({
|
||||
groupId: 'group-1',
|
||||
worktreeId: 'wt-1',
|
||||
isWorktreeActive: false,
|
||||
isFocused: false,
|
||||
hasSplitGroups: false,
|
||||
reserveClosedExplorerToggleSpace: true,
|
||||
|
|
@ -69,6 +71,7 @@ describe('TabGroupSplitLayout', () => {
|
|||
expect.objectContaining({
|
||||
groupId: 'group-1',
|
||||
worktreeId: 'wt-1',
|
||||
isWorktreeActive: true,
|
||||
isFocused: true,
|
||||
hasSplitGroups: false,
|
||||
reserveClosedExplorerToggleSpace: true,
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ function SplitNode({
|
|||
<TabGroupPanel
|
||||
groupId={node.groupId}
|
||||
worktreeId={worktreeId}
|
||||
isWorktreeActive={isWorktreeActive}
|
||||
// Why: hidden worktrees stay mounted so their PTYs and split layouts
|
||||
// survive worktree switches, but only the visible worktree may own the
|
||||
// global terminal shortcuts. If an offscreen group's pane stays
|
||||
|
|
|
|||
Loading…
Reference in a new issue