fix(terminal): use display:none instead of visibility for tab hiding

Replace visibility-based hiding with display property for reliable tab
detection. Use offsetParent and offsetHeight checks instead of style
properties to properly detect hidden terminals.

💘 Generated with Crush

Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
This commit is contained in:
Augustin
2026-04-24 17:23:54 +02:00
parent a994749dcf
commit e6da61f460
2 changed files with 10 additions and 16 deletions

View File

@@ -400,7 +400,7 @@ export default function Shell({ api }) {
const onResize = () => { const onResize = () => {
const el = document.getElementById(`terminal-${tabId}`) const el = document.getElementById(`terminal-${tabId}`)
if (el && el.style.visibility !== 'hidden' && el.style.position !== 'absolute') { if (el && el.style.display !== 'none') {
fitAddon.fit() fitAddon.fit()
} }
} }
@@ -438,25 +438,23 @@ export default function Shell({ api }) {
const tryInit = (attempt) => { const tryInit = (attempt) => {
if (cancelled || attempt > 20) return if (cancelled || attempt > 20) return
const shellCol = document.querySelector('.shell-terminal-col') const shellCol = document.querySelector('.shell-terminal-col')
if (!shellCol) { if (!shellCol || shellCol.offsetParent === null) {
pending.push(setTimeout(() => tryInit(attempt + 1), 150)) pending.push(setTimeout(() => tryInit(attempt + 1), 150))
return return
} }
const container = document.getElementById(`terminal-${tab.id}`) const container = document.getElementById(`terminal-${tab.id}`)
if (!container) { if (!container || container.offsetHeight === 0) {
pending.push(setTimeout(() => tryInit(attempt + 1), 100)) pending.push(setTimeout(() => tryInit(attempt + 1), 100))
return return
} }
if (!tabsRef.current[tab.id]) { if (!tabsRef.current[tab.id]) {
initTerminal(tab.id, tab) initTerminal(tab.id, tab)
} }
if (activeTab === tab.id) { requestAnimationFrame(() => {
requestAnimationFrame(() => { if (cancelled) return
if (cancelled) return const entry = tabsRef.current[tab.id]
const entry = tabsRef.current[tab.id] if (entry) entry.fitAddon.fit()
if (entry) entry.fitAddon.fit() })
})
}
} }
tryInit(0) tryInit(0)
@@ -472,7 +470,7 @@ export default function Shell({ api }) {
const entry = tabsRef.current[tab.id] const entry = tabsRef.current[tab.id]
if (entry) { if (entry) {
const el = document.getElementById(`terminal-${tab.id}`) const el = document.getElementById(`terminal-${tab.id}`)
if (el && el.style.visibility !== 'hidden') { if (el && el.style.display !== 'none') {
entry.fitAddon.fit() entry.fitAddon.fit()
} }
} }
@@ -841,10 +839,7 @@ export default function Shell({ api }) {
key={tab.id} key={tab.id}
id={`terminal-${tab.id}`} id={`terminal-${tab.id}`}
className="shell-xterm-instance" className="shell-xterm-instance"
style={activeTab === tab.id style={{ display: activeTab === tab.id ? 'block' : 'none' }}
? { visibility: 'visible', pointerEvents: 'auto' }
: { visibility: 'hidden', pointerEvents: 'none' }
}
/> />
))} ))}
</div> </div>

View File

@@ -385,7 +385,6 @@ input::placeholder { color: var(--text-disabled); }
.shell-xterm-wrapper { flex: 1; background: var(--bg); overflow: hidden; position: relative; } .shell-xterm-wrapper { flex: 1; background: var(--bg); overflow: hidden; position: relative; }
.shell-xterm-instance { .shell-xterm-instance {
position: absolute; inset: 0; padding: 4px; position: absolute; inset: 0; padding: 4px;
display: block !important;
} }
.shell-xterm-instance .xterm { height: 100%; padding: 4px; } .shell-xterm-instance .xterm { height: 100%; padding: 4px; }