@@ -113,6 +113,14 @@ export class ListService implements IListService {
113
113
}
114
114
}
115
115
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
+
116
124
export const RawWorkbenchListFocusContextKey = new RawContextKey < boolean > ( 'listFocus' , true ) ;
117
125
export const WorkbenchListSupportsMultiSelectContextKey = new RawContextKey < boolean > ( 'listSupportsMultiselect' , true ) ;
118
126
export const WorkbenchListFocusContextKey = ContextKeyExpr . and ( RawWorkbenchListFocusContextKey , ContextKeyExpr . not ( InputFocusedContextKey ) ) ;
@@ -139,6 +147,33 @@ function createScopedContextKeyService(contextKeyService: IContextKeyService, wi
139
147
return result ;
140
148
}
141
149
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
+
142
177
const multiSelectModifierSettingKey = 'workbench.list.multiSelectModifier' ;
143
178
const openModeSettingKey = 'workbench.list.openMode' ;
144
179
const horizontalScrollingKey = 'workbench.list.horizontalScrolling' ;
@@ -259,6 +294,8 @@ export class WorkbenchList<T> extends List<T> {
259
294
260
295
this . contextKeyService = createScopedContextKeyService ( contextKeyService , this ) ;
261
296
297
+ this . disposables . add ( createScrollObserver ( this . contextKeyService , this ) ) ;
298
+
262
299
this . listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey . bindTo ( this . contextKeyService ) ;
263
300
this . listSupportsMultiSelect . set ( options . multipleSelectionSupport !== false ) ;
264
301
@@ -390,6 +427,8 @@ export class WorkbenchPagedList<T> extends PagedList<T> {
390
427
391
428
this . contextKeyService = createScopedContextKeyService ( contextKeyService , this ) ;
392
429
430
+ this . disposables . add ( createScrollObserver ( this . contextKeyService , this . widget ) ) ;
431
+
393
432
this . horizontalScrolling = options . horizontalScrolling ;
394
433
395
434
this . listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey . bindTo ( this . contextKeyService ) ;
@@ -514,6 +553,8 @@ export class WorkbenchTable<TRow> extends Table<TRow> {
514
553
515
554
this . contextKeyService = createScopedContextKeyService ( contextKeyService , this ) ;
516
555
556
+ this . disposables . add ( createScrollObserver ( this . contextKeyService , this ) ) ;
557
+
517
558
this . listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey . bindTo ( this . contextKeyService ) ;
518
559
this . listSupportsMultiSelect . set ( options . multipleSelectionSupport !== false ) ;
519
560
@@ -1165,6 +1206,8 @@ class WorkbenchTreeInternals<TInput, T, TFilterData> {
1165
1206
) {
1166
1207
this . contextKeyService = createScopedContextKeyService ( contextKeyService , tree ) ;
1167
1208
1209
+ this . disposables . push ( createScrollObserver ( this . contextKeyService , tree ) ) ;
1210
+
1168
1211
this . listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey . bindTo ( this . contextKeyService ) ;
1169
1212
this . listSupportsMultiSelect . set ( options . multipleSelectionSupport !== false ) ;
1170
1213
0 commit comments