Skip to content

Commit 5bc2c2e

Browse files
terminal: bump xterm and addons (#12691)
Bumps `xterm` and related addons to their latest versions to benefit from additional improvements and bug fixes. Signed-off-by: vince-fugnitto <vincent.fugnitto@ericsson.com> Signed-off-by: Thomas Mäder <t.s.maeder@gmail.com> Co-authored-by: Thomas Mäder <t.s.maeder@gmail.com>
1 parent 84a54f4 commit 5bc2c2e

File tree

7 files changed

+113
-71
lines changed

7 files changed

+113
-71
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@
232232

233233
- [deps] bumped supported Node.js version from 16.x to >=18, you may need to update your environments [#12711](https://github.com/eclipse-theia/theia/pull/12711)
234234
- [preferences] removed the `welcome.alwaysShowWelcomePage` preference in favor of `workbench.startupEditor` [#12813](https://github.com/eclipse-theia/theia/pull/12813)
235+
- [terminal] deprecated `terminal.integrated.rendererType` preference [#12691](https://github.com/eclipse-theia/theia/pull/12691)
236+
- [terminal] removed protected method `TerminalWidgetImpl.getTerminalRendererType` [#12691](https://github.com/eclipse-theia/theia/pull/12691)
235237

236238
## v1.40.0 - 07/27/2023
237239

packages/terminal/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
"@theia/process": "1.46.0",
1010
"@theia/variable-resolver": "1.46.0",
1111
"@theia/workspace": "1.46.0",
12-
"xterm": "^4.16.0",
13-
"xterm-addon-fit": "^0.5.0",
14-
"xterm-addon-search": "^0.8.2"
12+
"xterm": "^5.3.0",
13+
"xterm-addon-fit": "^0.8.0",
14+
"xterm-addon-search": "^0.13.0"
1515
},
1616
"publishConfig": {
1717
"access": "public"
@@ -53,4 +53,4 @@
5353
"nyc": {
5454
"extends": "../../configs/nyc.json"
5555
}
56-
}
56+
}

packages/terminal/src/browser/terminal-frontend-contribution.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import { nls } from '@theia/core/lib/common/nls';
5555
import { Profiles, TerminalPreferences } from './terminal-preferences';
5656
import { ShellTerminalProfile } from './shell-terminal-profile';
5757
import { VariableResolverService } from '@theia/variable-resolver/lib/browser';
58+
import { Color } from '@theia/core/lib/common/color';
5859

5960
export namespace TerminalMenus {
6061
export const TERMINAL = [...MAIN_MENU_BAR, '7_terminal'];
@@ -1074,6 +1075,27 @@ export class TerminalFrontendContribution implements FrontendApplicationContribu
10741075
},
10751076
description: 'The selection background color of the terminal.'
10761077
});
1078+
colors.register({
1079+
id: 'terminal.inactiveSelectionBackground',
1080+
defaults: {
1081+
light: Color.transparent('terminal.selectionBackground', 0.5),
1082+
dark: Color.transparent('terminal.selectionBackground', 0.5),
1083+
hcDark: Color.transparent('terminal.selectionBackground', 0.7),
1084+
hcLight: Color.transparent('terminal.selectionBackground', 0.5),
1085+
},
1086+
description: 'The selection background color of the terminal when it does not have focus.'
1087+
});
1088+
colors.register({
1089+
id: 'terminal.selectionForeground',
1090+
defaults: {
1091+
light: undefined,
1092+
dark: undefined,
1093+
hcDark: '#000000',
1094+
hcLight: '#ffffff'
1095+
},
1096+
// eslint-disable-next-line max-len
1097+
description: 'The selection foreground color of the terminal. When this is null the selection foreground will be retained and have the minimum contrast ratio feature applied.'
1098+
});
10771099
colors.register({
10781100
id: 'terminal.border',
10791101
defaults: {

packages/terminal/src/browser/terminal-preferences.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ export const TerminalConfigSchema: PreferenceSchema = {
134134
description: nls.localize('theia/terminal/rendererType', 'Controls how the terminal is rendered.'),
135135
type: 'string',
136136
enum: ['canvas', 'dom'],
137-
default: 'canvas'
137+
default: 'canvas',
138+
deprecationMessage: nls.localize('theia/terminal/rendererTypeDeprecationMessage', 'The renderer type is no longer supported as an option.')
138139
},
139140
'terminal.integrated.copyOnSelection': {
140141
description: nls.localizeByDefault('Controls whether text selected in the terminal will be copied to the clipboard.'),

packages/terminal/src/browser/terminal-theme-service.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,18 @@ export class TerminalThemeService {
187187
const backgroundColor = this.colorRegistry.getCurrentColor('terminal.background') || this.colorRegistry.getCurrentColor('panel.background');
188188
const cursorColor = this.colorRegistry.getCurrentColor('terminalCursor.foreground') || foregroundColor;
189189
const cursorAccentColor = this.colorRegistry.getCurrentColor('terminalCursor.background') || backgroundColor;
190-
const selectionColor = this.colorRegistry.getCurrentColor('terminal.selectionBackground');
190+
const selectionBackgroundColor = this.colorRegistry.getCurrentColor('terminal.selectionBackground');
191+
const selectionInactiveBackground = this.colorRegistry.getCurrentColor('terminal.inactiveSelectionBackground');
192+
const selectionForegroundColor = this.colorRegistry.getCurrentColor('terminal.selectionForeground');
191193

192194
const theme: ITheme = {
193195
background: backgroundColor,
194196
foreground: foregroundColor,
195197
cursor: cursorColor,
196198
cursorAccent: cursorAccentColor,
197-
selection: selectionColor
199+
selectionBackground: selectionBackgroundColor,
200+
selectionInactiveBackground: selectionInactiveBackground,
201+
selectionForeground: selectionForegroundColor
198202
};
199203
// eslint-disable-next-line guard-for-in
200204
for (const id in terminalAnsiColorMap) {

packages/terminal/src/browser/terminal-widget-impl.ts

Lines changed: 63 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
1515
// *****************************************************************************
1616

17-
import { Terminal, RendererType } from 'xterm';
17+
import { Terminal } from 'xterm';
1818
import { FitAddon } from 'xterm-addon-fit';
1919
import { inject, injectable, named, postConstruct } from '@theia/core/shared/inversify';
2020
import { ContributionProvider, Disposable, Event, Emitter, ILogger, DisposableCollection, Channel, OS } from '@theia/core';
@@ -32,7 +32,7 @@ import {
3232
TerminalLocation
3333
} from './base/terminal-widget';
3434
import { Deferred } from '@theia/core/lib/common/promise-util';
35-
import { TerminalPreferences, TerminalRendererType, isTerminalRendererType, DEFAULT_TERMINAL_RENDERER_TYPE, CursorStyle } from './terminal-preferences';
35+
import { TerminalPreferences } from './terminal-preferences';
3636
import URI from '@theia/core/lib/common/uri';
3737
import { TerminalService } from './base/terminal-service';
3838
import { TerminalSearchWidgetFactory, TerminalSearchWidget } from './search/terminal-search-widget';
@@ -161,7 +161,7 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
161161

162162
this.term = new Terminal({
163163
cursorBlink: this.preferences['terminal.integrated.cursorBlinking'],
164-
cursorStyle: this.getCursorStyle(),
164+
cursorStyle: this.preferences['terminal.integrated.cursorStyle'] === 'line' ? 'bar' : this.preferences['terminal.integrated.cursorStyle'],
165165
cursorWidth: this.preferences['terminal.integrated.cursorWidth'],
166166
fontFamily: this.preferences['terminal.integrated.fontFamily'],
167167
fontSize: this.preferences['terminal.integrated.fontSize'],
@@ -172,7 +172,6 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
172172
lineHeight: this.preferences['terminal.integrated.lineHeight'],
173173
scrollback: this.preferences['terminal.integrated.scrollback'],
174174
fastScrollSensitivity: this.preferences['terminal.integrated.fastScrollSensitivity'],
175-
rendererType: this.getTerminalRendererType(this.preferences['terminal.integrated.rendererType']),
176175
theme: this.themeService.theme
177176
});
178177

@@ -182,34 +181,12 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
182181
this.initializeLinkHover();
183182

184183
this.toDispose.push(this.preferences.onPreferenceChanged(change => {
185-
const lastSeparator = change.preferenceName.lastIndexOf('.');
186-
if (lastSeparator > 0) {
187-
let preferenceName = change.preferenceName.substring(lastSeparator + 1);
188-
let preferenceValue = change.newValue;
189-
190-
if (preferenceName === 'rendererType') {
191-
const newRendererType = preferenceValue as string;
192-
if (newRendererType !== this.getTerminalRendererType(newRendererType)) {
193-
// Given terminal renderer type is not supported or invalid
194-
preferenceValue = DEFAULT_TERMINAL_RENDERER_TYPE;
195-
}
196-
} else if (preferenceName === 'cursorBlinking') {
197-
// Convert the terminal preference into a valid `xterm` option
198-
preferenceName = 'cursorBlink';
199-
} else if (preferenceName === 'cursorStyle') {
200-
preferenceValue = this.getCursorStyle();
201-
}
202-
try {
203-
this.term.setOption(preferenceName, preferenceValue);
204-
} catch (e) {
205-
console.debug(`xterm configuration: '${preferenceName}' with value '${preferenceValue}' is not valid.`);
206-
}
207-
this.needsResize = true;
208-
this.update();
209-
}
184+
this.updateConfig();
185+
this.needsResize = true;
186+
this.update();
210187
}));
211188

212-
this.toDispose.push(this.themeService.onDidChange(() => this.term.setOption('theme', this.themeService.theme)));
189+
this.toDispose.push(this.themeService.onDidChange(() => this.term.options.theme = this.themeService.theme));
213190
this.attachCustomKeyEventHandler();
214191
const titleChangeListenerDispose = this.term.onTitleChange((title: string) => {
215192
if (this.options.useServerTitle) {
@@ -314,25 +291,38 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
314291
return this.terminalKind;
315292
}
316293

317-
/**
318-
* Get the cursor style compatible with `xterm`.
319-
* @returns CursorStyle
320-
*/
321-
private getCursorStyle(): CursorStyle {
322-
const value = this.preferences['terminal.integrated.cursorStyle'];
323-
return value === 'line' ? 'bar' : value;
294+
updateConfig(): void {
295+
this.setCursorBlink(this.preferences.get('terminal.integrated.cursorBlinking'));
296+
this.setCursorStyle(this.preferences.get('terminal.integrated.cursorStyle'));
297+
this.setCursorWidth(this.preferences.get('terminal.integrated.cursorWidth'));
298+
this.term.options.fontFamily = this.preferences.get('terminal.integrated.fontFamily');
299+
this.term.options.fontSize = this.preferences.get('terminal.integrated.fontSize');
300+
this.term.options.fontWeight = this.preferences.get('terminal.integrated.fontWeight');
301+
this.term.options.fontWeightBold = this.preferences.get('terminal.integrated.fontWeightBold');
302+
this.term.options.drawBoldTextInBrightColors = this.preferences.get('terminal.integrated.drawBoldTextInBrightColors');
303+
this.term.options.letterSpacing = this.preferences.get('terminal.integrated.letterSpacing');
304+
this.term.options.lineHeight = this.preferences.get('terminal.integrated.lineHeight');
305+
this.term.options.scrollback = this.preferences.get('terminal.integrated.scrollback');
306+
this.term.options.fastScrollSensitivity = this.preferences.get('terminal.integrated.fastScrollSensitivity');
324307
}
325308

326-
/**
327-
* Returns given renderer type if it is valid and supported or default renderer otherwise.
328-
*
329-
* @param terminalRendererType desired terminal renderer type
330-
*/
331-
private getTerminalRendererType(terminalRendererType?: string | TerminalRendererType): RendererType {
332-
if (terminalRendererType && isTerminalRendererType(terminalRendererType)) {
333-
return terminalRendererType;
309+
private setCursorBlink(blink: boolean): void {
310+
if (this.term.options.cursorBlink !== blink) {
311+
this.term.options.cursorBlink = blink;
312+
this.term.refresh(0, this.term.rows - 1);
313+
}
314+
}
315+
316+
private setCursorStyle(style: 'block' | 'underline' | 'bar' | 'line'): void {
317+
if (this.term.options.cursorStyle !== style) {
318+
this.term.options.cursorStyle = (style === 'line') ? 'bar' : style;
319+
}
320+
}
321+
322+
private setCursorWidth(width: number): void {
323+
if (this.term.options.cursorWidth !== width) {
324+
this.term.options.cursorWidth = width;
334325
}
335-
return DEFAULT_TERMINAL_RENDERER_TYPE;
336326
}
337327

338328
protected initializeLinkHover(): void {
@@ -670,16 +660,34 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
670660
}
671661
this.term.open(this.node);
672662

663+
interface ViewportType {
664+
register(d: Disposable): void;
665+
_refreshAnimationFrame: number | null;
666+
_coreBrowserService: {
667+
window: Window;
668+
}
669+
}
670+
671+
// Workaround for https://github.com/xtermjs/xterm.js/issues/4775. Can be removed for releases > 5.3.0
672+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
673+
const viewPort: ViewportType = (this.term as any)._core.viewport;
674+
viewPort.register(Disposable.create(() => {
675+
if (typeof viewPort._refreshAnimationFrame === 'number') {
676+
viewPort._coreBrowserService.window.cancelAnimationFrame(viewPort._refreshAnimationFrame);
677+
}
678+
}));
679+
673680
if (isFirefox) {
674681
// monkey patching intersection observer handling for secondary window support
675682
// eslint-disable-next-line @typescript-eslint/no-explicit-any
676683
const renderService: any = (this.term as any)._core._renderService;
677-
const originalFunc: (entry: IntersectionObserverEntry) => void = renderService._onIntersectionChange.bind(renderService);
684+
685+
const originalFunc: (entry: IntersectionObserverEntry) => void = renderService._handleIntersectionChange.bind(renderService);
678686
const replacement = function (entry: IntersectionObserverEntry): void {
679687
if (entry.target.ownerDocument !== document) {
680688
// in Firefox, the intersection observer always reports the widget as non-intersecting if the dom element
681689
// is in a different document from when the IntersectionObserver started observing. Since we know
682-
// that the widget is always "visible" when in a secondary window, so we mark the entry as "intersecting"
690+
// that the widget is always "visible" when in a secondary window, so we refresh the rows ourselves
683691
const patchedEvent: IntersectionObserverEntry = {
684692
...entry,
685693
isIntersecting: true,
@@ -690,21 +698,14 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
690698
}
691699
};
692700

693-
renderService._onIntersectionChange = replacement;
701+
renderService._handleIntersectionChange = replacement.bind(renderService);
694702
}
695703

696704
if (this.initialData) {
697705
this.term.write(this.initialData);
698706
}
699707
this.termOpened = true;
700708
this.initialData = '';
701-
702-
if (isFirefox) {
703-
// The software scrollbars don't work with xterm.js, so we disable the scrollbar if we are on firefox.
704-
if (this.term.element) {
705-
(this.term.element.children.item(0) as HTMLElement).style.overflow = 'hidden';
706-
}
707-
}
708709
}
709710

710711
write(data: string): void {
@@ -792,11 +793,13 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
792793
return;
793794
}
794795
const geo = this.fitAddon.proposeDimensions();
795-
const cols = geo.cols;
796-
const rows = geo.rows - 1; // subtract one row for margin
797-
this.term.resize(cols, rows);
796+
if (geo) {
797+
const cols = geo.cols;
798+
const rows = geo.rows - 1; // subtract one row for margin
799+
this.term.resize(cols, rows);
798800

799-
this.resizeTerminalProcess();
801+
this.resizeTerminalProcess();
802+
}
800803
}
801804

802805
protected resizeTerminalProcess(): void {

yarn.lock

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12134,16 +12134,26 @@ xterm-addon-fit@^0.5.0:
1213412134
resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz#2d51b983b786a97dcd6cde805e700c7f913bc596"
1213512135
integrity sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==
1213612136

12137-
xterm-addon-search@^0.8.2:
12138-
version "0.8.2"
12139-
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.8.2.tgz#be7aa74d5ff12c901707c6ff674229f214318032"
12140-
integrity sha512-I1863mjn8P6uVrqm/X+btalVsqjAKLhnhpbP7SavAOpEkI1jJhbHU2UTp7NjeRtcKTks6UWk/ycgds5snDSejg==
12137+
xterm-addon-fit@^0.8.0:
12138+
version "0.8.0"
12139+
resolved "https://registry.yarnpkg.com/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz#48ca99015385141918f955ca7819e85f3691d35f"
12140+
integrity sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==
12141+
12142+
xterm-addon-search@^0.13.0:
12143+
version "0.13.0"
12144+
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.13.0.tgz#21286f4db48aa949fbefce34bb8bc0c9d3cec627"
12145+
integrity sha512-sDUwG4CnqxUjSEFh676DlS3gsh3XYCzAvBPSvJ5OPgF3MRL3iHLPfsb06doRicLC2xXNpeG2cWk8x1qpESWJMA==
1214112146

1214212147
xterm@^4.16.0:
1214312148
version "4.19.0"
1214412149
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.19.0.tgz#c0f9d09cd61de1d658f43ca75f992197add9ef6d"
1214512150
integrity sha512-c3Cp4eOVsYY5Q839dR5IejghRPpxciGmLWWaP9g+ppfMeBChMeLa1DCA+pmX/jyDZ+zxFOmlJL/82qVdayVoGQ==
1214612151

12152+
xterm@^5.3.0:
12153+
version "5.3.0"
12154+
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.3.0.tgz#867daf9cc826f3d45b5377320aabd996cb0fce46"
12155+
integrity sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg==
12156+
1214712157
y18n@^4.0.0:
1214812158
version "4.0.3"
1214912159
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"

0 commit comments

Comments
 (0)