未验证 提交 4b4d6e61 编写于 作者: D Daniel Imms 提交者: GitHub

Merge pull request #48028 from chenhowa/chenhowa/monospace-check

Attempts to make described workaround from issue #45226
......@@ -48,22 +48,48 @@ export class TerminalConfigHelper implements ITerminalConfigHelper {
this.config = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION);
}
private _measureFont(fontFamily: string, fontSize: number, letterSpacing: number, lineHeight: number): ITerminalFont {
public configFontIsMonospace(): boolean {
this._createCharMeasureElementIfNecessary();
let fontSize = 15;
let fontFamily = this.config.fontFamily || this._configurationService.getValue<IEditorOptions>('editor').fontFamily;
let i_rect = this._getBoundingRectFor('i', fontFamily, fontSize);
let w_rect = this._getBoundingRectFor('w', fontFamily, fontSize);
let invalidBounds = !i_rect.width || !w_rect.width;
if (invalidBounds) {
// There is no reason to believe the font is not Monospace.
return true;
}
return i_rect.width === w_rect.width;
}
private _createCharMeasureElementIfNecessary() {
// Create charMeasureElement if it hasn't been created or if it was orphaned by its parent
if (!this._charMeasureElement || !this._charMeasureElement.parentElement) {
this._charMeasureElement = document.createElement('div');
this.panelContainer.appendChild(this._charMeasureElement);
}
}
private _getBoundingRectFor(char: string, fontFamily: string, fontSize: number): ClientRect | DOMRect {
const style = this._charMeasureElement.style;
style.display = 'block';
style.display = 'inline-block';
style.fontFamily = fontFamily;
style.fontSize = fontSize + 'px';
style.lineHeight = 'normal';
this._charMeasureElement.innerText = 'X';
this._charMeasureElement.innerText = char;
const rect = this._charMeasureElement.getBoundingClientRect();
style.display = 'none';
return rect;
}
private _measureFont(fontFamily: string, fontSize: number, letterSpacing: number, lineHeight: number): ITerminalFont {
this._createCharMeasureElementIfNecessary();
let rect = this._getBoundingRectFor('X', fontFamily, fontSize);
// Bounding client rect was invalid, use last font measurement if available.
if (this._lastFontMeasurement && !rect.width && !rect.height) {
return this._lastFontMeasurement;
......
......@@ -26,6 +26,9 @@ import { PANEL_BACKGROUND, PANEL_BORDER } from 'vs/workbench/common/theme';
import { TERMINAL_BACKGROUND_COLOR, TERMINAL_BORDER_COLOR } from 'vs/workbench/parts/terminal/common/terminalColorRegistry';
import { DataTransfers } from 'vs/base/browser/dnd';
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { INotificationService, IPromptChoice } from 'vs/platform/notification/common/notification';
import { TerminalConfigHelper } from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
import { Severity } from 'vs/editor/editor.api';
export class TerminalPanel extends Panel {
......@@ -45,7 +48,8 @@ export class TerminalPanel extends Panel {
@ITerminalService private readonly _terminalService: ITerminalService,
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
@IThemeService protected themeService: IThemeService,
@ITelemetryService telemetryService: ITelemetryService
@ITelemetryService telemetryService: ITelemetryService,
@INotificationService private readonly _notificationService: INotificationService
) {
super(TERMINAL_PANEL_ID, telemetryService, themeService);
}
......@@ -74,6 +78,19 @@ export class TerminalPanel extends Panel {
if (e.affectsConfiguration('terminal.integrated') || e.affectsConfiguration('editor.fontFamily')) {
this._updateFont();
}
if (e.affectsConfiguration('terminal.integrated.fontFamily') || e.affectsConfiguration('editor.fontFamily')) {
let configHelper = this._terminalService.configHelper;
if (configHelper instanceof TerminalConfigHelper) {
if (!configHelper.configFontIsMonospace()) {
const choices: IPromptChoice[] = [{
label: nls.localize('terminal.useMonospace', "Use 'monospace'"),
run: () => this._configurationService.updateValue('terminal.integrated.fontFamily', 'monospace'),
}];
this._notificationService.prompt(Severity.Warning, nls.localize('terminal.monospaceOnly', "The terminal only supports monospace fonts."), choices);
}
}
}
}));
this._updateFont();
this._updateTheme();
......
......@@ -125,4 +125,89 @@ suite('Workbench - TerminalConfigHelper', () => {
configHelper.panelContainer = fixture;
assert.equal(configHelper.getFont().lineHeight, 1, 'editor.lineHeight should be 1 when terminal.integrated.lineHeight not set');
});
test('TerminalConfigHelper - isMonospace monospace', function () {
const configurationService = new TestConfigurationService();
configurationService.setUserConfiguration('terminal', {
integrated: {
fontFamily: 'monospace'
}
});
let configHelper = new TerminalConfigHelper(configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.configFontIsMonospace(), true, 'monospace is monospaced');
});
test('TerminalConfigHelper - isMonospace sans-serif', function () {
const configurationService = new TestConfigurationService();
configurationService.setUserConfiguration('terminal', {
integrated: {
fontFamily: 'sans-serif'
}
});
let configHelper = new TerminalConfigHelper(configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.configFontIsMonospace(), false, 'sans-serif is not monospaced');
});
test('TerminalConfigHelper - isMonospace serif', function () {
const configurationService = new TestConfigurationService();
configurationService.setUserConfiguration('terminal', {
integrated: {
fontFamily: 'serif'
}
});
let configHelper = new TerminalConfigHelper(configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.configFontIsMonospace(), false, 'serif is not monospaced');
});
test('TerminalConfigHelper - isMonospace monospace falls back to editor.fontFamily', function () {
const configurationService = new TestConfigurationService();
configurationService.setUserConfiguration('editor', {
fontFamily: 'monospace'
});
configurationService.setUserConfiguration('terminal', {
integrated: {
fontFamily: null
}
});
let configHelper = new TerminalConfigHelper(configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.configFontIsMonospace(), true, 'monospace is monospaced');
});
test('TerminalConfigHelper - isMonospace sans-serif falls back to editor.fontFamily', function () {
const configurationService = new TestConfigurationService();
configurationService.setUserConfiguration('editor', {
fontFamily: 'sans-serif'
});
configurationService.setUserConfiguration('terminal', {
integrated: {
fontFamily: null
}
});
let configHelper = new TerminalConfigHelper(configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.configFontIsMonospace(), false, 'sans-serif is not monospaced');
});
test('TerminalConfigHelper - isMonospace serif falls back to editor.fontFamily', function () {
const configurationService = new TestConfigurationService();
configurationService.setUserConfiguration('editor', {
fontFamily: 'serif'
});
configurationService.setUserConfiguration('terminal', {
integrated: {
fontFamily: null
}
});
let configHelper = new TerminalConfigHelper(configurationService, null, null, null);
configHelper.panelContainer = fixture;
assert.equal(configHelper.configFontIsMonospace(), false, 'serif is not monospaced');
});
});
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册