未验证 提交 9054054a 编写于 作者: I Isidor Nikolic 提交者: GitHub

Merge branch 'master' into isidorn/listClear

[
{
"name": "ms-vscode.node-debug",
"version": "1.35.3",
"version": "1.38.2",
"repo": "https://github.com/Microsoft/vscode-node-debug",
"metadata": {
"id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6",
......
......@@ -679,12 +679,15 @@ export class Repository implements Disposable {
const root = Uri.file(repository.root);
this._sourceControl = scm.createSourceControl('git', 'Git', root);
this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message (press {0} to commit)");
this._sourceControl.acceptInputCommand = { command: 'git.commit', title: localize('commit', "Commit"), arguments: [this._sourceControl] };
this._sourceControl.quickDiffProvider = this;
this._sourceControl.inputBox.validateInput = this.validateInput.bind(this);
this.disposables.push(this._sourceControl);
this.updateInputBoxPlaceholder();
this.disposables.push(this.onDidRunGitStatus(() => this.updateInputBoxPlaceholder()));
this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "MERGE CHANGES"));
this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "STAGED CHANGES"));
this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "CHANGES"));
......@@ -1649,6 +1652,21 @@ export class Repository implements Disposable {
return `${this.HEAD.behind}${this.HEAD.ahead}↑`;
}
private updateInputBoxPlaceholder(): void {
const HEAD = this.HEAD;
if (HEAD) {
const tag = this.refs.filter(iref => iref.type === RefType.Tag && iref.commit === HEAD.commit)[0];
const tagName = tag && tag.name;
const head = HEAD.name || tagName || (HEAD.commit || '').substr(0, 8);
// '{0}' will be replaced by the corresponding key-command later in the process, which is why it needs to stay.
this._sourceControl.inputBox.placeholder = localize('commitMessageWithHeadLabel', "Message ({0} to commit on '{1}')", "{0}", head);
} else {
this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message ({0} to commit)");
}
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
......
......@@ -337,14 +337,15 @@ suite('window namespace tests', () => {
});
terminal.dispose();
});
overrideDimensionsEmitter.fire({ columns: 10, rows: 5 });
});
const writeEmitter = new EventEmitter<string>();
const overrideDimensionsEmitter = new EventEmitter<TerminalDimensions>();
const pty: Pseudoterminal = {
onDidWrite: writeEmitter.event,
onDidOverrideDimensions: overrideDimensionsEmitter.event,
open: () => {},
open: () => {
overrideDimensionsEmitter.fire({ columns: 10, rows: 5 });
},
close: () => {}
};
const terminal = window.createTerminal({ name: 'foo', pty });
......
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 3.76345L5.80687 11.9351L5.08584 11.8927L1 7.29614L1.76345 6.61752L5.50997 10.8324L14.3214 3L15 3.76345Z" fill="#C5C5C5"/>
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 3.76345L5.80687 11.9351L5.08584 11.8927L1 7.29614L1.76345 6.61752L5.50997 10.8324L14.3214 3L15 3.76345Z" fill="#424242"/>
</svg>
......@@ -39,4 +39,24 @@
.hc-black .monaco-custom-checkbox:hover {
background: none;
}
\ No newline at end of file
}
.monaco-custom-checkbox.monaco-simple-checkbox {
height: 18px;
width: 18px;
border: 1px solid transparent;
border-radius: 3px;
margin-right: 9px;
margin-left: 0px;
padding: 0px;
opacity: 1;
background-size: 16px !important;
}
.monaco-custom-checkbox.monaco-simple-checkbox.checked {
background: url('check-light.svg') center center no-repeat;
}
.monaco-custom-checkbox.monaco-simple-checkbox.checked {
background: url('check-dark.svg') center center no-repeat;
}
......@@ -25,6 +25,12 @@ export interface ICheckboxStyles {
inputActiveOptionBackground?: Color;
}
export interface ISimpleCheckboxStyles {
checkboxBackground?: Color;
checkboxBorder?: Color;
checkboxForeground?: Color;
}
const defaultOpts = {
inputActiveOptionBorder: Color.fromHex('#007ACC00'),
inputActiveOptionBackground: Color.fromHex('#0E639C50')
......@@ -174,3 +180,46 @@ export class Checkbox extends Widget {
this.domNode.setAttribute('aria-disabled', String(true));
}
}
export class SimpleCheckbox extends Widget {
private checkbox: Checkbox;
private styles: ISimpleCheckboxStyles;
readonly domNode: HTMLElement;
constructor(private title: string, private isChecked: boolean) {
super();
this.checkbox = new Checkbox({ title: this.title, isChecked: this.isChecked, actionClassName: 'monaco-simple-checkbox' });
this.domNode = this.checkbox.domNode;
this.styles = {};
this.checkbox.onChange(() => {
this.applyStyles();
});
}
get checked(): boolean {
return this.checkbox.checked;
}
set checked(newIsChecked: boolean) {
this.checkbox.checked = newIsChecked;
this.applyStyles();
}
style(styles: ISimpleCheckboxStyles): void {
this.styles = styles;
this.applyStyles();
}
protected applyStyles(): void {
this.domNode.style.color = this.styles.checkboxForeground ? this.styles.checkboxForeground.toString() : null;
this.domNode.style.backgroundColor = this.styles.checkboxBackground ? this.styles.checkboxBackground.toString() : null;
this.domNode.style.borderColor = this.styles.checkboxBorder ? this.styles.checkboxBorder.toString() : null;
}
}
......@@ -149,6 +149,11 @@
outline-style: solid;
}
.monaco-workbench .dialog-box .dialog-message-row .dialog-message-container .dialog-checkbox-row {
padding: 15px 0px 0px;
display: flex;
}
/** Dialog: Buttons Row */
.monaco-workbench .dialog-box > .dialog-buttons-row {
display: flex;
......@@ -175,4 +180,4 @@
margin: 4px 5px; /* allows button focus outline to be visible */
overflow: hidden;
text-overflow: ellipsis;
}
\ No newline at end of file
}
......@@ -16,15 +16,23 @@ import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action } from 'vs/base/common/actions';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { isMacintosh, isLinux } from 'vs/base/common/platform';
import { SimpleCheckbox, ISimpleCheckboxStyles } from 'vs/base/browser/ui/checkbox/checkbox';
export interface IDialogOptions {
cancelId?: number;
detail?: string;
checkboxLabel?: string;
checkboxChecked?: boolean;
type?: 'none' | 'info' | 'error' | 'question' | 'warning' | 'pending';
keyEventProcessor?: (event: StandardKeyboardEvent) => void;
}
export interface IDialogStyles extends IButtonStyles {
export interface IDialogResult {
button: number;
checkboxChecked?: boolean;
}
export interface IDialogStyles extends IButtonStyles, ISimpleCheckboxStyles {
dialogForeground?: Color;
dialogBackground?: Color;
dialogShadow?: Color;
......@@ -42,6 +50,7 @@ export class Dialog extends Disposable {
private buttonsContainer: HTMLElement | undefined;
private messageDetailElement: HTMLElement | undefined;
private iconElement: HTMLElement | undefined;
private checkbox: SimpleCheckbox | undefined;
private toolbarContainer: HTMLElement | undefined;
private buttonGroup: ButtonGroup | undefined;
private styles: IDialogStyles | undefined;
......@@ -68,6 +77,19 @@ export class Dialog extends Disposable {
this.messageDetailElement = messageContainer.appendChild($('.dialog-message-detail'));
this.messageDetailElement.innerText = this.options.detail ? this.options.detail : message;
if (this.options.checkboxLabel) {
const checkboxRowElement = messageContainer.appendChild($('.dialog-checkbox-row'));
this.checkbox = this._register(new SimpleCheckbox(this.options.checkboxLabel, !!this.options.checkboxChecked));
checkboxRowElement.appendChild(this.checkbox.domNode);
const checkboxMessageElement = checkboxRowElement.appendChild($('.dialog-checkbox-message'));
checkboxMessageElement.innerText = this.options.checkboxLabel;
}
const toolbarRowElement = this.element.appendChild($('.dialog-toolbar-row'));
this.toolbarContainer = toolbarRowElement.appendChild($('.dialog-toolbar'));
}
......@@ -78,12 +100,12 @@ export class Dialog extends Disposable {
}
}
async show(): Promise<number> {
async show(): Promise<IDialogResult> {
this.focusToReturn = document.activeElement as HTMLElement;
return new Promise<number>((resolve) => {
return new Promise<IDialogResult>((resolve) => {
if (!this.element || !this.buttonsContainer || !this.iconElement || !this.toolbarContainer) {
resolve(0);
resolve({ button: 0 });
return;
}
......@@ -112,7 +134,7 @@ export class Dialog extends Disposable {
this._register(button.onDidClick(e => {
EventHelper.stop(e);
resolve(buttonMap[index].index);
resolve({ button: buttonMap[index].index, checkboxChecked: this.checkbox ? this.checkbox.checked : undefined });
}));
});
......@@ -147,7 +169,7 @@ export class Dialog extends Disposable {
const evt = new StandardKeyboardEvent(e);
if (evt.equals(KeyCode.Escape)) {
resolve(this.options.cancelId || 0);
resolve({ button: this.options.cancelId || 0, checkboxChecked: this.checkbox ? this.checkbox.checked : undefined });
}
}));
......@@ -187,7 +209,7 @@ export class Dialog extends Disposable {
const actionBar = new ActionBar(this.toolbarContainer, {});
const action = new Action('dialog.close', nls.localize('dialogClose', "Close Dialog"), 'dialog-close-action', true, () => {
resolve(this.options.cancelId || 0);
resolve({ button: this.options.cancelId || 0, checkboxChecked: this.checkbox ? this.checkbox.checked : undefined });
return Promise.resolve();
});
......@@ -221,6 +243,10 @@ export class Dialog extends Disposable {
if (this.buttonGroup) {
this.buttonGroup.buttons.forEach(button => button.style(style));
}
if (this.checkbox) {
this.checkbox.style(style);
}
}
}
}
......@@ -261,4 +287,4 @@ export class Dialog extends Disposable {
return buttonMap;
}
}
\ No newline at end of file
}
......@@ -348,6 +348,7 @@ class BranchNode implements ISplitView, IDisposable {
}
this.splitview.setViewVisible(index, visible);
this._onDidChange.fire(undefined);
}
getChildCachedVisibleSize(index: number): number | undefined {
......
......@@ -39,6 +39,7 @@
white-space: initial;
flex: none;
position: relative;
overflow: hidden;
}
.monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) {
......@@ -72,4 +73,4 @@
.monaco-split-view2.separator-border.vertical > .split-view-container > .split-view-view:not(:first-child)::before {
height: 1px;
width: 100%;
}
\ No newline at end of file
}
......@@ -125,7 +125,10 @@ abstract class ViewItem {
dom.addClass(container, 'visible');
}
abstract layout(): void;
layout(): void {
this.container.scrollTop = 0;
this.container.scrollLeft = 0;
}
layoutView(orientation: Orientation): void {
this.view.layout(this.size, orientation);
......@@ -140,6 +143,7 @@ abstract class ViewItem {
class VerticalViewItem extends ViewItem {
layout(): void {
super.layout();
this.container.style.height = `${this.size}px`;
this.layoutView(Orientation.VERTICAL);
}
......@@ -148,6 +152,7 @@ class VerticalViewItem extends ViewItem {
class HorizontalViewItem extends ViewItem {
layout(): void {
super.layout();
this.container.style.width = `${this.size}px`;
this.layoutView(Orientation.HORIZONTAL);
}
......
......@@ -95,7 +95,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
this._typicalHalfwidthCharacterWidth = conf.editor.fontInfo.typicalHalfwidthCharacterWidth;
this._isViewportWrapping = conf.editor.wrappingInfo.isViewportWrapping;
this._revealHorizontalRightPadding = conf.editor.viewInfo.revealHorizontalRightPadding;
this._scrollOff = conf.editor.viewInfo.scrollOff;
this._scrollOff = conf.editor.viewInfo.cursorSurroundingLines;
this._canUseLayerHinting = conf.editor.canUseLayerHinting;
this._viewLineOptions = new ViewLineOptions(conf, this._context.theme.type);
......@@ -152,7 +152,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
}
if (e.viewInfo) {
this._revealHorizontalRightPadding = conf.editor.viewInfo.revealHorizontalRightPadding;
this._scrollOff = conf.editor.viewInfo.scrollOff;
this._scrollOff = conf.editor.viewInfo.cursorSurroundingLines;
}
if (e.canUseLayerHinting) {
this._canUseLayerHinting = conf.editor.canUseLayerHinting;
......
......@@ -268,10 +268,10 @@ const editorConfiguration: IConfigurationNode = {
'default': 'on',
'description': nls.localize('lineNumbers', "Controls the display of line numbers.")
},
'editor.scrollOff': {
'editor.cursorSurroundingLines': {
'type': 'number',
'default': EDITOR_DEFAULTS.viewInfo.scrollOff,
'description': nls.localize('scrollOff', "Controls the number of context lines above and below the cursor.")
'default': EDITOR_DEFAULTS.viewInfo.cursorSurroundingLines,
'description': nls.localize('cursorSurroundingLines', "Controls the minimal number of visible leading and trailing lines surrounding the cursor. Known as 'scrollOff' or `scrollOffset` in some other editors.")
},
'editor.renderFinalNewline': {
'type': 'boolean',
......
......@@ -269,10 +269,10 @@ export interface IEditorOptions {
*/
lineNumbers?: 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string);
/**
* Controls the number of context lines above and below the cursor.
* Controls the minimal number of visible leading and trailing lines surrounding the cursor.
* Defaults to 0.
*/
scrollOff?: number;
cursorSurroundingLines?: number;
/**
* Render last line number when the file ends with a newline.
* Defaults to true.
......@@ -987,7 +987,7 @@ export interface InternalEditorViewOptions {
readonly ariaLabel: string;
readonly renderLineNumbers: RenderLineNumbersType;
readonly renderCustomLineNumbers: ((lineNumber: number) => string) | null;
readonly scrollOff: number;
readonly cursorSurroundingLines: number;
readonly renderFinalNewline: boolean;
readonly selectOnLineNumbers: boolean;
readonly glyphMargin: boolean;
......@@ -1296,7 +1296,7 @@ export class InternalEditorOptions {
&& a.ariaLabel === b.ariaLabel
&& a.renderLineNumbers === b.renderLineNumbers
&& a.renderCustomLineNumbers === b.renderCustomLineNumbers
&& a.scrollOff === b.scrollOff
&& a.cursorSurroundingLines === b.cursorSurroundingLines
&& a.renderFinalNewline === b.renderFinalNewline
&& a.selectOnLineNumbers === b.selectOnLineNumbers
&& a.glyphMargin === b.glyphMargin
......@@ -2056,7 +2056,7 @@ export class EditorOptionsValidator {
disableMonospaceOptimizations: disableMonospaceOptimizations,
rulers: rulers,
ariaLabel: _string(opts.ariaLabel, defaults.ariaLabel),
scrollOff: _clampedInt(opts.scrollOff, defaults.cursorWidth, 0, Number.MAX_VALUE),
cursorSurroundingLines: _clampedInt(opts.cursorSurroundingLines, defaults.cursorWidth, 0, Number.MAX_VALUE),
renderLineNumbers: renderLineNumbers,
renderCustomLineNumbers: renderCustomLineNumbers,
renderFinalNewline: _boolean(opts.renderFinalNewline, defaults.renderFinalNewline),
......@@ -2180,7 +2180,7 @@ export class InternalEditorOptionsFactory {
ariaLabel: (accessibilityIsOff ? nls.localize('accessibilityOffAriaLabel', "The editor is not accessible at this time. Press Alt+F1 for options.") : opts.viewInfo.ariaLabel),
renderLineNumbers: opts.viewInfo.renderLineNumbers,
renderCustomLineNumbers: opts.viewInfo.renderCustomLineNumbers,
scrollOff: opts.viewInfo.scrollOff,
cursorSurroundingLines: opts.viewInfo.cursorSurroundingLines,
renderFinalNewline: opts.viewInfo.renderFinalNewline,
selectOnLineNumbers: opts.viewInfo.selectOnLineNumbers,
glyphMargin: opts.viewInfo.glyphMargin,
......@@ -2645,7 +2645,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = {
ariaLabel: nls.localize('editorViewAccessibleLabel', "Editor content"),
renderLineNumbers: RenderLineNumbersType.On,
renderCustomLineNumbers: null,
scrollOff: 0,
cursorSurroundingLines: 0,
renderFinalNewline: true,
selectOnLineNumbers: true,
glyphMargin: true,
......
......@@ -961,12 +961,14 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
this.expandSideOrBelow();
show(this.details.element);
this.details.element.style.maxHeight = this.maxWidgetHeight + 'px';
if (loading) {
this.details.renderLoading();
} else {
this.details.renderItem(this.list.getFocusedElements()[0], this.explainMode);
}
this.details.element.style.maxHeight = this.maxWidgetHeight + 'px';
// Reset margin-top that was set as Fix for #26416
this.listElement.style.marginTop = '0px';
......
......@@ -2650,10 +2650,10 @@ declare namespace monaco.editor {
*/
lineNumbers?: 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string);
/**
* Controls the number of context lines above and below the cursor.
* Controls the minimal number of visible leading and trailing lines surrounding the cursor.
* Defaults to 0.
*/
scrollOff?: number;
cursorSurroundingLines?: number;
/**
* Render last line number when the file ends with a newline.
* Defaults to true.
......@@ -3302,7 +3302,7 @@ declare namespace monaco.editor {
readonly ariaLabel: string;
readonly renderLineNumbers: RenderLineNumbersType;
readonly renderCustomLineNumbers: ((lineNumber: number) => string) | null;
readonly scrollOff: number;
readonly cursorSurroundingLines: number;
readonly renderFinalNewline: boolean;
readonly selectOnLineNumbers: boolean;
readonly glyphMargin: boolean;
......
......@@ -40,32 +40,35 @@ export class DialogService implements IDialogService {
buttons.push(nls.localize('cancelButton', "Cancel"));
}
const severity = this.getSeverity(confirmation.type || 'none');
const result = await this.show(severity, confirmation.message, buttons, { cancelId: 1, detail: confirmation.detail });
const dialogDisposables = new DisposableStore();
const dialog = new Dialog(
this.layoutService.container,
confirmation.message,
buttons,
{
detail: confirmation.detail,
cancelId: 1,
type: confirmation.type,
keyEventProcessor: (event: StandardKeyboardEvent) => {
EventHelper.stop(event, true);
},
checkboxChecked: confirmation.checkbox ? confirmation.checkbox.checked : undefined,
checkboxLabel: confirmation.checkbox ? confirmation.checkbox.label : undefined
});
return { confirmed: result === 0 };
}
dialogDisposables.add(dialog);
dialogDisposables.add(attachDialogStyler(dialog, this.themeService));
private getSeverity(type: DialogType): Severity {
switch (type) {
case 'error':
return Severity.Error;
case 'warning':
return Severity.Warning;
case 'question':
case 'info':
return Severity.Info;
case 'none':
default:
return Severity.Ignore;
}
const result = await dialog.show();
dialogDisposables.dispose();
return { confirmed: result.button === 0, checkboxChecked: result.checkboxChecked };
}
private getDialogType(severity: Severity): DialogType {
return (severity === Severity.Info) ? 'question' : (severity === Severity.Error) ? 'error' : (severity === Severity.Warning) ? 'warning' : 'none';
}
async show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise<number> {
this.logService.trace('DialogService#show', message);
......@@ -86,9 +89,9 @@ export class DialogService implements IDialogService {
dialogDisposables.add(dialog);
dialogDisposables.add(attachDialogStyler(dialog, this.themeService));
const choice = await dialog.show();
const result = await dialog.show();
dialogDisposables.dispose();
return choice;
return result.button;
}
}
......@@ -127,6 +127,8 @@ export const IDialogService = createDecorator<IDialogService>('dialogService');
export interface IDialogOptions {
cancelId?: number;
detail?: string;
checkboxLabel?: string;
checkboxChecked?: boolean;
}
/**
......@@ -234,4 +236,4 @@ export function getConfirmMessage(start: string, resourcesToConfirm: URI[]): str
message.push('');
return message.join('\n');
}
\ No newline at end of file
}
......@@ -222,6 +222,10 @@ export const selectListBackground = registerColor('dropdown.listBackground', { d
export const selectForeground = registerColor('dropdown.foreground', { dark: '#F0F0F0', light: null, hc: Color.white }, nls.localize('dropdownForeground', "Dropdown foreground."));
export const selectBorder = registerColor('dropdown.border', { dark: selectBackground, light: '#CECECE', hc: contrastBorder }, nls.localize('dropdownBorder', "Dropdown border."));
export const simpleCheckboxBackground = registerColor('checkbox.background', { dark: selectBackground, light: selectBackground, hc: selectBackground }, nls.localize('checkbox.background', "Background color of checkbox widget."));
export const simpleCheckboxForeground = registerColor('checkbox.foreground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, nls.localize('checkbox.foreground', "Foreground color of checkbox widget."));
export const simpleCheckboxBorder = registerColor('checkbox.border', { dark: selectBorder, light: selectBorder, hc: selectBorder }, nls.localize('checkbox.border', "Border color of checkbox widget."));
export const listFocusBackground = registerColor('list.focusBackground', { dark: '#062F4A', light: '#D6EBFF', hc: null }, nls.localize('listFocusBackground', "List/Tree background color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not."));
export const listFocusForeground = registerColor('list.focusForeground', { dark: null, light: null, hc: null }, nls.localize('listFocusForeground', "List/Tree foreground color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not."));
export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#0074E8', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not."));
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService';
import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground, treeIndentGuidesStroke, editorWidgetForeground } from 'vs/platform/theme/common/colorRegistry';
import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground, treeIndentGuidesStroke, editorWidgetForeground, simpleCheckboxBackground, simpleCheckboxBorder, simpleCheckboxForeground } from 'vs/platform/theme/common/colorRegistry';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
......@@ -341,6 +341,9 @@ export interface IDialogStyleOverrides extends IButtonStyleOverrides {
dialogBackground?: ColorIdentifier;
dialogShadow?: ColorIdentifier;
dialogBorder?: ColorIdentifier;
checkboxBorder?: ColorIdentifier;
checkboxBackground?: ColorIdentifier;
checkboxForeground?: ColorIdentifier;
}
export const defaultDialogStyles = <IDialogStyleOverrides>{
......@@ -351,7 +354,10 @@ export const defaultDialogStyles = <IDialogStyleOverrides>{
buttonForeground: buttonForeground,
buttonBackground: buttonBackground,
buttonHoverBackground: buttonHoverBackground,
buttonBorder: contrastBorder
buttonBorder: contrastBorder,
checkboxBorder: simpleCheckboxBorder,
checkboxBackground: simpleCheckboxBackground,
checkboxForeground: simpleCheckboxForeground
};
......
......@@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext } from 'vs/platform/contextkey/common/contextkeys';
import { IWindowsConfiguration } from 'vs/platform/windows/common/windows';
import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext } from 'vs/workbench/common/editor';
import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext } from 'vs/workbench/common/editor';
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
......@@ -52,17 +52,20 @@ export class WorkbenchContextKeysHandler extends Disposable {
private inputFocusedContext: IContextKey<boolean>;
private activeEditorContext: IContextKey<string | null>;
private activeEditorGroupEmpty: IContextKey<boolean>;
private activeEditorGroupIndex: IContextKey<number>;
private activeEditorGroupLast: IContextKey<boolean>;
private multipleEditorGroupsContext: IContextKey<boolean>;
private editorsVisibleContext: IContextKey<boolean>;
private textCompareEditorVisibleContext: IContextKey<boolean>;
private textCompareEditorActiveContext: IContextKey<boolean>;
private activeEditorGroupEmpty: IContextKey<boolean>;
private multipleEditorGroupsContext: IContextKey<boolean>;
private splitEditorsVerticallyContext: IContextKey<boolean>;
private workbenchStateContext: IContextKey<string>;
private workspaceFolderCountContext: IContextKey<number>;
private inZenModeContext: IContextKey<boolean>;
private isFullscreenContext: IContextKey<boolean>;
private isCenteredLayoutContext: IContextKey<boolean>;
......@@ -90,8 +93,10 @@ export class WorkbenchContextKeysHandler extends Disposable {
this._register(this.editorService.onDidActiveEditorChange(() => this.updateEditorContextKeys()));
this._register(this.editorService.onDidVisibleEditorsChange(() => this.updateEditorContextKeys()));
this._register(this.editorGroupService.onDidAddGroup(() => this.updateEditorContextKeys()));
this._register(this.editorGroupService.onDidRemoveGroup(() => this.updateEditorContextKeys()));
this._register(this.editorGroupService.onDidGroupIndexChange(() => this.updateEditorContextKeys()));
this._register(addDisposableListener(window, EventType.FOCUS_IN, () => this.updateInputContextKeys(), true));
......@@ -141,6 +146,8 @@ export class WorkbenchContextKeysHandler extends Disposable {
this.textCompareEditorVisibleContext = TextCompareEditorVisibleContext.bindTo(this.contextKeyService);
this.textCompareEditorActiveContext = TextCompareEditorActiveContext.bindTo(this.contextKeyService);
this.activeEditorGroupEmpty = ActiveEditorGroupEmptyContext.bindTo(this.contextKeyService);
this.activeEditorGroupIndex = ActiveEditorGroupIndexContext.bindTo(this.contextKeyService);
this.activeEditorGroupLast = ActiveEditorGroupLastContext.bindTo(this.contextKeyService);
this.multipleEditorGroupsContext = MultipleEditorGroupsContext.bindTo(this.contextKeyService);
// Inputs
......@@ -176,6 +183,7 @@ export class WorkbenchContextKeysHandler extends Disposable {
}
private updateEditorContextKeys(): void {
const activeGroup = this.editorGroupService.activeGroup;
const activeControl = this.editorService.activeControl;
const visibleEditors = this.editorService.visibleControls;
......@@ -194,12 +202,16 @@ export class WorkbenchContextKeysHandler extends Disposable {
this.activeEditorGroupEmpty.reset();
}
if (this.editorGroupService.count > 1) {
const groupCount = this.editorGroupService.count;
if (groupCount > 1) {
this.multipleEditorGroupsContext.set(true);
} else {
this.multipleEditorGroupsContext.reset();
}
this.activeEditorGroupIndex.set(activeGroup.index);
this.activeEditorGroupLast.set(activeGroup.index === groupCount - 1);
if (activeControl) {
this.activeEditorContext.set(activeControl.getId());
} else {
......@@ -250,4 +262,4 @@ export class WorkbenchContextKeysHandler extends Disposable {
private updateSideBarContextKeys(): void {
this.sideBarVisibleContext.set(this.layoutService.isVisible(Parts.SIDEBAR_PART));
}
}
\ No newline at end of file
}
......@@ -1076,33 +1076,15 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
toggleMaximizedPanel(): void {
if (this.workbenchGrid instanceof Grid) {
const curSize = this.workbenchGrid.getViewSize(this.panelPartView);
const size = { ...curSize };
const size = this.workbenchGrid.getViewSize(this.panelPartView);
if (!this.isPanelMaximized()) {
if (this.state.panel.position === Position.BOTTOM) {
size.height = this.panelPartView.maximumHeight;
this.state.panel.sizeBeforeMaximize = curSize.height;
} else {
size.width = this.panelPartView.maximumWidth;
this.state.panel.sizeBeforeMaximize = curSize.width;
}
this.state.panel.sizeBeforeMaximize = this.state.panel.position === Position.BOTTOM ? size.height : size.width;
this.storageService.store(Storage.PANEL_SIZE_BEFORE_MAXIMIZED, this.state.panel.sizeBeforeMaximize, StorageScope.GLOBAL);
this.setEditorHidden(true);
} else {
if (this.state.panel.position === Position.BOTTOM) {
size.height = this.state.panel.sizeBeforeMaximize;
} else {
size.width = this.state.panel.sizeBeforeMaximize;
}
// Unhide the editor if needed
if (this.state.editor.hidden) {
this.setEditorHidden(false);
}
this.setEditorHidden(false);
this.workbenchGrid.resizeView(this.panelPartView, { width: this.state.panel.position === Position.BOTTOM ? size.width : this.state.panel.sizeBeforeMaximize, height: this.state.panel.position === Position.BOTTOM ? this.state.panel.sizeBeforeMaximize : size.height });
}
this.workbenchGrid.resizeView(this.panelPartView, size);
} else {
this.workbenchGrid.layout({ toggleMaximizedPanel: true, source: Parts.PANEL_PART });
}
......@@ -1114,16 +1096,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
}
if (this.workbenchGrid instanceof Grid) {
try {
// The panel is maximum when the editor is minimum
if (this.state.panel.position === Position.BOTTOM) {
return this.workbenchGrid.getViewSize(this.editorPartView).height <= this.editorPartView.minimumHeight;
} else {
return this.workbenchGrid.getViewSize(this.editorPartView).width <= this.editorPartView.minimumWidth;
}
} catch (e) {
return false;
}
return this.state.editor.hidden;
} else {
return this.workbenchGrid.isPanelMaximized();
}
......@@ -1258,7 +1231,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
{
type: 'leaf',
data: { type: Parts.TITLEBAR_PART },
size: titleBarHeight
size: titleBarHeight,
visible: this.isVisible(Parts.TITLEBAR_PART)
},
{
type: 'branch',
......
......@@ -118,7 +118,9 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito
isEmpty(): boolean;
setActive(isActive: boolean): void;
setLabel(label: string): void;
notifyIndexChanged(newIndex: number): void;
relayout(): void;
}
......
......@@ -54,16 +54,16 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
//#region factory
static createNew(accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView {
return instantiationService.createInstance(EditorGroupView, accessor, null, label);
static createNew(accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView {
return instantiationService.createInstance(EditorGroupView, accessor, null, index);
}
static createFromSerialized(serialized: ISerializedEditorGroup, accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView {
return instantiationService.createInstance(EditorGroupView, accessor, serialized, label);
static createFromSerialized(serialized: ISerializedEditorGroup, accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView {
return instantiationService.createInstance(EditorGroupView, accessor, serialized, index);
}
static createCopy(copyFrom: IEditorGroupView, accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView {
return instantiationService.createInstance(EditorGroupView, accessor, copyFrom, label);
static createCopy(copyFrom: IEditorGroupView, accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView {
return instantiationService.createInstance(EditorGroupView, accessor, copyFrom, index);
}
//#endregion
......@@ -119,7 +119,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
constructor(
private accessor: IEditorGroupsAccessor,
from: IEditorGroupView | ISerializedEditorGroup,
private _label: string,
private _index: number,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IThemeService themeService: IThemeService,
......@@ -656,8 +656,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
return this._group;
}
get index(): number {
return this._index;
}
get label(): string {
return this._label;
return localize('groupLabel', "Group {0}", this._index + 1);
}
get disposed(): boolean {
......@@ -668,10 +672,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
return this._whenRestored;
}
setLabel(label: string): void {
if (this._label !== label) {
this._label = label;
this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_LABEL });
notifyIndexChanged(newIndex: number): void {
if (this._index !== newIndex) {
this._index = newIndex;
this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_INDEX });
}
}
......
......@@ -24,7 +24,6 @@ import { assign } from 'vs/base/common/objects';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup';
import { EditorDropTarget } from 'vs/workbench/browser/parts/editor/editorDropTarget';
import { localize } from 'vs/nls';
import { Color } from 'vs/base/common/color';
import { CenteredViewLayout } from 'vs/base/browser/ui/centered/centeredViewLayout';
import { onUnexpectedError } from 'vs/base/common/errors';
......@@ -95,6 +94,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
private readonly _onDidActiveGroupChange: Emitter<IEditorGroupView> = this._register(new Emitter<IEditorGroupView>());
readonly onDidActiveGroupChange: Event<IEditorGroupView> = this._onDidActiveGroupChange.event;
private readonly _onDidGroupIndexChange: Emitter<IEditorGroupView> = this._register(new Emitter<IEditorGroupView>());
readonly onDidGroupIndexChange: Event<IEditorGroupView> = this._onDidGroupIndexChange.event;
private readonly _onDidActivateGroup: Emitter<IEditorGroupView> = this._register(new Emitter<IEditorGroupView>());
readonly onDidActivateGroup: Event<IEditorGroupView> = this._onDidActivateGroup.event;
......@@ -424,8 +426,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
}
});
// Update labels
this.updateGroupLabels();
// Notify group index change given layout has changed
this.notifyGroupIndexChange();
// Restore focus as needed
if (restoreFocus) {
......@@ -484,25 +486,22 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
// Event
this._onDidAddGroup.fire(newGroupView);
// Update labels
this.updateGroupLabels();
// Notify group index change given a new group was added
this.notifyGroupIndexChange();
return newGroupView;
}
private doCreateGroupView(from?: IEditorGroupView | ISerializedEditorGroup | null): IEditorGroupView {
// Label: just use the number of existing groups as label
const label = this.getGroupLabel(this.count + 1);
// Create group view
let groupView: IEditorGroupView;
if (from instanceof EditorGroupView) {
groupView = EditorGroupView.createCopy(from, this, label, this.instantiationService);
groupView = EditorGroupView.createCopy(from, this, this.count, this.instantiationService);
} else if (isSerializedEditorGroup(from)) {
groupView = EditorGroupView.createFromSerialized(from, this, label, this.instantiationService);
groupView = EditorGroupView.createFromSerialized(from, this, this.count, this.instantiationService);
} else {
groupView = EditorGroupView.createNew(this, label, this.instantiationService);
groupView = EditorGroupView.createNew(this, this.count, this.instantiationService);
}
// Keep in map
......@@ -516,8 +515,13 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
// Track editor change
groupDisposables.add(groupView.onDidGroupChange(e => {
if (e.kind === GroupChangeKind.EDITOR_ACTIVE) {
this.updateContainer();
switch (e.kind) {
case GroupChangeKind.EDITOR_ACTIVE:
this.updateContainer();
break;
case GroupChangeKind.GROUP_INDEX:
this._onDidGroupIndexChange.fire(groupView);
break;
}
}));
......@@ -643,8 +647,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
this._activeGroup.focus();
}
// Update labels
this.updateGroupLabels();
// Notify group index change given a group was removed
this.notifyGroupIndexChange();
// Update container
this.updateContainer();
......@@ -675,6 +679,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
// Event
this._onDidMoveGroup.fire(sourceView);
// Notify group index change given a group was moved
this.notifyGroupIndexChange();
return sourceView;
}
......@@ -784,6 +791,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
centerLayout(active: boolean): void {
this.centeredLayoutWidget.activate(active);
this._activeGroup.focus();
}
......@@ -909,19 +917,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
toggleClass(this.container, 'empty', this.isEmpty());
}
private updateGroupLabels(): void {
// Since our labels are created using the index of the
// group, adding/removing a group might produce gaps.
// So we iterate over all groups and reassign the label
// based on the index.
this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => {
group.setLabel(this.getGroupLabel(index + 1));
});
}
private getGroupLabel(index: number): string {
return localize('groupLabel', "Group {0}", index);
private notifyGroupIndexChange(): void {
this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => group.notifyIndexChanged(index));
}
private isEmpty(): boolean {
......
......@@ -237,7 +237,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform'
'workbench.useExperimentalGridLayout': {
'type': 'boolean',
'description': nls.localize('workbench.useExperimentalGridLayout', "Enables the grid layout for the workbench. This setting may enable additional layout options for workbench components."),
'default': false,
'default': true,
'scope': ConfigurationScope.APPLICATION
}
}
......
......@@ -30,6 +30,8 @@ export const NoEditorsVisibleContext: ContextKeyExpr = EditorsVisibleContext.toN
export const TextCompareEditorVisibleContext = new RawContextKey<boolean>('textCompareEditorVisible', false);
export const TextCompareEditorActiveContext = new RawContextKey<boolean>('textCompareEditorActive', false);
export const ActiveEditorGroupEmptyContext = new RawContextKey<boolean>('activeEditorGroupEmpty', false);
export const ActiveEditorGroupIndexContext = new RawContextKey<number>('activeEditorGroupIndex', -1);
export const ActiveEditorGroupLastContext = new RawContextKey<boolean>('activeEditorGroupLast', false);
export const MultipleEditorGroupsContext = new RawContextKey<boolean>('multipleEditorGroups', false);
export const SingleEditorGroupsContext = MultipleEditorGroupsContext.toNegated();
export const InEditorZenModeContext = new RawContextKey<boolean>('inZenMode', false);
......
......@@ -141,7 +141,7 @@ export class FilesRenderer implements ITreeRenderer<ExplorerItem, FuzzyScore, IF
renderTemplate(container: HTMLElement): IFileTemplateData {
const elementDisposable = Disposable.None;
const label = this.labels.create(container, { supportHighlights: true });
const label = this.labels.create(container, { supportHighlights: true, donotSupportOcticons: true });
return { elementDisposable, label, container };
}
......
......@@ -129,7 +129,7 @@ export class OpenEditorsView extends ViewletPanel {
const index = this.getIndex(group, e.editor);
switch (e.kind) {
case GroupChangeKind.GROUP_LABEL: {
case GroupChangeKind.GROUP_INDEX: {
if (this.showGroups) {
this.list.splice(index, 1, [group]);
}
......
......@@ -16,7 +16,7 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import 'vs/css!./media/settingsWidgets';
import { localize } from 'vs/nls';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { foreground, inputBackground, inputBorder, inputForeground, listActiveSelectionBackground, listActiveSelectionForeground, listHoverBackground, listHoverForeground, listInactiveSelectionBackground, listInactiveSelectionForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, textPreformatForeground, editorWidgetBorder, textLinkActiveForeground } from 'vs/platform/theme/common/colorRegistry';
import { foreground, inputBackground, inputBorder, inputForeground, listActiveSelectionBackground, listActiveSelectionForeground, listHoverBackground, listHoverForeground, listInactiveSelectionBackground, listInactiveSelectionForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, textPreformatForeground, editorWidgetBorder, textLinkActiveForeground, simpleCheckboxBackground, simpleCheckboxForeground, simpleCheckboxBorder } from 'vs/platform/theme/common/colorRegistry';
import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler';
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { disposableTimeout } from 'vs/base/common/async';
......@@ -37,9 +37,9 @@ export const settingsSelectBorder = registerColor('settings.dropdownBorder', { d
export const settingsSelectListBorder = registerColor('settings.dropdownListBorder', { dark: editorWidgetBorder, light: editorWidgetBorder, hc: editorWidgetBorder }, localize('settingsDropdownListBorder', "(For settings editor preview) Settings editor dropdown list border. This surrounds the options and separates the options from the description."));
// Bool control colors
export const settingsCheckboxBackground = registerColor('settings.checkboxBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsCheckboxBackground', "(For settings editor preview) Settings editor checkbox background."));
export const settingsCheckboxForeground = registerColor('settings.checkboxForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsCheckboxForeground', "(For settings editor preview) Settings editor checkbox foreground."));
export const settingsCheckboxBorder = registerColor('settings.checkboxBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsCheckboxBorder', "(For settings editor preview) Settings editor checkbox border."));
export const settingsCheckboxBackground = registerColor('settings.checkboxBackground', { dark: simpleCheckboxBackground, light: simpleCheckboxBackground, hc: simpleCheckboxBackground }, localize('settingsCheckboxBackground', "(For settings editor preview) Settings editor checkbox background."));
export const settingsCheckboxForeground = registerColor('settings.checkboxForeground', { dark: simpleCheckboxForeground, light: simpleCheckboxForeground, hc: simpleCheckboxForeground }, localize('settingsCheckboxForeground', "(For settings editor preview) Settings editor checkbox foreground."));
export const settingsCheckboxBorder = registerColor('settings.checkboxBorder', { dark: simpleCheckboxBorder, light: simpleCheckboxBorder, hc: simpleCheckboxBorder }, localize('settingsCheckboxBorder', "(For settings editor preview) Settings editor checkbox border."));
// Text control colors
export const settingsTextInputBackground = registerColor('settings.textInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('textInputBoxBackground', "(For settings editor preview) Settings editor text input box background."));
......
......@@ -1130,6 +1130,12 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
}
}
// HACK: Force initialText to be non-falsy for reused terminals such that the
// conptyInheritCursor flag is passed to the node-pty, this flag can cause a Window to hang
// in Windows 10 1903 so we only want to use it when something is definitely written to the
// terminal.
shell.initialText = ' ';
// Set the new shell launch config
this._shellLaunchConfig = shell; // Must be done before calling _createProcess()
......
......@@ -66,7 +66,8 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
cols,
rows,
experimentalUseConpty: useConpty,
conptyInheritCursor: true
// This option will force conpty to not redraw the whole viewport on launch
conptyInheritCursor: useConpty && !!shellLaunchConfig.initialText
};
const cwdVerification = stat(cwd).then(async stat => {
......
......@@ -176,6 +176,11 @@ export interface IEditorGroupsService {
*/
readonly onDidLayout: Event<IDimension>;
/**
* An event for when the index of a group changes.
*/
readonly onDidGroupIndexChange: Event<IEditorGroup>;
/**
* The size of the editor groups area.
*/
......@@ -343,7 +348,7 @@ export const enum GroupChangeKind {
/* Group Changes */
GROUP_ACTIVE,
GROUP_LABEL,
GROUP_INDEX,
/* Editor Changes */
EDITOR_OPEN,
......@@ -374,6 +379,14 @@ export interface IEditorGroup {
*/
readonly id: GroupIdentifier;
/**
* A number that indicates the position of this group in the visual
* order of groups from left to right and top to bottom. The lowest
* index will likely be top-left while the largest index in most
* cases should be bottom-right, but that depends on the grid.
*/
readonly index: number;
/**
* A human readable label for the group. This label can change depending
* on the layout of all editor groups. Clients should listen on the
......
......@@ -254,30 +254,60 @@ suite('EditorGroupsService', () => {
part.dispose();
});
test('groups labels', function () {
test('groups index / labels', function () {
const part = createPart();
const rootGroup = part.groups[0];
const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT);
const downGroup = part.addGroup(rightGroup, GroupDirection.DOWN);
let labelChangeCounter = 0;
let groupIndexChangedCounter = 0;
const groupIndexChangedListener = part.onDidGroupIndexChange(() => {
groupIndexChangedCounter++;
});
let indexChangeCounter = 0;
const labelChangeListener = downGroup.onDidGroupChange(e => {
if (e.kind === GroupChangeKind.GROUP_LABEL) {
labelChangeCounter++;
if (e.kind === GroupChangeKind.GROUP_INDEX) {
indexChangeCounter++;
}
});
assert.equal(rootGroup.index, 0);
assert.equal(rightGroup.index, 1);
assert.equal(downGroup.index, 2);
assert.equal(rootGroup.label, 'Group 1');
assert.equal(rightGroup.label, 'Group 2');
assert.equal(downGroup.label, 'Group 3');
part.removeGroup(rightGroup);
assert.equal(rootGroup.index, 0);
assert.equal(downGroup.index, 1);
assert.equal(rootGroup.label, 'Group 1');
assert.equal(downGroup.label, 'Group 2');
assert.equal(labelChangeCounter, 1);
assert.equal(indexChangeCounter, 1);
assert.equal(groupIndexChangedCounter, 1);
part.moveGroup(downGroup, rootGroup, GroupDirection.UP);
assert.equal(downGroup.index, 0);
assert.equal(rootGroup.index, 1);
assert.equal(downGroup.label, 'Group 1');
assert.equal(rootGroup.label, 'Group 2');
assert.equal(indexChangeCounter, 2);
assert.equal(groupIndexChangedCounter, 3);
const newFirstGroup = part.addGroup(downGroup, GroupDirection.UP);
assert.equal(newFirstGroup.index, 0);
assert.equal(downGroup.index, 1);
assert.equal(rootGroup.index, 2);
assert.equal(newFirstGroup.label, 'Group 1');
assert.equal(downGroup.label, 'Group 2');
assert.equal(rootGroup.label, 'Group 3');
assert.equal(indexChangeCounter, 3);
assert.equal(groupIndexChangedCounter, 6);
labelChangeListener.dispose();
groupIndexChangedListener.dispose();
part.dispose();
});
......
......@@ -665,6 +665,7 @@ export class TestEditorGroupsService implements IEditorGroupsService {
onDidAddGroup: Event<IEditorGroup> = Event.None;
onDidRemoveGroup: Event<IEditorGroup> = Event.None;
onDidMoveGroup: Event<IEditorGroup> = Event.None;
onDidGroupIndexChange: Event<IEditorGroup> = Event.None;
onDidLayout: Event<IDimension> = Event.None;
orientation: any;
......@@ -761,6 +762,7 @@ export class TestEditorGroup implements IEditorGroupView {
disposed: boolean;
editors: ReadonlyArray<IEditorInput> = [];
label: string;
index: number;
whenRestored: Promise<void> = Promise.resolve(undefined);
element: HTMLElement;
minimumWidth: number;
......@@ -839,7 +841,7 @@ export class TestEditorGroup implements IEditorGroupView {
isEmpty(): boolean { return true; }
setActive(_isActive: boolean): void { }
setLabel(_label: string): void { }
notifyIndexChanged(_index: number): void { }
dispose(): void { }
toJSON(): object { return Object.create(null); }
layout(_width: number, _height: number): void { }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册