@@ -113,6 +113,14 @@ export class ListService implements IListService {
113113 }
114114}
115115
116+ export const RawWorkbenchListScrollAtBoundaryContextKey = new RawContextKey < 'none' | 'top' | 'bottom' | 'both' > ( 'listScrollAtBoundary' , 'none' ) ;
117+ export const WorkbenchListScrollAtTopContextKey = ContextKeyExpr . or (
118+ RawWorkbenchListScrollAtBoundaryContextKey . isEqualTo ( 'top' ) ,
119+ RawWorkbenchListScrollAtBoundaryContextKey . isEqualTo ( 'both' ) ) ;
120+ export const WorkbenchListScrollAtBottomContextKey = ContextKeyExpr . or (
121+ RawWorkbenchListScrollAtBoundaryContextKey . isEqualTo ( 'bottom' ) ,
122+ RawWorkbenchListScrollAtBoundaryContextKey . isEqualTo ( 'both' ) ) ;
123+
116124export const RawWorkbenchListFocusContextKey = new RawContextKey < boolean > ( 'listFocus' , true ) ;
117125export const WorkbenchListSupportsMultiSelectContextKey = new RawContextKey < boolean > ( 'listSupportsMultiselect' , true ) ;
118126export const WorkbenchListFocusContextKey = ContextKeyExpr . and ( RawWorkbenchListFocusContextKey , ContextKeyExpr . not ( InputFocusedContextKey ) ) ;
@@ -139,6 +147,33 @@ function createScopedContextKeyService(contextKeyService: IContextKeyService, wi
139147 return result ;
140148}
141149
150+ // Note: We must declare IScrollObservarable as the arithmetic of concrete classes,
151+ // instead of object type like { onDidScroll: Event<any>; ... }. The latter will not mark
152+ // those properties as referenced during tree-shaking, causing them to be shaked away.
153+ type IScrollObservarable = Exclude < WorkbenchListWidget , WorkbenchPagedList < any > > | List < any > ;
154+
155+ function createScrollObserver ( contextKeyService : IContextKeyService , widget : IScrollObservarable ) : IDisposable {
156+ const listScrollAt = RawWorkbenchListScrollAtBoundaryContextKey . bindTo ( contextKeyService ) ;
157+ const update = ( ) => {
158+ const atTop = widget . scrollTop === 0 ;
159+
160+ // We need a threshold `1` since scrollHeight is rounded.
161+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#determine_if_an_element_has_been_totally_scrolled
162+ const atBottom = widget . scrollHeight - widget . renderHeight - widget . scrollTop < 1 ;
163+ if ( atTop && atBottom ) {
164+ listScrollAt . set ( 'both' ) ;
165+ } else if ( atTop ) {
166+ listScrollAt . set ( 'top' ) ;
167+ } else if ( atBottom ) {
168+ listScrollAt . set ( 'bottom' ) ;
169+ } else {
170+ listScrollAt . set ( 'none' ) ;
171+ }
172+ } ;
173+ update ( ) ;
174+ return widget . onDidScroll ( update ) ;
175+ }
176+
142177const multiSelectModifierSettingKey = 'workbench.list.multiSelectModifier' ;
143178const openModeSettingKey = 'workbench.list.openMode' ;
144179const horizontalScrollingKey = 'workbench.list.horizontalScrolling' ;
@@ -259,6 +294,8 @@ export class WorkbenchList<T> extends List<T> {
259294
260295 this . contextKeyService = createScopedContextKeyService ( contextKeyService , this ) ;
261296
297+ this . disposables . add ( createScrollObserver ( this . contextKeyService , this ) ) ;
298+
262299 this . listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey . bindTo ( this . contextKeyService ) ;
263300 this . listSupportsMultiSelect . set ( options . multipleSelectionSupport !== false ) ;
264301
@@ -390,6 +427,8 @@ export class WorkbenchPagedList<T> extends PagedList<T> {
390427
391428 this . contextKeyService = createScopedContextKeyService ( contextKeyService , this ) ;
392429
430+ this . disposables . add ( createScrollObserver ( this . contextKeyService , this . widget ) ) ;
431+
393432 this . horizontalScrolling = options . horizontalScrolling ;
394433
395434 this . listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey . bindTo ( this . contextKeyService ) ;
@@ -514,6 +553,8 @@ export class WorkbenchTable<TRow> extends Table<TRow> {
514553
515554 this . contextKeyService = createScopedContextKeyService ( contextKeyService , this ) ;
516555
556+ this . disposables . add ( createScrollObserver ( this . contextKeyService , this ) ) ;
557+
517558 this . listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey . bindTo ( this . contextKeyService ) ;
518559 this . listSupportsMultiSelect . set ( options . multipleSelectionSupport !== false ) ;
519560
@@ -1165,6 +1206,8 @@ class WorkbenchTreeInternals<TInput, T, TFilterData> {
11651206 ) {
11661207 this . contextKeyService = createScopedContextKeyService ( contextKeyService , tree ) ;
11671208
1209+ this . disposables . push ( createScrollObserver ( this . contextKeyService , tree ) ) ;
1210+
11681211 this . listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey . bindTo ( this . contextKeyService ) ;
11691212 this . listSupportsMultiSelect . set ( options . multipleSelectionSupport !== false ) ;
11701213
0 commit comments