From 7a40fd7c97c52c5f1745a8ca8e5b7a4809b17ff9 Mon Sep 17 00:00:00 2001 From: Juan Campa Date: Fri, 28 Dec 2018 17:42:05 -0500 Subject: [PATCH] WebGL renderer (using xterm.js fork) (#3368) * Enabling webGL renderer * Use @zeit/xterm fork of xterm * Adding webGLRenderer config * Fix linting issues * Allow for hot-reloading of webGLRenderer * Adding link to WebGL renderer issue we're working around * Using NPM tarball instead of resolutions (which wasn't working * Hard-coding selection color to white because nothing else is yet supported --- app/config/config-default.js | 2 ++ lib/components/term-group.js | 1 + lib/components/term.js | 25 ++++++++++++++++++++++--- lib/components/terms.js | 1 + lib/containers/terms.js | 3 ++- lib/reducers/ui.js | 7 ++++++- package.json | 2 +- yarn.lock | 5 ++--- 8 files changed, 37 insertions(+), 9 deletions(-) diff --git a/app/config/config-default.js b/app/config/config-default.js index 7d3ce3190eb6..9badfb52493b 100644 --- a/app/config/config-default.js +++ b/app/config/config-default.js @@ -144,6 +144,8 @@ module.exports = { // to load it and avoid it being `npm install`ed localPlugins: [], + webGLRenderer: true, + keymaps: { // Example // 'window:devtools': 'cmd+alt+o', diff --git a/lib/components/term-group.js b/lib/components/term-group.js index 328f959b4f99..319c2ded1c6b 100644 --- a/lib/components/term-group.js +++ b/lib/components/term-group.js @@ -92,6 +92,7 @@ class TermGroup_ extends React.PureComponent { borderColor: this.props.borderColor, selectionColor: this.props.selectionColor, quickEdit: this.props.quickEdit, + webGLRenderer: this.props.webGLRenderer, uid }); diff --git a/lib/components/term.js b/lib/components/term.js index 8bbd4c73e6d8..d95429ec8ddd 100644 --- a/lib/components/term.js +++ b/lib/components/term.js @@ -36,13 +36,21 @@ const getTermOptions = props => { lineHeight: props.lineHeight, letterSpacing: props.letterSpacing, allowTransparency: needTransparency, - experimentalCharAtlas: 'dynamic', + // 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: props.webGLRenderer ? 'webgl' : 'canvas', + experimentalCharAtlas: props.webGLRenderer ? 'webgl' : 'dynamic', theme: { foreground: props.foregroundColor, background: backgroundColor, cursor: props.cursorColor, cursorAccent: props.cursorAccentColor, - selection: props.selectionColor, + // TODO: This hard codes the selection color to opaque white because the + // webgl renderer doesn't support anything else at the moment. Remove this + // once WebGL gets support for selection color. Discussed here: + // https://github.com/xtermjs/xterm.js/pull/1790 + selection: props.webGLRenderer ? '#fff' : props.selectionColor, black: props.colors.black, red: props.colors.red, green: props.colors.green, @@ -243,11 +251,22 @@ export default class Term extends React.PureComponent { // Update only options that have changed. Object.keys(nextTermOptions) .filter(option => option !== 'theme' && nextTermOptions[option] !== this.termOptions[option]) - .forEach(option => this.term.setOption(option, nextTermOptions[option])); + .forEach(option => { + try { + this.term.setOption(option, nextTermOptions[option]); + } catch (e) { + if (/The webgl renderer only works with the webgl char atlas/i.test(e.message)) { + // Ignore this because the char atlas will also be changed + } else { + throw e; + } + } + }); // Do we need to update theme? const shouldUpdateTheme = !this.termOptions.theme || + nextTermOptions.rendererType !== this.termOptions.rendererType || Object.keys(nextTermOptions.theme).some( option => nextTermOptions.theme[option] !== this.termOptions.theme[option] ); diff --git a/lib/components/terms.js b/lib/components/terms.js index 0d8a36b1a448..88921b7a1558 100644 --- a/lib/components/terms.js +++ b/lib/components/terms.js @@ -116,6 +116,7 @@ export default class Terms extends React.Component { onURLAbort: this.props.onURLAbort, onContextMenu: this.props.onContextMenu, quickEdit: this.props.quickEdit, + webGLRenderer: this.props.webGLRenderer, parentProps: this.props }); diff --git a/lib/containers/terms.js b/lib/containers/terms.js index 30671dd3f5a2..24a83cd3fa1f 100644 --- a/lib/containers/terms.js +++ b/lib/containers/terms.js @@ -45,7 +45,8 @@ const TermsContainer = connect( bellSoundURL: state.ui.bellSoundURL, copyOnSelect: state.ui.copyOnSelect, modifierKeys: state.ui.modifierKeys, - quickEdit: state.ui.quickEdit + quickEdit: state.ui.quickEdit, + webGLRenderer: state.ui.webGLRenderer }; }, dispatch => { diff --git a/lib/reducers/ui.js b/lib/reducers/ui.js index 5627154f69d7..ac1363b3280f 100644 --- a/lib/reducers/ui.js +++ b/lib/reducers/ui.js @@ -96,7 +96,8 @@ const initial = Immutable({ }, showHamburgerMenu: '', showWindowControls: '', - quickEdit: false + quickEdit: false, + webGLRenderer: true }); const currentWindow = remote.getCurrentWindow(); @@ -237,6 +238,10 @@ const reducer = (state = initial, action) => { ret.quickEdit = config.quickEdit; } + if (typeof config.webGLRenderer !== undefined) { + ret.webGLRenderer = config.webGLRenderer; + } + ret._lastUpdate = now; return ret; diff --git a/package.json b/package.json index eedda3d62963..147f2de07e50 100644 --- a/package.json +++ b/package.json @@ -207,7 +207,7 @@ "styled-jsx": "2.2.6", "stylis": "3.5.0", "uuid": "3.1.0", - "xterm": "3.9.1" + "xterm": "https://registry.npmjs.org/@zeit/xterm/-/xterm-3.9.1.tgz" }, "devDependencies": { "ava": "0.25.0", diff --git a/yarn.lock b/yarn.lock index 90cfb32ffae9..5182d23e54c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7111,10 +7111,9 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -xterm@3.9.1: +"xterm@https://registry.npmjs.org/@zeit/xterm/-/xterm-3.9.1.tgz": version "3.9.1" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.9.1.tgz#65756beb09bb6fb44aeb29032adcd6789aaaa5f4" - integrity sha512-5AZlhP0jvH/Sskx1UvvNFMqDRHVFqapl59rjV3RRpTJmveoharJplxPfzSThk85I4+AZo2xvD0X0nh0AAzkeZQ== + resolved "https://registry.npmjs.org/@zeit/xterm/-/xterm-3.9.1.tgz#576ba39c4159e8a31540b98a2bfebda4940e98ed" y18n@^3.2.1: version "3.2.1"