Update xterm to v4 (#3830)

* update xterm to 4

* add back webGL addon

* remove ligatures xterm addon, unused atm and does not work with webGL renderer

* update node-pty

* more work on trying to get xterm4 to work

* update xterm to 4.0.2

* move where xterm addon props are assigned

* more updates

* only load webgl addon if webgl is enabled

* fix search function

* remove rendererType setting, the xterm addon does this for us

* use xcode 10.3 on circleci

* fix typo

* revert node-pty bump for now

* use stable versions of the xterm plugins

* fix focus listener

* add windowsMode prop

* move webGL check

* apply tweaks by @GitSquared

* fix resizing issue

* Revert "fix resizing issue"

This reverts commit fce3780b038d69378f63bdfbfa613f20130fad34.

* apply review suggestions

* change so all addons have separate instances for each terminal

* update yarn-standalone to 1.19

* fix resize problem of split view

by @ivanwonder

* apply review feedback

* fix lint

* add name and version to package.json

* address review feedback

* more review feedback
This commit is contained in:
Benjamin Staneck 2019-10-06 20:51:56 +02:00 committed by GitHub
parent 19644f3fa2
commit 2cc4c9e1ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 78136 additions and 67182 deletions

View file

@ -2,7 +2,7 @@ version: 2
jobs: jobs:
install: install:
macos: macos:
xcode: "9.2.0" xcode: "10.3.0"
working_directory: ~/repo working_directory: ~/repo
steps: steps:
- checkout - checkout
@ -25,7 +25,7 @@ jobs:
test: test:
macos: macos:
xcode: "9.2.0" xcode: "10.3.0"
steps: steps:
- checkout - checkout
- attach_workspace: - attach_workspace:
@ -36,7 +36,7 @@ jobs:
build: build:
macos: macos:
xcode: "9.2.0" xcode: "10.3.0"
steps: steps:
- checkout - checkout
- attach_workspace: - attach_workspace:
@ -53,7 +53,7 @@ jobs:
release: release:
macos: macos:
xcode: "9.2.0" xcode: "10.3.0"
steps: steps:
- checkout - checkout
- attach_workspace: - attach_workspace:

File diff suppressed because one or more lines are too long

View file

@ -57,6 +57,8 @@ class TermGroup_ extends React.PureComponent {
const props = getTermProps(uid, this.props, { const props = getTermProps(uid, this.props, {
isTermActive: uid === this.props.activeSession, isTermActive: uid === this.props.activeSession,
term: termRef ? termRef.term : null, term: termRef ? termRef.term : null,
fitAddon: termRef ? termRef.fitAddon : null,
searchAddon: termRef ? termRef.searchAddon : null,
scrollback: this.props.scrollback, scrollback: this.props.scrollback,
backgroundColor: this.props.backgroundColor, backgroundColor: this.props.backgroundColor,
foregroundColor: this.props.foregroundColor, foregroundColor: this.props.foregroundColor,

View file

@ -1,19 +1,16 @@
import React from 'react'; import React from 'react';
import {Terminal} from 'xterm'; import {Terminal} from 'xterm';
import * as fit from 'xterm/lib/addons/fit/fit'; import {FitAddon} from 'xterm-addon-fit';
import * as webLinks from 'xterm/lib/addons/webLinks/webLinks'; import {WebLinksAddon} from 'xterm-addon-web-links';
import * as search from 'xterm/lib/addons/search/search'; import {SearchAddon} from 'xterm-addon-search';
import * as winptyCompat from 'xterm/lib/addons/winptyCompat/winptyCompat'; import {WebglAddon} from 'xterm-addon-webgl';
import {clipboard} from 'electron'; import {clipboard} from 'electron';
import * as Color from 'color'; import * as Color from 'color';
import terms from '../terms'; import terms from '../terms';
import processClipboard from '../utils/paste'; import processClipboard from '../utils/paste';
import SearchBox from './searchBox'; import SearchBox from './searchBox';
Terminal.applyAddon(fit); const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0;
Terminal.applyAddon(webLinks);
Terminal.applyAddon(winptyCompat);
Terminal.applyAddon(search);
// map old hterm constants to xterm.js // map old hterm constants to xterm.js
const CURSOR_STYLES = { const CURSOR_STYLES = {
@ -39,23 +36,6 @@ const getTermOptions = props => {
const needTransparency = Color(props.backgroundColor).alpha() < 1; const needTransparency = Color(props.backgroundColor).alpha() < 1;
const backgroundColor = needTransparency ? 'transparent' : props.backgroundColor; const backgroundColor = needTransparency ? 'transparent' : props.backgroundColor;
let useWebGL = false;
if (props.webGLRenderer) {
if (needTransparency) {
// eslint-disable-next-line no-console
console.warn(
'WebGL Renderer has been disabled since it does not support transparent backgrounds yet. ' +
'Falling back to canvas-based rendering.'
);
} else if (!isWebgl2Supported()) {
// eslint-disable-next-line no-console
console.warn('WebGL2 is not supported on your machine. Falling back to canvas-based rendering.');
} else {
useWebGL = true;
}
}
Term.reportRenderer(props.uid, useWebGL ? 'WebGL' : 'Canvas');
return { return {
macOptionIsMeta: props.modifierKeys.altIsMeta, macOptionIsMeta: props.modifierKeys.altIsMeta,
scrollback: props.scrollback, scrollback: props.scrollback,
@ -69,12 +49,8 @@ const getTermOptions = props => {
letterSpacing: props.letterSpacing, letterSpacing: props.letterSpacing,
allowTransparency: needTransparency, allowTransparency: needTransparency,
macOptionClickForcesSelection: props.macOptionSelectionMode === 'force', macOptionClickForcesSelection: props.macOptionSelectionMode === 'force',
// HACK: Terminal.setOption breaks if we don't apply these in this order
// TODO: The above notice can be removed once this is addressed:
// https://github.com/xtermjs/xterm.js/pull/1790#issuecomment-450000121
rendererType: useWebGL ? 'webgl' : 'canvas',
experimentalCharAtlas: useWebGL ? 'webgl' : 'dynamic',
bellStyle: props.bell === 'SOUND' ? 'sound' : 'none', bellStyle: props.bell === 'SOUND' ? 'sound' : 'none',
windowsMode: isWindows,
theme: { theme: {
foreground: props.foregroundColor, foreground: props.foregroundColor,
background: backgroundColor, background: backgroundColor,
@ -118,6 +94,8 @@ export default class Term extends React.PureComponent {
this.termOptions = {}; this.termOptions = {};
this.disposableListeners = []; this.disposableListeners = [];
this.termDefaultBellSound = null; this.termDefaultBellSound = null;
this.fitAddon = new FitAddon();
this.searchAddon = new SearchAddon();
} }
// The main process shows this in the About dialog // The main process shows this in the About dialog
@ -145,10 +123,37 @@ export default class Term extends React.PureComponent {
this.termWrapperRef.appendChild(this.termRef); this.termWrapperRef.appendChild(this.termRef);
if (!props.term) { if (!props.term) {
let needTransparency = Color(props.backgroundColor).alpha() < 1;
let useWebGL = false;
if (props.webGLRenderer) {
if (needTransparency) {
// eslint-disable-next-line no-console
console.warn(
'WebGL Renderer has been disabled since it does not support transparent backgrounds yet. ' +
'Falling back to canvas-based rendering.'
);
} else if (!isWebgl2Supported()) {
// eslint-disable-next-line no-console
console.warn('WebGL2 is not supported on your machine. Falling back to canvas-based rendering.');
} else {
// Experimental WebGL renderer needs some more glue-code to make it work on Hyper.
// useWebGL = true;
}
}
Term.reportRenderer(props.uid, useWebGL ? 'WebGL' : 'Canvas');
this.term.attachCustomKeyEventHandler(this.keyboardHandler); this.term.attachCustomKeyEventHandler(this.keyboardHandler);
this.term.loadAddon(this.fitAddon);
this.term.loadAddon(this.searchAddon);
this.term.loadAddon(new WebLinksAddon());
this.term.open(this.termRef); this.term.open(this.termRef);
this.term.webLinksInit(); if (useWebGL) {
this.term.winptyCompatInit(); this.term.loadAddon(new WebglAddon());
}
} else {
// get the cached plugins
this.fitAddon = props.fitAddon;
this.searchAddon = props.searchAddon;
} }
if (this.props.isTermActive) { if (this.props.isTermActive) {
@ -156,28 +161,32 @@ export default class Term extends React.PureComponent {
} }
if (props.onTitle) { if (props.onTitle) {
this.disposableListeners.push(this.term.addDisposableListener('title', props.onTitle)); this.disposableListeners.push(this.term.onTitleChange(props.onTitle));
} }
if (props.onActive) { if (props.onActive) {
this.disposableListeners.push(this.term.addDisposableListener('focus', props.onActive)); this.term.textarea.addEventListener('focus', props.onActive);
this.disposableListeners.push({
dispose: () => this.term.textarea.removeEventListener('focus', this.props.onActive)
});
} }
if (props.onData) { if (props.onData) {
this.disposableListeners.push(this.term.addDisposableListener('data', props.onData)); this.disposableListeners.push(this.term.onData(props.onData));
} }
if (props.onResize) { if (props.onResize) {
this.disposableListeners.push( this.disposableListeners.push(
this.term.addDisposableListener('resize', ({cols, rows}) => { this.term.onResize(({cols, rows}) => {
props.onResize(cols, rows); props.onResize(cols, rows);
}) })
); );
this.fitAddon.fit();
} }
if (props.onCursorMove) { if (props.onCursorMove) {
this.disposableListeners.push( this.disposableListeners.push(
this.term.addDisposableListener('cursormove', () => { this.term.onCursorMove(() => {
const cursorFrame = { const cursorFrame = {
x: this.term._core.buffer.x * this.term._core.renderer.dimensions.actualCellWidth, x: this.term._core.buffer.x * this.term._core.renderer.dimensions.actualCellWidth,
y: this.term._core.buffer.y * this.term._core.renderer.dimensions.actualCellHeight, y: this.term._core.buffer.y * this.term._core.renderer.dimensions.actualCellHeight,
@ -253,15 +262,15 @@ export default class Term extends React.PureComponent {
} }
search(searchTerm) { search(searchTerm) {
this.term.findNext(searchTerm); this.searchAddon.findNext(searchTerm);
} }
searchNext(searchTerm) { searchNext(searchTerm) {
this.term.findNext(searchTerm); this.searchAddon.findNext(searchTerm);
} }
searchPrevious(searchTerm) { searchPrevious(searchTerm) {
this.term.findPrevious(searchTerm); this.searchAddon.findPrevious(searchTerm);
} }
closeSearchBox() { closeSearchBox() {
@ -270,6 +279,7 @@ export default class Term extends React.PureComponent {
resize(cols, rows) { resize(cols, rows) {
this.term.resize(cols, rows); this.term.resize(cols, rows);
this.fitAddon.fit();
} }
selectAll() { selectAll() {
@ -280,7 +290,7 @@ export default class Term extends React.PureComponent {
if (!this.termWrapperRef) { if (!this.termWrapperRef) {
return; return;
} }
this.term.fit(); this.fitAddon.fit();
} }
keyboardHandler(e) { keyboardHandler(e) {
@ -288,7 +298,7 @@ export default class Term extends React.PureComponent {
return !e.catched; return !e.catched;
} }
componentWillReceiveProps(nextProps) { UNSAFE_componentWillReceiveProps(nextProps) {
if (!this.props.cleared && nextProps.cleared) { if (!this.props.cleared && nextProps.cleared) {
this.clear(); this.clear();
} }

View file

@ -1,4 +1,6 @@
{ {
"name": "hyper",
"version": "3.0.1-canary.4",
"repository": "zeit/hyper", "repository": "zeit/hyper",
"scripts": { "scripts": {
"start": "echo 'please run `yarn run dev` in one tab and then `yarn run app` in another one'", "start": "echo 'please run `yarn run dev` in one tab and then `yarn run app` in another one'",
@ -256,7 +258,11 @@
"stylis": "3.5.0", "stylis": "3.5.0",
"uuid": "3.1.0", "uuid": "3.1.0",
"webpack-cli": "3.3.7", "webpack-cli": "3.3.7",
"xterm": "https://registry.npmjs.org/@zeit/xterm/-/xterm-3.12.0-1.tgz" "xterm": "~4.0.2",
"xterm-addon-fit": "^0.2.1",
"xterm-addon-search": "^0.2.1",
"xterm-addon-webgl": "^0.2.1",
"xterm-addon-web-links": "^0.2.1"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "7.5.5", "@babel/cli": "7.5.5",

View file

@ -8971,9 +8971,30 @@ xtend@~2.1.1:
dependencies: dependencies:
object-keys "~0.4.0" object-keys "~0.4.0"
"xterm@https://registry.npmjs.org/@zeit/xterm/-/xterm-3.12.0-1.tgz": xterm-addon-fit@^0.2.1:
version "3.12.0-1" version "0.2.1"
resolved "https://registry.npmjs.org/@zeit/xterm/-/xterm-3.12.0-1.tgz#df7bb98fe53d621c0bfd559d0ae87be401c8f246" resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.2.1.tgz#353f43921eb78e3f9ad3f3afbb14e7ac183ca738"
integrity sha512-BlR57O3t1/bmVcnS81bn9ZnNf+GiGNbeXdNUKSBa9tKEwNUMcU3S+KFLIRv7rm1Ty0D5pMOu0vbz/RDorKRwKQ==
xterm-addon-search@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.1.tgz#f2c02fa92198d5115bde5cc518bff9d7998f2b9c"
integrity sha512-zT2TD0szNIgYYMJuCXMyjY2oF5YzhJ4QqKDO/KyPCm+d67x/7DvPxcg4DWkrPHhBc14jvo0iaTqpdPnSAUvhgg==
xterm-addon-web-links@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.2.1.tgz#6d1f2ce613e09870badf17615e7a1170a31542b2"
integrity sha512-2KnHtiq0IG7hfwv3jw2/jQeH1RBk2d5CH4zvgwQe00rLofSJqSfgnJ7gwowxxpGHrpbPr6Lv4AmH/joaNw2+HQ==
xterm-addon-webgl@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.2.1.tgz#86452460601dc29b7d907dbcd0b8a058bcbc6bcf"
integrity sha512-MZyh/KGbOBEEOqGpgilHuKHSj0OCXiZsBedTtLesHNerc79710shUHnfBlk31ggYU9G/WJ91qoNNux3ek5QBPA==
xterm@~4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.0.2.tgz#c6a1b9586c0786627625e2ee9e78ad519dbc8c99"
integrity sha512-NIr11b6C782TZznU8e6K/IMfmwlWMWRI6ba9GEDG9uX25SadkpjoMnzvxOS0Z/15sfrbn0rghPiarGDmmP0uhQ==
y18n@^3.2.1: y18n@^3.2.1:
version "3.2.1" version "3.2.1"