mirror of
https://github.com/weaveworks/scope.git
synced 2026-05-06 01:08:03 +00:00
Merge pull request #3179 from weaveworks/3178-fix-terminal-viewport
Adjusted terminal character width/height estimation
This commit is contained in:
@@ -5,6 +5,7 @@ import { connect } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import { debounce } from 'lodash';
|
||||
import { Terminal as Term } from 'xterm';
|
||||
import * as fit from 'xterm/lib/addons/fit/fit';
|
||||
|
||||
import { closeTerminal } from '../actions/app-actions';
|
||||
import { getNeutralColor } from '../utils/color-utils';
|
||||
@@ -30,32 +31,6 @@ function ab2str(buf) {
|
||||
return decodedString;
|
||||
}
|
||||
|
||||
function terminalCellSize(wrapperNode) {
|
||||
// Badly guess the width/height of the row.
|
||||
let characterWidth = 20;
|
||||
let characterHeight = 20;
|
||||
|
||||
// Now try and measure the first row we find.
|
||||
const subjectRow = wrapperNode.querySelector('.terminal .xterm-rows div');
|
||||
if (!subjectRow) {
|
||||
log("ERROR: Couldn't find first row, resizing might not work very well.");
|
||||
} else {
|
||||
const rowDisplay = subjectRow.style.display;
|
||||
const contentBuffer = subjectRow.innerHTML;
|
||||
|
||||
subjectRow.innerHTML = 'W';
|
||||
subjectRow.style.display = 'inline';
|
||||
characterWidth = subjectRow.getBoundingClientRect().width;
|
||||
subjectRow.style.display = rowDisplay;
|
||||
characterHeight = parseInt(subjectRow.offsetHeight, 10);
|
||||
subjectRow.innerHTML = contentBuffer;
|
||||
}
|
||||
|
||||
log('Calculated (charWidth, charHeight) sizes in px: ', characterWidth, characterHeight);
|
||||
return {characterWidth, characterHeight};
|
||||
}
|
||||
|
||||
|
||||
function openNewWindow(url, bcr, minWidth = 200) {
|
||||
const screenLeft = window.screenX || window.screenLeft;
|
||||
const screenTop = window.screenY || window.screenTop;
|
||||
@@ -89,8 +64,6 @@ class Terminal extends React.Component {
|
||||
detached: false,
|
||||
rows: DEFAULT_ROWS,
|
||||
cols: DEFAULT_COLS,
|
||||
characterWidth: 0,
|
||||
characterHeight: 0
|
||||
};
|
||||
|
||||
this.handleCloseClick = this.handleCloseClick.bind(this);
|
||||
@@ -171,9 +144,8 @@ class Terminal extends React.Component {
|
||||
}
|
||||
|
||||
mountTerminal() {
|
||||
Term.applyAddon(fit);
|
||||
this.term = new Term({
|
||||
cols: this.state.cols,
|
||||
rows: this.state.rows,
|
||||
convertEol: !this.props.pipe.get('raw'),
|
||||
cursorBlink: true,
|
||||
scrollback: 10000,
|
||||
@@ -188,17 +160,19 @@ class Terminal extends React.Component {
|
||||
}
|
||||
});
|
||||
|
||||
this.createWebsocket(this.term);
|
||||
this.term.on('resize', ({ cols, rows }) => {
|
||||
const resizeTtyControl = this.props.pipe.get('resizeTtyControl');
|
||||
if (resizeTtyControl) {
|
||||
doResizeTty(this.getPipeId(), resizeTtyControl, cols, rows);
|
||||
}
|
||||
this.setState({ cols, rows });
|
||||
});
|
||||
|
||||
const {characterWidth, characterHeight} = terminalCellSize(this.term.element);
|
||||
this.createWebsocket(this.term);
|
||||
|
||||
window.addEventListener('resize', this.handleResizeDebounced);
|
||||
|
||||
this.resizeTimeout = setTimeout(() => {
|
||||
this.setState({
|
||||
characterWidth,
|
||||
characterHeight
|
||||
});
|
||||
this.handleResize();
|
||||
}, 10);
|
||||
}
|
||||
@@ -231,14 +205,7 @@ class Terminal extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const sizeChanged = (
|
||||
prevState.cols !== this.state.cols ||
|
||||
prevState.rows !== this.state.rows
|
||||
);
|
||||
if (sizeChanged) {
|
||||
this.term.resize(this.state.cols, this.state.rows);
|
||||
}
|
||||
componentDidUpdate() {
|
||||
if (!this.isEmbedded()) {
|
||||
setDocumentTitle(this.getTitle());
|
||||
}
|
||||
@@ -256,24 +223,11 @@ class Terminal extends React.Component {
|
||||
this.setState({detached: true});
|
||||
|
||||
const bcr = this.node.getBoundingClientRect();
|
||||
const minWidth = (this.state.characterWidth * 80) + (8 * 2);
|
||||
openNewWindow(`${basePath(window.location.pathname)}/terminal.html#!/state/${paramString}`, bcr, minWidth);
|
||||
openNewWindow(`${basePath(window.location.pathname)}/terminal.html#!/state/${paramString}`, bcr);
|
||||
}
|
||||
|
||||
handleResize() {
|
||||
// scrollbar === 16px
|
||||
const width = this.innerFlex.clientWidth - (2 * 8) - 16;
|
||||
const height = this.innerFlex.clientHeight - (2 * 8);
|
||||
const cols = Math.floor(width / this.state.characterWidth);
|
||||
const rows = Math.floor(height / this.state.characterHeight);
|
||||
|
||||
const resizeTtyControl = this.props.pipe.get('resizeTtyControl');
|
||||
if (resizeTtyControl) {
|
||||
doResizeTty(this.getPipeId(), resizeTtyControl, cols, rows)
|
||||
.then(() => this.setState({cols, rows}));
|
||||
} else if (!this.props.pipe.get('raw')) {
|
||||
this.setState({cols, rows});
|
||||
}
|
||||
this.term.fit();
|
||||
}
|
||||
|
||||
isEmbedded() {
|
||||
@@ -352,9 +306,6 @@ class Terminal extends React.Component {
|
||||
opacity: this.state.connected ? 1 : 0.8,
|
||||
overflow: 'hidden',
|
||||
};
|
||||
const innerStyle = {
|
||||
width: (this.state.cols + 2) * this.state.characterWidth
|
||||
};
|
||||
const innerClassName = classNames('terminal-inner hideable', {
|
||||
'terminal-inactive': !this.state.connected
|
||||
});
|
||||
@@ -362,9 +313,7 @@ class Terminal extends React.Component {
|
||||
return (
|
||||
<div className="terminal-wrapper" ref={this.saveNodeRef}>
|
||||
{this.isEmbedded() && this.getTerminalHeader()}
|
||||
<div className={innerClassName} style={innerFlexStyle} ref={this.saveInnerFlexRef}>
|
||||
<div style={innerStyle} />
|
||||
</div>
|
||||
<div className={innerClassName} style={innerFlexStyle} ref={this.saveInnerFlexRef} />
|
||||
{this.getTerminalStatusBar()}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1303,6 +1303,7 @@ a {
|
||||
right: 0;
|
||||
background-color: $color-black;
|
||||
padding: 8px;
|
||||
box-sizing: content-box;
|
||||
border-bottom-left-radius: $border-radius-soft;
|
||||
|
||||
.terminal {
|
||||
|
||||
Reference in New Issue
Block a user