terminal: init xterm.js options before calling `open()`
This is more efficient and prevents some flashing.
Bug: b/236205389
Change-Id: I5832799ae0093854f8fef2eebd2d2fcf506aaa76
Reviewed-on: https://chromium-review.googlesource.com/c/apps/libapps/+/3868655
Reviewed-by: Joel Hockey <joelhockey@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/terminal/js/terminal_emulator.js b/terminal/js/terminal_emulator.js
index c346cc9..a8348c6 100644
--- a/terminal/js/terminal_emulator.js
+++ b/terminal/js/terminal_emulator.js
@@ -158,6 +158,7 @@
this.ctrlVKeyDownHandler_ = this.ctrlVKeyDownHandler_.bind(this);
this.zoomKeyDownHandler_ = this.zoomKeyDownHandler_.bind(this);
+ this.inited_ = false;
this.profileId_ = profileId;
/** @type {!hterm.PreferenceManager} */
this.prefs_ = new hterm.PreferenceManager(storage, profileId);
@@ -169,7 +170,12 @@
this.fitAddon = testParams?.fitAddon || new FitAddon();
this.term.loadAddon(this.fitAddon);
- this.scheduleFit_ = delayedScheduler(() => this.fitAddon.fit(),
+ this.scheduleFit_ = delayedScheduler(
+ () => {
+ if (this.inited_) {
+ this.fitAddon.fit();
+ }
+ },
testParams ? 0 : 250);
this.term.loadAddon(new WebLinksAddon());
@@ -294,15 +300,6 @@
}
/**
- * One-time initialization at the beginning.
- */
- async init() {
- await new Promise((resolve) => this.prefs_.readStorage(resolve));
- this.prefs_.notifyAll();
- this.onTerminalReady();
- }
-
- /**
* Write data to the terminal.
*
* @param {string|!Uint8Array} data string for UTF-16 data, Uint8Array for
@@ -336,15 +333,26 @@
* @override
*/
decorate(elem) {
- this.term.open(elem);
- this.scheduleFit_();
- if (this.enableWebGL_) {
- this.term.loadAddon(new WebglAddon());
- }
- this.term.focus();
- (new ResizeObserver(() => this.scheduleFit_())).observe(elem);
- // TODO: Make a11y work. Maybe we can just use `hterm.AccessibilityReader`.
- this.notificationCenter_ = new hterm.NotificationCenter(document.body);
+ (async () => {
+ await new Promise((resolve) => this.prefs_.readStorage(resolve));
+ // This will trigger all the observers to set the terminal options before
+ // we call `this.term.open()`.
+ this.prefs_.notifyAll();
+
+ this.inited_ = true;
+ this.term.open(elem);
+
+ this.scheduleFit_();
+ if (this.enableWebGL_) {
+ this.term.loadAddon(new WebglAddon());
+ }
+ this.term.focus();
+ (new ResizeObserver(() => this.scheduleFit_())).observe(elem);
+ // TODO: Make a11y work. Maybe we can just use hterm.AccessibilityReader.
+ this.notificationCenter_ = new hterm.NotificationCenter(document.body);
+
+ this.onTerminalReady();
+ })();
}
/** @override */
@@ -458,15 +466,25 @@
* @param {!Object} theme
*/
updateTheme_(theme) {
- const newTheme = {...this.term.options.theme};
- for (const key in theme) {
- newTheme[key] = lib.colors.normalizeCSS(theme[key]);
+ const updateTheme = (target) => {
+ for (const [key, value] of Object.entries(theme)) {
+ target[key] = lib.colors.normalizeCSS(value);
+ }
+ };
+
+ // Must use a new theme object to trigger re-render if we have initialized.
+ if (this.inited_) {
+ const newTheme = {...this.term.options.theme};
+ updateTheme(newTheme);
+ this.term.options.theme = newTheme;
+ return;
}
- this.updateOption_('theme', newTheme);
+
+ updateTheme(this.term.options.theme);
}
/**
- * Update one xterm.js option.
+ * Update one xterm.js option. Use updateTheme_() for theme.
*
* @param {string} key
* @param {*} value
@@ -489,7 +507,7 @@
async onFontLoadingDone_() {
// If there is a pending font, the font is going to be refresh soon, so we
// don't need to do anything.
- if (!this.pendingFont_) {
+ if (this.inited_ && !this.pendingFont_) {
this.scheduleRefreshFont_();
}
}
@@ -809,9 +827,6 @@
profileId,
enableWebGL: config.webgl,
});
- // Don't await it so that the caller can override
- // `terminal.onTerminalReady()` before the terminal is ready.
- terminal.init();
return terminal;
}
case 'hterm':
diff --git a/terminal/js/terminal_emulator_tests.js b/terminal/js/terminal_emulator_tests.js
index e0f41ab..1e3b764 100644
--- a/terminal/js/terminal_emulator_tests.js
+++ b/terminal/js/terminal_emulator_tests.js
@@ -35,6 +35,7 @@
enableWebGL: true,
testParams: /** @type {!XtermTerminalTestParams} */(testParams),
});
+ this.terminal.inited_ = true;
});
describe('updateFont_()', function() {