Skip to content

Commit f143959

Browse files
aiday-maralexdima
andauthored
Sticky Scroll: Adding height and emitter for height change event (microsoft#235953)
* adding height and emitter for hieght change event * adding the event to the interface * Set the height always through `_setHeight` * Switch to non-overflow mode when it would go on top of sticky scroll --------- Co-authored-by: Alexandru Dima <[email protected]>
1 parent ab7dae3 commit f143959

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/sideBySideDiff.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { IAction } from '../../../../../../base/common/actions.js';
77
import { Color } from '../../../../../../base/common/color.js';
88
import { structuralEquals } from '../../../../../../base/common/equals.js';
99
import { Disposable } from '../../../../../../base/common/lifecycle.js';
10-
import { IObservable, autorun, constObservable, derived, derivedOpts, observableValue } from '../../../../../../base/common/observable.js';
10+
import { IObservable, autorun, constObservable, derived, derivedOpts, observableFromEvent, observableValue } from '../../../../../../base/common/observable.js';
1111
import { MenuId, MenuItemAction } from '../../../../../../platform/actions/common/actions.js';
1212
import { ICommandService } from '../../../../../../platform/commands/common/commands.js';
1313
import { IInstantiationService } from '../../../../../../platform/instantiation/common/instantiation.js';
@@ -25,6 +25,7 @@ import { Position } from '../../../../../common/core/position.js';
2525
import { Range } from '../../../../../common/core/range.js';
2626
import { Command } from '../../../../../common/languages.js';
2727
import { ITextModel } from '../../../../../common/model.js';
28+
import { StickyScrollController } from '../../../../stickyScroll/browser/stickyScrollController.js';
2829
import { CustomizedMenuWorkbenchToolBar } from '../../hintsWidget/inlineCompletionsHintsWidget.js';
2930
import { PathBuilder, StatusBarViewItem, getOffsetForPos, mapOutFalsy, maxContentWidthInRange, n } from './utils.js';
3031
import { InlineEditWithChanges } from './viewAndDiffProducer.js';
@@ -396,13 +397,17 @@ export class InlineEditsSideBySideDiff extends Disposable {
396397
};
397398
});
398399

400+
private _stickyScrollController = StickyScrollController.get(this._editorObs.editor);
401+
private readonly _stickyScrollHeight = this._stickyScrollController ? observableFromEvent(this._stickyScrollController.onDidChangeStickyScrollHeight, () => this._stickyScrollController!.stickyScrollWidgetHeight) : constObservable(0);
402+
399403
private readonly _shouldOverflow = derived(reader => {
400404
const range = this._edit.read(reader)?.originalLineRange;
401405
if (!range) {
402406
return false;
403407
}
408+
const stickyScrollHeight = this._stickyScrollHeight.read(reader);
404409
const top = this._editor.getTopForLineNumber(range.startLineNumber) - this._editorObs.scrollTop.read(reader);
405-
return top > 0;
410+
return top > stickyScrollHeight;
406411
});
407412

408413

src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ import { StickyRange } from './stickyScrollElement.js';
2929
import { IMouseEvent, StandardMouseEvent } from '../../../../base/browser/mouseEvent.js';
3030
import { FoldingController } from '../../folding/browser/folding.js';
3131
import { FoldingModel, toggleCollapseState } from '../../folding/browser/foldingModel.js';
32+
import { Emitter, Event } from '../../../../base/common/event.js';
3233

