From aca81c764a188738ae89886bab407d93cd37d136 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 3 Apr 2017 14:49:21 -0700 Subject: [PATCH 1/2] Use setInterval over animation for cursor blink Fixes #625 --- src/xterm.css | 23 ++++++++--------------- src/xterm.js | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/xterm.css b/src/xterm.css index aac95444..a67485e5 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -97,16 +97,9 @@ background-color: transparent; } -.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink .terminal-cursor { - animation: xterm-cursor-blink 1.2s infinite step-end; -} - -@keyframes xterm-cursor-blink { - 0% { } - 50% { - background-color: transparent; - color: inherit; - } +.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink-on .terminal-cursor { + background-color: transparent; + color: inherit; } .terminal.xterm-cursor-style-bar .terminal-cursor, @@ -132,13 +125,13 @@ right: 0; height: 1px; } +.terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before, +.terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before { + background-color: transparent; +} .terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink .terminal-cursor::before, .terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink .terminal-cursor::before { - animation: xterm-cursor-non-bar-blink 1.2s infinite step-end; -} -@keyframes xterm-cursor-non-bar-blink { - 0% { background-color: #fff; } - 50% { background-color: transparent; } + background-color: #fff; } .terminal .composition-view { diff --git a/src/xterm.js b/src/xterm.js index 830b8f84..fb690bd4 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -52,6 +52,13 @@ var WRITE_BUFFER_PAUSE_THRESHOLD = 5; */ var WRITE_BATCH_SIZE = 300; +/** + * The time between cursor blinks. This is driven by JS rather than a CSS + * animation due to a bug in Chromium that causes it to use excessive CPU time. + * See https://github.com/Microsoft/vscode/issues/22900 + */ +var CURSOR_BLINK_INTERVAL = 600; + /** * Terminal */ @@ -159,6 +166,7 @@ function Terminal(options) { this.scrollTop = 0; this.scrollBottom = this.rows - 1; this.customKeydownHandler = null; + this.cursorBlinkInterval = null; // modes this.applicationKeypad = false; @@ -423,7 +431,7 @@ Terminal.prototype.setOption = function(key, value) { this[key] = value; this.options[key] = value; switch (key) { - case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break; + case 'cursorBlink': this.setCursorBlinking(value); break; case 'cursorStyle': // Style 'block' applies with no class this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline'); @@ -433,6 +441,25 @@ Terminal.prototype.setOption = function(key, value) { } }; +Terminal.prototype.restartCursorBlinking = function () { + this.setCursorBlinking(this.options.cursorBlink); +} + +Terminal.prototype.setCursorBlinking = function (enabled) { + this.element.classList.toggle('xterm-cursor-blink', enabled); + this.element.classList.remove('xterm-cursor-blink-on'); + if (this.cursorBlinkInterval) { + clearInterval(this.cursorBlinkInterval); + this.cursorBlinkInterval = null; + } + if (enabled) { + var self = this; + this.cursorBlinkInterval = setInterval(function () { + self.element.classList.toggle('xterm-cursor-blink-on'); + }, CURSOR_BLINK_INTERVAL); + } +} + /** * Binds the desired focus behavior on a given terminal object. * @@ -445,6 +472,7 @@ Terminal.bindFocus = function (term) { } term.element.classList.add('focus'); term.showCursor(); + term.restartCursorBlinking.apply(term); Terminal.focus = term; term.emit('focus', {terminal: term}); }); @@ -594,7 +622,7 @@ Terminal.prototype.open = function(parent) { this.element.classList.add('terminal'); this.element.classList.add('xterm'); this.element.classList.add('xterm-theme-' + this.theme); - this.element.classList.toggle('xterm-cursor-blink', this.options.cursorBlink); + this.setCursorBlinking(this.options.cursorBlink); this.element.style.height this.element.setAttribute('tabindex', 0); @@ -1336,6 +1364,8 @@ Terminal.prototype.keyDown = function(ev) { return false; } + this.restartCursorBlinking(); + if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) { if (this.ybase !== this.ydisp) { this.scrollToBottom(); From 0c4ba9fd676f08b29bdb90aa8f6b4f7197bcb307 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 3 Apr 2017 15:09:38 -0700 Subject: [PATCH 2/2] Clear cursor blink interval on blur --- src/xterm.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index fb690bd4..fb7d0cf7 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -443,22 +443,26 @@ Terminal.prototype.setOption = function(key, value) { Terminal.prototype.restartCursorBlinking = function () { this.setCursorBlinking(this.options.cursorBlink); -} +}; Terminal.prototype.setCursorBlinking = function (enabled) { this.element.classList.toggle('xterm-cursor-blink', enabled); - this.element.classList.remove('xterm-cursor-blink-on'); - if (this.cursorBlinkInterval) { - clearInterval(this.cursorBlinkInterval); - this.cursorBlinkInterval = null; - } + this.clearCursorBlinkingInterval(); if (enabled) { var self = this; this.cursorBlinkInterval = setInterval(function () { self.element.classList.toggle('xterm-cursor-blink-on'); }, CURSOR_BLINK_INTERVAL); } -} +}; + +Terminal.prototype.clearCursorBlinkingInterval = function () { + this.element.classList.remove('xterm-cursor-blink-on'); + if (this.cursorBlinkInterval) { + clearInterval(this.cursorBlinkInterval); + this.cursorBlinkInterval = null; + } +}; /** * Binds the desired focus behavior on a given terminal object. @@ -497,6 +501,7 @@ Terminal.bindBlur = function (term) { term.send(C0.ESC + '[O'); } term.element.classList.remove('focus'); + term.clearCursorBlinkingInterval.apply(term); Terminal.focus = null; term.emit('blur', {terminal: term}); });