Skip to content

Commit 5ce780c

Browse files
terrengbenibenj
andauthored
Implement new option to control title scrollbar visibility (#246161)
* Implement titleScrollbarVisibility option * Fix --------- Co-authored-by: Benjamin Christopher Simmonds <[email protected]>
1 parent 3cbaddc commit 5ce780c

File tree

7 files changed

+66
-3
lines changed

7 files changed

+66
-3
lines changed

src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export class BreadcrumbsWidget {
6565
constructor(
6666
container: HTMLElement,
6767
horizontalScrollbarSize: number,
68+
horizontalScrollbarVisibility: ScrollbarVisibility = ScrollbarVisibility.Auto,
6869
separatorIcon: ThemeIcon,
6970
styles: IBreadcrumbsWidgetStyles
7071
) {
@@ -74,7 +75,7 @@ export class BreadcrumbsWidget {
7475
this._domNode.setAttribute('role', 'list');
7576
this._scrollable = new DomScrollableElement(this._domNode, {
7677
vertical: ScrollbarVisibility.Hidden,
77-
horizontal: ScrollbarVisibility.Auto,
78+
horizontal: horizontalScrollbarVisibility,
7879
horizontalScrollbarSize,
7980
useShadows: false,
8081
scrollYToX: true
@@ -99,6 +100,12 @@ export class BreadcrumbsWidget {
99100
});
100101
}
101102

103+
setHorizontalScrollbarVisibility(visibility: ScrollbarVisibility) {
104+
this._scrollable.updateOptions({
105+
horizontal: visibility
106+
});
107+
}
108+
102109
dispose(): void {
103110
this._disposables.dispose();
104111
this._pendingLayout?.dispose();

src/vs/workbench/browser/parts/editor/breadcrumbs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export abstract class BreadcrumbsConfig<T> {
7373
static readonly SymbolSortOrder = BreadcrumbsConfig._stub<'position' | 'name' | 'type'>('breadcrumbs.symbolSortOrder');
7474
static readonly Icons = BreadcrumbsConfig._stub<boolean>('breadcrumbs.icons');
7575
static readonly TitleScrollbarSizing = BreadcrumbsConfig._stub<IEditorPartOptions['titleScrollbarSizing']>('workbench.editor.titleScrollbarSizing');
76+
static readonly TitleScrollbarVisibility = BreadcrumbsConfig._stub<IEditorPartOptions['titleScrollbarVisibility']>('workbench.editor.titleScrollbarVisibility');
7677

7778
static readonly FileExcludes = BreadcrumbsConfig._stub<glob.IExpression>('files.exclude');
7879

src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import { BreadcrumbsModel, FileElement, OutlineElement2 } from './breadcrumbsMod
4646
import { BreadcrumbsFilePicker, BreadcrumbsOutlinePicker, BreadcrumbsPicker } from './breadcrumbsPicker.js';
4747
import { IEditorGroupView } from './editor.js';
4848
import './media/breadcrumbscontrol.css';
49+
import { ScrollbarVisibility } from '../../../../base/common/scrollable.js';
4950

5051
class OutlineItem extends BreadcrumbsItem {
5152

@@ -215,6 +216,12 @@ export class BreadcrumbsControl {
215216
large: 8
216217
};
217218

219+
private static readonly SCROLLBAR_VISIBILITY = {
220+
auto: ScrollbarVisibility.Auto,
221+
visible: ScrollbarVisibility.Visible,
222+
hidden: ScrollbarVisibility.Hidden
223+
};
224+
218225
static readonly Payload_Reveal = {};
219226
static readonly Payload_RevealAside = {};
220227
static readonly Payload_Pick = {};
@@ -230,6 +237,7 @@ export class BreadcrumbsControl {
230237
private readonly _cfUseQuickPick: BreadcrumbsConfig<boolean>;
231238
private readonly _cfShowIcons: BreadcrumbsConfig<boolean>;
232239
private readonly _cfTitleScrollbarSizing: BreadcrumbsConfig<IEditorPartOptions['titleScrollbarSizing']>;
240+
private readonly _cfTitleScrollbarVisibility: BreadcrumbsConfig<IEditorPartOptions['titleScrollbarVisibility']>;
233241

234242
readonly domNode: HTMLDivElement;
235243
private readonly _widget: BreadcrumbsWidget;
@@ -267,12 +275,21 @@ export class BreadcrumbsControl {
267275
this._cfUseQuickPick = BreadcrumbsConfig.UseQuickPick.bindTo(configurationService);
268276
this._cfShowIcons = BreadcrumbsConfig.Icons.bindTo(configurationService);
269277
this._cfTitleScrollbarSizing = BreadcrumbsConfig.TitleScrollbarSizing.bindTo(configurationService);
278+
this._cfTitleScrollbarVisibility = BreadcrumbsConfig.TitleScrollbarVisibility.bindTo(configurationService);
270279

271280
this._labels = this._instantiationService.createInstance(ResourceLabels, DEFAULT_LABELS_CONTAINER);
272281

273282
const sizing = this._cfTitleScrollbarSizing.getValue() ?? 'default';
274283
const styles = _options.widgetStyles ?? defaultBreadcrumbsWidgetStyles;
275-
this._widget = new BreadcrumbsWidget(this.domNode, BreadcrumbsControl.SCROLLBAR_SIZES[sizing], separatorIcon, styles);
284+
const visibility = this._cfTitleScrollbarVisibility?.getValue() ?? 'auto';
285+
286+
this._widget = new BreadcrumbsWidget(
287+
this.domNode,
288+
BreadcrumbsControl.SCROLLBAR_SIZES[sizing],
289+
BreadcrumbsControl.SCROLLBAR_VISIBILITY[visibility],
290+
separatorIcon,
291+
styles
292+
);
276293
this._widget.onDidSelectItem(this._onSelectEvent, this, this._disposables);
277294
this._widget.onDidFocusItem(this._onFocusEvent, this, this._disposables);
278295
this._widget.onDidChangeFocus(this._updateCkBreadcrumbsActive, this, this._disposables);
@@ -414,11 +431,16 @@ export class BreadcrumbsControl {
414431

415432
const updateScrollbarSizing = () => {
416433
const sizing = this._cfTitleScrollbarSizing.getValue() ?? 'default';
434+
const visibility = this._cfTitleScrollbarVisibility?.getValue() ?? 'auto';
435+
417436
this._widget.setHorizontalScrollbarSize(BreadcrumbsControl.SCROLLBAR_SIZES[sizing]);
437+
this._widget.setHorizontalScrollbarVisibility(BreadcrumbsControl.SCROLLBAR_VISIBILITY[visibility]);
418438
};
419439
updateScrollbarSizing();
420440
const updateScrollbarSizeListener = this._cfTitleScrollbarSizing.onDidChange(updateScrollbarSizing);
441+
const updateScrollbarVisibilityListener = this._cfTitleScrollbarVisibility.onDidChange(updateScrollbarSizing);
421442
this._breadcrumbsDisposables.add(updateScrollbarSizeListener);
443+
this._breadcrumbsDisposables.add(updateScrollbarVisibilityListener);
422444

423445
// close picker on hide/update
424446
this._breadcrumbsDisposables.add({

src/vs/workbench/browser/parts/editor/editor.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const DEFAULT_EDITOR_PART_OPTIONS: IEditorPartOptions = {
4343
tabHeight: 'default',
4444
preventPinnedEditorClose: 'keyboardAndMouse',
4545
titleScrollbarSizing: 'default',
46+
titleScrollbarVisibility: 'auto',
4647
focusRecentEditorAfterClose: true,
4748
showIcons: true,
4849
hasIcons: true, // 'vs-seti' is our default icon theme
@@ -151,6 +152,7 @@ function validateEditorPartOptions(options: IEditorPartOptions): IEditorPartOpti
151152
'tabHeight': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['tabHeight'], ['default', 'compact']),
152153
'preventPinnedEditorClose': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['preventPinnedEditorClose'], ['keyboardAndMouse', 'keyboard', 'mouse', 'never']),
153154
'titleScrollbarSizing': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['titleScrollbarSizing'], ['default', 'large']),
155+
'titleScrollbarVisibility': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['titleScrollbarVisibility'], ['auto', 'visible', 'hidden']),
154156
'openPositioning': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['openPositioning'], ['left', 'right', 'first', 'last']),
155157
'openSideBySideDirection': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['openSideBySideDirection'], ['right', 'down']),
156158
'labelFormat': new EnumVerifier(DEFAULT_EDITOR_PART_OPTIONS['labelFormat'], ['default', 'short', 'medium', 'long']),

src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ export class MultiEditorTabsControl extends EditorTabsControl {
201201

202202
private createTabsScrollbar(scrollable: HTMLElement): ScrollableElement {
203203
const tabsScrollbar = this._register(new ScrollableElement(scrollable, {
204-
horizontal: ScrollbarVisibility.Auto,
204+
horizontal: this.getTabsScrollbarVisibility(),
205205
horizontalScrollbarSize: this.getTabsScrollbarSizing(),
206206
vertical: ScrollbarVisibility.Hidden,
207207
scrollYToX: true,
@@ -223,6 +223,12 @@ export class MultiEditorTabsControl extends EditorTabsControl {
223223
});
224224
}
225225

226+
private updateTabsScrollbarVisibility(): void {
227+
this.tabsScrollbar?.updateOptions({
228+
horizontal: this.getTabsScrollbarVisibility()
229+
});
230+
}
231+
226232
private updateTabSizing(fromEvent: boolean): void {
227233
const [tabsContainer, tabSizingFixedDisposables] = assertReturnsAllDefined(this.tabsContainer, this.tabSizingFixedDisposables);
228234

@@ -271,6 +277,14 @@ export class MultiEditorTabsControl extends EditorTabsControl {
271277
return MultiEditorTabsControl.SCROLLBAR_SIZES.large;
272278
}
273279

280+
private getTabsScrollbarVisibility(): ScrollbarVisibility {
281+
switch (this.groupsView.partOptions.titleScrollbarVisibility) {
282+
case 'visible': return ScrollbarVisibility.Visible;
283+
case 'hidden': return ScrollbarVisibility.Hidden;
284+
default: return ScrollbarVisibility.Auto;
285+
}
286+
}
287+
274288
private registerTabsContainerListeners(tabsContainer: HTMLElement, tabsScrollbar: ScrollableElement): void {
275289

276290
// Forward scrolling inside the container to our custom scrollbar
@@ -733,6 +747,11 @@ export class MultiEditorTabsControl extends EditorTabsControl {
733747
this.updateTabsScrollbarSizing();
734748
}
735749

750+
// Update tabs scrollbar visibility
751+
if (oldOptions.titleScrollbarVisibility !== newOptions.titleScrollbarVisibility) {
752+
this.updateTabsScrollbarVisibility();
753+
}
754+
736755
// Update editor actions
737756
if (oldOptions.alwaysShowEditorActions !== newOptions.alwaysShowEditorActions) {
738757
this.updateEditorActionsToolbar();

src/vs/workbench/browser/workbench.contribution.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
4545
description: localize('tabScrollbarHeight', "Controls the height of the scrollbars used for tabs and breadcrumbs in the editor title area."),
4646
default: 'default',
4747
},
48+
'workbench.editor.titleScrollbarVisibility': {
49+
type: 'string',
50+
enum: ['auto', 'visible', 'hidden'],
51+
enumDescriptions: [
52+
localize('workbench.editor.titleScrollbarVisibility.auto', "The horizontal scrollbar will be visible only when necessary."),
53+
localize('workbench.editor.titleScrollbarVisibility.visible', "The horizontal scrollbar will always be visible."),
54+
localize('workbench.editor.titleScrollbarVisibility.hidden', "The horizontal scrollbar will always be hidden.")
55+
],
56+
description: localize('titleScrollbarVisibility', "Controls the visibility of the scrollbars used for tabs and breadcrumbs in the editor title area."),
57+
default: 'auto',
58+
},
4859
[LayoutSettings.EDITOR_TABS_MODE]: {
4960
'type': 'string',
5061
'enum': [EditorTabsMode.MULTIPLE, EditorTabsMode.SINGLE, EditorTabsMode.NONE],

src/vs/workbench/common/editor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,7 @@ interface IEditorPartConfiguration {
12411241
tabHeight?: 'default' | 'compact';
12421242
preventPinnedEditorClose?: PreventPinnedEditorClose;
12431243
titleScrollbarSizing?: 'default' | 'large';
1244+
titleScrollbarVisibility?: 'auto' | 'visible' | 'hidden';
12441245
focusRecentEditorAfterClose?: boolean;
12451246
showIcons?: boolean;
12461247
enablePreview?: boolean;

0 commit comments

Comments
 (0)