Skip to content

Commit

Permalink
fix: fix terminal resize when hidden (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
UziTech committed Aug 5, 2020
1 parent c2a3dcb commit 025cd5d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
38 changes: 38 additions & 0 deletions spec/element-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ describe('XTerminalElement', () => {
['removeItem', 'getActiveItem', 'destroyItem'])
const element = new XTerminalElement()
await element.initialize(model)
await element.createTerminal()
return element
}

Expand Down Expand Up @@ -1592,13 +1593,31 @@ describe('XTerminalElement', () => {

it('refitTerminal() terminal not visible', () => {
spyOn(this.element.fitAddon, 'proposeDimensions')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = false
this.element.refitTerminal()
expect(this.element.fitAddon.proposeDimensions).not.toHaveBeenCalled()
})

it('refitTerminal() terminal no width', () => {
spyOn(this.element.fitAddon, 'proposeDimensions')
this.element.mainDivContentRect = { width: 0, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.refitTerminal()
expect(this.element.fitAddon.proposeDimensions).not.toHaveBeenCalled()
})

it('refitTerminal() terminal no height', () => {
spyOn(this.element.fitAddon, 'proposeDimensions')
this.element.mainDivContentRect = { width: 1, height: 0 }
this.element.terminalDivInitiallyVisible = true
this.element.refitTerminal()
expect(this.element.fitAddon.proposeDimensions).not.toHaveBeenCalled()
})

it('refitTerminal() terminal completely visible', () => {
spyOn(this.element.fitAddon, 'proposeDimensions').and.returnValue(null)
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.refitTerminal()
expect(this.element.fitAddon.proposeDimensions).toHaveBeenCalled()
Expand All @@ -1610,6 +1629,7 @@ describe('XTerminalElement', () => {
rows: this.element.terminal.rows,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = false
this.element.refitTerminal()
Expand All @@ -1622,6 +1642,7 @@ describe('XTerminalElement', () => {
rows: this.element.terminal.rows,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = false
this.element.refitTerminal()
Expand All @@ -1634,6 +1655,7 @@ describe('XTerminalElement', () => {
rows: this.element.terminal.rows + 1,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = false
this.element.refitTerminal()
Expand All @@ -1646,6 +1668,7 @@ describe('XTerminalElement', () => {
rows: this.element.terminal.rows + 1,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = false
this.element.refitTerminal()
Expand All @@ -1658,6 +1681,7 @@ describe('XTerminalElement', () => {
rows: this.element.terminal.rows - 1,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = false
this.element.refitTerminal()
Expand All @@ -1670,6 +1694,7 @@ describe('XTerminalElement', () => {
rows: this.element.terminal.rows - 1,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = false
this.element.refitTerminal()
Expand All @@ -1682,6 +1707,7 @@ describe('XTerminalElement', () => {
rows: this.element.ptyProcessRows,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1694,6 +1720,7 @@ describe('XTerminalElement', () => {
rows: this.element.ptyProcessRows,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1706,6 +1733,7 @@ describe('XTerminalElement', () => {
rows: this.element.ptyProcessRows + 1,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1718,6 +1746,7 @@ describe('XTerminalElement', () => {
rows: this.element.ptyProcessRows + 1,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1730,6 +1759,7 @@ describe('XTerminalElement', () => {
rows: this.element.ptyProcessRows,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1742,6 +1772,7 @@ describe('XTerminalElement', () => {
rows: this.element.ptyProcessRows - 1,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1754,6 +1785,7 @@ describe('XTerminalElement', () => {
rows: this.element.ptyProcessRows - 1,
})
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1767,6 +1799,7 @@ describe('XTerminalElement', () => {
}
spyOn(this.element.fitAddon, 'proposeDimensions').and.returnValue(expected)
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1780,6 +1813,7 @@ describe('XTerminalElement', () => {
}
spyOn(this.element.fitAddon, 'proposeDimensions').and.returnValue(expected)
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1793,6 +1827,7 @@ describe('XTerminalElement', () => {
}
spyOn(this.element.fitAddon, 'proposeDimensions').and.returnValue(expected)
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1806,6 +1841,7 @@ describe('XTerminalElement', () => {
}
spyOn(this.element.fitAddon, 'proposeDimensions').and.returnValue(expected)
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1819,6 +1855,7 @@ describe('XTerminalElement', () => {
}
spyOn(this.element.fitAddon, 'proposeDimensions').and.returnValue(expected)
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand All @@ -1832,6 +1869,7 @@ describe('XTerminalElement', () => {
}
spyOn(this.element.fitAddon, 'proposeDimensions').and.returnValue(expected)
spyOn(this.element.terminal, 'resize')
this.element.mainDivContentRect = { width: 1, height: 1 }
this.element.terminalDivInitiallyVisible = true
this.element.ptyProcessRunning = true
this.element.refitTerminal()
Expand Down
22 changes: 14 additions & 8 deletions src/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class XTerminalElementImpl extends HTMLElement {
this.atomXtermProfileMenuElement = new XTerminalProfileMenuElement()
this.hoveredLink = null
this.pendingTerminalProfileOptions = {}
this.mainDivContentRect = null
this.terminalDivInitiallyVisible = false
this.isInitialized = false
let resolveInit, rejectInit
Expand All @@ -85,11 +86,12 @@ class XTerminalElementImpl extends HTMLElement {
this.setAttribute('session-id', this.model.getSessionId())
await this.atomXtermProfileMenuElement.initialize(new XTerminalProfileMenuModel(this.model))
this.menuDiv.append(this.atomXtermProfileMenuElement)
await this.createTerminal()
// An element resize detector is used to check when this element is
// resized due to the pane resizing or due to the entire window
// resizing.
this.mainDivResizeObserver = new ResizeObserver((entries, observer) => {
this.mainDivResizeObserver = new ResizeObserver(entries => {
const lastEntry = entries.pop()
this.mainDivContentRect = lastEntry.contentRect
this.refitTerminal()
})
this.mainDivResizeObserver.observe(this.mainDiv)
Expand All @@ -99,12 +101,11 @@ class XTerminalElementImpl extends HTMLElement {
}))
// Add an IntersectionObserver in order to apply new options and
// refit as soon as the terminal is visible.
this.terminalDivIntersectionObserver = new IntersectionObserver((entries, observer) => {
// NOTE: Only the terminal div should be observed therefore there
// should only be one entry.
const visible = entries.some(e => e.intersectionRatio === 1.0)
if (visible) {
this.terminalDivIntersectionObserver = new IntersectionObserver(async entries => {
const lastEntry = entries.pop()
if (lastEntry.intersectionRatio === 1.0) {
this.terminalDivInitiallyVisible = true
await this.createTerminal()
this.applyPendingTerminalProfileOptions()
// Remove observer once visible
this.terminalDivIntersectionObserver.disconnect()
Expand Down Expand Up @@ -678,7 +679,12 @@ class XTerminalElementImpl extends HTMLElement {

refitTerminal () {
// Only refit the terminal when it is completely visible.
if (this.terminalDivInitiallyVisible) {
if (
this.terminalDivInitiallyVisible &&
this.mainDivContentRect &&
this.mainDivContentRect.width > 0 &&
this.mainDivContentRect.height > 0
) {
this.fitAddon.fit()
const geometry = this.fitAddon.proposeDimensions()
if (geometry && this.isPtyProcessRunning()) {
Expand Down

0 comments on commit 025cd5d

Please sign in to comment.