mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge pull request #438 from Tyriar/280_improve_refresh_queue
Improve refresh queue
This commit is contained in:
+56
-56
@@ -137,14 +137,8 @@ function Terminal(options) {
|
||||
*/
|
||||
this.y = 0;
|
||||
|
||||
/**
|
||||
* Used to debounce the refresh function
|
||||
*/
|
||||
this.isRefreshing = false;
|
||||
|
||||
/**
|
||||
* Whether there is a full terminal refresh queued
|
||||
*/
|
||||
/** A queue of the rows to be refreshed */
|
||||
this.refreshRowsQueue = [];
|
||||
|
||||
this.cursorState = 0;
|
||||
this.cursorHidden = false;
|
||||
@@ -407,7 +401,7 @@ Terminal.prototype.blur = function() {
|
||||
*/
|
||||
Terminal.bindBlur = function (term) {
|
||||
on(term.textarea, 'blur', function (ev) {
|
||||
term.refresh(term.y, term.y);
|
||||
term.queueRefresh(term.y, term.y);
|
||||
if (term.sendFocus) {
|
||||
term.send('\x1b[O');
|
||||
}
|
||||
@@ -585,8 +579,9 @@ Terminal.prototype.open = function(parent) {
|
||||
|
||||
this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasureElement);
|
||||
|
||||
// Draw the screen.
|
||||
this.refresh(0, this.rows - 1);
|
||||
// Setup loop that draws to screen
|
||||
this.queueRefresh(0, this.rows - 1);
|
||||
this.refreshLoop();
|
||||
|
||||
// Initialize global actions that
|
||||
// need to be taken on the document.
|
||||
@@ -997,6 +992,48 @@ Terminal.flags = {
|
||||
INVISIBLE: 16
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues a refresh between two rows (inclusive), to be done on next animation
|
||||
* frame.
|
||||
* @param {number} start The start row.
|
||||
* @param {number} end The end row.
|
||||
*/
|
||||
Terminal.prototype.queueRefresh = function(start, end) {
|
||||
this.refreshRowsQueue.push({ start: start, end: end });
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the refresh loop callback, calling refresh only if a refresh is
|
||||
* necessary before queueing up the next one.
|
||||
*/
|
||||
Terminal.prototype.refreshLoop = function() {
|
||||
// Don't refresh if there were no row changes
|
||||
if (this.refreshRowsQueue.length > 0) {
|
||||
var start;
|
||||
var end;
|
||||
if (this.refreshRowsQueue.length > 4) {
|
||||
// Just do a full refresh when 5+ refreshes are queued
|
||||
start = 0;
|
||||
end = this.rows - 1;
|
||||
} else {
|
||||
// Get start and end rows that need refreshing
|
||||
start = this.refreshRowsQueue[0].start;
|
||||
end = this.refreshRowsQueue[0].end;
|
||||
for (var i = 1; i < this.refreshRowsQueue.length; i++) {
|
||||
if (this.refreshRowsQueue[i].start < start) {
|
||||
start = this.refreshRowsQueue[i].start;
|
||||
}
|
||||
if (this.refreshRowsQueue[i].end > end) {
|
||||
end = this.refreshRowsQueue[i].end;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.refreshRowsQueue = [];
|
||||
this.refresh(start, end);
|
||||
}
|
||||
window.requestAnimationFrame(this.refreshLoop.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes (re-renders) terminal content within two rows (inclusive)
|
||||
*
|
||||
@@ -1017,47 +1054,10 @@ Terminal.flags = {
|
||||
*
|
||||
* @param {number} start The row to start from (between 0 and terminal's height terminal - 1)
|
||||
* @param {number} end The row to end at (between fromRow and terminal's height terminal - 1)
|
||||
* @param {boolean} queue Whether the refresh should ran right now or be queued
|
||||
*/
|
||||
Terminal.prototype.refresh = function(start, end, queue) {
|
||||
Terminal.prototype.refresh = function(start, end) {
|
||||
var self = this;
|
||||
|
||||
// queue defaults to true
|
||||
queue = (typeof queue == 'undefined') ? true : queue;
|
||||
|
||||
/**
|
||||
* The refresh queue allows refresh to execute only approximately 30 times a second. For
|
||||
* commands that pass a significant amount of output to the write function, this prevents the
|
||||
* terminal from maxing out the CPU and making the UI unresponsive. While commands can still
|
||||
* run beyond what they do on the terminal, it is far better with a debounce in place as
|
||||
* every single terminal manipulation does not need to be constructed in the DOM.
|
||||
*
|
||||
* A side-effect of this is that it makes ^C to interrupt a process seem more responsive.
|
||||
*/
|
||||
if (queue) {
|
||||
// If refresh should be queued, order the refresh and return.
|
||||
if (this._refreshIsQueued) {
|
||||
// If a refresh has already been queued, just order a full refresh next
|
||||
this._fullRefreshNext = true;
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
self.refresh(start, end, false);
|
||||
}, 34)
|
||||
this._refreshIsQueued = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If refresh should be run right now (not be queued), release the lock
|
||||
this._refreshIsQueued = false;
|
||||
|
||||
// If multiple refreshes were requested, make a full refresh.
|
||||
if (this._fullRefreshNext) {
|
||||
start = 0;
|
||||
end = this.rows - 1;
|
||||
this._fullRefreshNext = false // reset lock
|
||||
}
|
||||
|
||||
var x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement;
|
||||
|
||||
// If this is a big refresh, remove the terminal rows from the DOM for faster calculations
|
||||
@@ -1224,7 +1224,7 @@ Terminal.prototype.refresh = function(start, end, queue) {
|
||||
Terminal.prototype.showCursor = function() {
|
||||
if (!this.cursorState) {
|
||||
this.cursorState = 1;
|
||||
this.refresh(this.y, this.y);
|
||||
this.queueRefresh(this.y, this.y);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1311,7 +1311,7 @@ Terminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {
|
||||
this.emit('scroll', this.ydisp);
|
||||
}
|
||||
|
||||
this.refresh(0, this.rows - 1);
|
||||
this.queueRefresh(0, this.rows - 1);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2379,7 +2379,7 @@ Terminal.prototype.write = function(data) {
|
||||
}
|
||||
|
||||
this.updateRange(this.y);
|
||||
this.refresh(this.refreshStart, this.refreshEnd);
|
||||
this.queueRefresh(this.refreshStart, this.refreshEnd);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2945,7 +2945,7 @@ Terminal.prototype.resize = function(x, y) {
|
||||
this.scrollTop = 0;
|
||||
this.scrollBottom = y - 1;
|
||||
|
||||
this.refresh(0, this.rows - 1);
|
||||
this.queueRefresh(0, this.rows - 1);
|
||||
|
||||
this.normal = null;
|
||||
|
||||
@@ -3074,7 +3074,7 @@ Terminal.prototype.clear = function() {
|
||||
for (var i = 1; i < this.rows; i++) {
|
||||
this.lines.push(this.blankLine());
|
||||
}
|
||||
this.refresh(0, this.rows - 1);
|
||||
this.queueRefresh(0, this.rows - 1);
|
||||
this.emit('scroll', this.ydisp);
|
||||
};
|
||||
|
||||
@@ -3205,7 +3205,7 @@ Terminal.prototype.reset = function() {
|
||||
var customKeydownHandler = this.customKeydownHandler;
|
||||
Terminal.call(this, this.options);
|
||||
this.customKeydownHandler = customKeydownHandler;
|
||||
this.refresh(0, this.rows - 1);
|
||||
this.queueRefresh(0, this.rows - 1);
|
||||
this.viewport.syncScrollArea();
|
||||
};
|
||||
|
||||
@@ -4324,7 +4324,7 @@ Terminal.prototype.resetMode = function(params) {
|
||||
// this.x = this.savedX;
|
||||
// this.y = this.savedY;
|
||||
// }
|
||||
this.refresh(0, this.rows - 1);
|
||||
this.queueRefresh(0, this.rows - 1);
|
||||
this.viewport.syncScrollArea();
|
||||
this.showCursor();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user