3334
export interface IStickyScrollController {
3435
get stickyScrollCandidateProvider(): IStickyLineCandidateProvider;
3536
get stickyScrollWidgetState(): StickyScrollWidgetState;
37+
readonly stickyScrollWidgetHeight: number;
3638
isFocused(): boolean;
3739
focus(): void;
3840
focusNext(): void;
@@ -41,6 +43,7 @@ export interface IStickyScrollController {
4143
findScrollWidgetState(): StickyScrollWidgetState;
4244
dispose(): void;
4345
selectEditor(): void;
46+
onDidChangeStickyScrollHeight: Event<{ height: number }>;
4447
}
4548

4649
export class StickyScrollController extends Disposable implements IEditorContribution, IStickyScrollController {
@@ -71,6 +74,9 @@ export class StickyScrollController extends Disposable implements IEditorContrib
7174
private _showEndForLine: number | undefined;
7275
private _minRebuildFromLine: number | undefined;
7376

77+
private readonly _onDidChangeStickyScrollHeight = this._register(new Emitter<{ height: number }>());
78+
public readonly onDidChangeStickyScrollHeight = this._onDidChangeStickyScrollHeight.event;
79+
7480
constructor(
7581
private readonly _editor: ICodeEditor,
7682
@IContextMenuService private readonly _contextMenuService: IContextMenuService,
@@ -118,6 +124,9 @@ export class StickyScrollController extends Disposable implements IEditorContrib
118124
this._register(dom.addDisposableListener(stickyScrollDomNode, dom.EventType.MOUSE_DOWN, (e) => {
119125
this._onMouseDown = true;
120126
}));
127+
this._register(this._stickyScrollWidget.onDidChangeStickyScrollHeight((e) => {
128+
this._onDidChangeStickyScrollHeight.fire(e);
129+
}));
121130
this._onDidResize();
122131
this._readConfiguration();
123132
}
@@ -130,6 +139,10 @@ export class StickyScrollController extends Disposable implements IEditorContrib
130139
return this._widgetState;
131140
}
132141

142+
get stickyScrollWidgetHeight(): number {
143+
return this._stickyScrollWidget.height;
144+
}
145+
133146
public static get(editor: ICodeEditor): IStickyScrollController | null {
134147
return editor.getContribution<StickyScrollController>(StickyScrollController.ID);
135148
}
@@ -413,6 +426,7 @@ export class StickyScrollController extends Disposable implements IEditorContrib
413426
const options = this._editor.getOption(EditorOption.stickyScroll);
414427
if (options.enabled === false) {
415428
this._editor.removeOverlayWidget(this._stickyScrollWidget);
429+
this._resetState();
416430
this._sessionStore.clear();
417431
this._enabled = false;
418432
return;

src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { LineDecoration } from '../../../common/viewLayout/lineDecorations.js';
1919
import { CharacterMapping, RenderLineInput, renderViewLine } from '../../../common/viewLayout/viewLineRenderer.js';
2020
import { foldingCollapsedIcon, foldingExpandedIcon } from '../../folding/browser/foldingDecorations.js';
2121
import { FoldingModel } from '../../folding/browser/foldingModel.js';
22+
import { Emitter } from '../../../../base/common/event.js';
2223

2324
export class StickyScrollWidgetState {
2425
constructor(
@@ -62,6 +63,12 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
6263
private _lastLineRelativePosition: number = 0;
6364
private _minContentWidthInPx: number = 0;
6465
private _isOnGlyphMargin: boolean = false;
66+
private _height: number = -1;
67+
68+
public get height(): number { return this._height; }
69+
70+
private readonly _onDidChangeStickyScrollHeight = this._register(new Emitter<{ height: number }>());
71+
public readonly onDidChangeStickyScrollHeight = this._onDidChangeStickyScrollHeight.event;
6572

6673
constructor(
6774
private readonly _editor: ICodeEditor
@@ -81,6 +88,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
8188
this._rootDomNode.classList.toggle('peek', _editor instanceof EmbeddedCodeEditorWidget);
8289
this._rootDomNode.appendChild(this._lineNumbersDomNode);
8390
this._rootDomNode.appendChild(this._linesDomNodeScrollable);
91+
this._setHeight(0);
8492

8593
const updateScrollLeftPosition = () => {
8694
this._linesDomNode.style.left = this._editor.getOption(EditorOption.stickyScroll).scrollWithEditor ? `-${this._editor.getScrollLeft()}px` : '0px';
@@ -193,7 +201,6 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
193201
}
194202
// Keep the lines that need to be updated
195203
this._renderedStickyLines = this._renderedStickyLines.slice(0, clearFromLine);
196-
this._rootDomNode.style.display = 'none';
197204
}
198205

199206
private _useFoldingOpacityTransition(requireTransitions: boolean) {
@@ -213,6 +220,8 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
213220
private async _renderRootNode(state: StickyScrollWidgetState | undefined, foldingModel: FoldingModel | undefined, rebuildFromLine: number): Promise<void> {
214221
this._clearStickyLinesFromLine(rebuildFromLine);
215222
if (!state) {
223+
// make sure the dom is 0 height and display:none
224+
this._setHeight(0);
216225
return;
217226
}
218227
// For existing sticky lines update the top and z-index
@@ -237,16 +246,31 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget {
237246
}
238247

239248
const widgetHeight = this._lineNumbers.length * this._lineHeight + this._lastLineRelativePosition;
240-
this._rootDomNode.style.display = 'block';
241-
this._lineNumbersDomNode.style.height = `${widgetHeight}px`;
242-
this._linesDomNodeScrollable.style.height = `${widgetHeight}px`;
243-
this._rootDomNode.style.height = `${widgetHeight}px`;
249+
this._setHeight(widgetHeight);
244250

245251
this._rootDomNode.style.marginLeft = '0px';
246252
this._minContentWidthInPx = Math.max(...this._renderedStickyLines.map(l => l.scrollWidth)) + layoutInfo.verticalScrollbarWidth;
247253
this._editor.layoutOverlayWidget(this);
248254
}
249255

256+
private _setHeight(height: number): void {
257+
if (this._height === height) {
258+
return;
259+
}
260+
this._height = height;
261+
262+
if (this._height === 0) {
263+
this._rootDomNode.style.display = 'none';
264+
} else {
265+
this._rootDomNode.style.display = 'block';
266+
this._lineNumbersDomNode.style.height = `${this._height}px`;
267+
this._linesDomNodeScrollable.style.height = `${this._height}px`;
268+
this._rootDomNode.style.height = `${this._height}px`;
269+
}
270+
271+
this._onDidChangeStickyScrollHeight.fire({ height: this._height });
272+
}
273+
250274
private _setFoldingHoverListeners(): void {
251275
const showFoldingControls: 'mouseover' | 'always' | 'never' = this._editor.getOption(EditorOption.showFoldingControls);
252276
if (showFoldingControls !== 'mouseover') {

0 commit comments

Comments
 (0)