Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 56 additions & 56 deletions src/xterm.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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');
}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
*
Expand All @@ -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
Expand Down Expand Up @@ -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);
}
};

Expand Down Expand Up @@ -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);
};

/**
Expand Down Expand Up @@ -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);
};

/**
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
};

Expand Down Expand Up @@ -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();
};

Expand Down Expand Up @@ -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();
}
Expand Down