@@ -24,6 +24,7 @@ import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableEle
24
24
25
25
export interface IPointerHandlerHelper {
26
26
viewDomNode :HTMLElement ;
27
+ overflowWidgetsDomNode :HTMLElement | null ;
27
28
linesContentDomNode :HTMLElement ;
28
29
viewLinesDomNode :HTMLElement ;
29
30
@@ -62,6 +63,8 @@ export class MouseHandler extends ViewEventHandler {
62
63
private lastMouseLeaveTime :number ;
63
64
private _height :number ;
64
65
private _mouseLeaveMonitor :IDisposable | null = null ;
66
+ private _mouseOnOverflowWidgetsDomNode :boolean = false ;
67
+ private _mouseOnViewDomNode :boolean = false ;
65
68
66
69
constructor ( context :ViewContext , viewController :ViewController , viewHelper :IPointerHandlerHelper ) {
67
70
super ( ) ;
@@ -76,7 +79,7 @@ export class MouseHandler extends ViewEventHandler {
76
79
this . viewController ,
77
80
this . viewHelper ,
78
81
this . mouseTargetFactory ,
79
- ( e , testEventTarget ) => this . _createMouseTarget ( e , testEventTarget ) ,
82
+ ( e , testEventTarget ) => this . _createMouseTargetForView ( e , testEventTarget ) ,
80
83
( e ) => this . _getMouseColumn ( e )
81
84
) ) ;
82
85
@@ -88,7 +91,8 @@ export class MouseHandler extends ViewEventHandler {
88
91
this . _register ( mouseEvents . onContextMenu ( this . viewHelper . viewDomNode , ( e ) => this . _onContextMenu ( e , true ) ) ) ;
89
92
90
93
this . _register ( mouseEvents . onMouseMove ( this . viewHelper . viewDomNode , ( e ) => {
91
- this . _onMouseMove ( e ) ;
94
+ this . _mouseOnViewDomNode = true ;
95
+ this . _onMouseMoveOverView ( e ) ;
92
96
93
97
// See https://github.com/microsoft/vscode/issues/138789
94
98
// When moving the mouse really quickly, the browser sometimes forgets to
@@ -101,15 +105,45 @@ export class MouseHandler extends ViewEventHandler {
101
105
this . _mouseLeaveMonitor = dom . addDisposableListener ( this . viewHelper . viewDomNode . ownerDocument , 'mousemove' , ( e ) => {
102
106
if ( ! this . viewHelper . viewDomNode . contains ( e . target as Node | null ) ) {
103
107
// went outside the editor!
104
- this . _onMouseLeave ( new EditorMouseEvent ( e , false , this . viewHelper . viewDomNode ) ) ;
108
+ this . _mouseOnViewDomNode = false ;
109
+ setTimeout ( ( ) => {
110
+ if ( ! this . _mouseOnOverflowWidgetsDomNode ) {
111
+ this . _onMouseLeave ( new EditorMouseEvent ( e , false , this . viewHelper . viewDomNode ) ) ;
112
+ }
113
+ } , 0 ) ;
105
114
}
106
115
} ) ;
107
116
}
108
117
} ) ) ;
109
118
110
119
this . _register ( mouseEvents . onMouseUp ( this . viewHelper . viewDomNode , ( e ) => this . _onMouseUp ( e ) ) ) ;
111
120
112
- this . _register ( mouseEvents . onMouseLeave ( this . viewHelper . viewDomNode , ( e ) => this . _onMouseLeave ( e ) ) ) ;
121
+ this . _register ( mouseEvents . onMouseLeave ( this . viewHelper . viewDomNode , ( e ) => {
122
+ this . _mouseOnViewDomNode = false ;
123
+ setTimeout ( ( ) => {
124
+ if ( ! this . _mouseOnOverflowWidgetsDomNode ) {
125
+ this . _onMouseLeave ( e ) ;
126
+ }
127
+ } , 0 ) ;
128
+ } ) ) ;
129
+
130
+ const overflowWidgetsDomNode = this . viewHelper . overflowWidgetsDomNode ;
131
+ if ( overflowWidgetsDomNode ) {
132
+ this . _register ( mouseEvents . onMouseMove ( overflowWidgetsDomNode , ( e ) => {
133
+ this . _mouseOnOverflowWidgetsDomNode = true ;
134
+ this . _mouseLeaveMonitor ?. dispose ( ) ;
135
+ this . _mouseLeaveMonitor = null ;
136
+ this . _onMouseMoveOverOverflowWidgetsDomNode ( e ) ;
137
+ } ) ) ;
138
+ this . _register ( mouseEvents . onMouseLeave ( overflowWidgetsDomNode , ( e ) => {
139
+ this . _mouseOnOverflowWidgetsDomNode = false ;
140
+ setTimeout ( ( ) => {
141
+ if ( ! this . _mouseOnViewDomNode ) {
142
+ this . _onMouseLeave ( e ) ;
143
+ }
144
+ } , 0 ) ;
145
+ } ) ) ;
146
+ }
113
147
114
148
// `pointerdown` events can't be used to determine if there's a double click, or triple click
115
149
// because their `e.detail` is always 0.
@@ -234,10 +268,10 @@ export class MouseHandler extends ViewEventHandler {
234
268
}
235
269
236
270
const relativePos = createCoordinatesRelativeToEditor ( this . viewHelper . viewDomNode , editorPos , pos ) ;
237
- return this . mouseTargetFactory . createMouseTarget ( this . viewHelper . getLastRenderData ( ) , editorPos , pos , relativePos , null ) ;
271
+ return this . mouseTargetFactory . createMouseTargetForView ( this . viewHelper . getLastRenderData ( ) , editorPos , pos , relativePos , null ) ;
238
272
}
239
273
240
- protected _createMouseTarget ( e :EditorMouseEvent , testEventTarget :boolean ) :IMouseTarget {
274
+ protected _createMouseTargetForView ( e :EditorMouseEvent , testEventTarget :boolean ) :IMouseTarget {
241
275
let target = e . target ;
242
276
if ( ! this . viewHelper . viewDomNode . contains ( target ) ) {
243
277
const shadowRoot = dom . getShadowRoot ( this . viewHelper . viewDomNode ) ;
@@ -247,7 +281,11 @@ export class MouseHandler extends ViewEventHandler {
247
281
) ;
248
282
}
249
283
}
250
- return this . mouseTargetFactory . createMouseTarget ( this . viewHelper . getLastRenderData ( ) , e . editorPos , e . pos , e . relativePos , testEventTarget ?target :null ) ;
284
+ return this . mouseTargetFactory . createMouseTargetForView ( this . viewHelper . getLastRenderData ( ) , e . editorPos , e . pos , e . relativePos , testEventTarget ?target :null ) ;
285
+ }
286
+
287
+ private _createMouseTargetForOverflowWidgetsDomNode ( e :EditorMouseEvent ) :IMouseTarget {
288
+ return this . mouseTargetFactory . createMouseTargetForOverflowWidgetsDomNode ( this . viewHelper . getLastRenderData ( ) , e . editorPos , e . pos , e . relativePos , e . target ) ;
251
289
}
252
290
253
291
private _getMouseColumn ( e :EditorMouseEvent ) :number {
@@ -257,30 +295,45 @@ export class MouseHandler extends ViewEventHandler {
257
295
protected _onContextMenu ( e :EditorMouseEvent , testEventTarget :boolean ) :void {
258
296
this . viewController . emitContextMenu ( {
259
297
event :e ,
260
- target :this . _createMouseTarget ( e , testEventTarget )
298
+ target :this . _createMouseTargetForView ( e , testEventTarget )
299
+ } ) ;
300
+ }
301
+
302
+ protected _onMouseMoveOverView ( e :EditorMouseEvent ) :void {
303
+ this . _onMouseMove ( e , this . _createMouseTargetForView ( e , true ) ) ;
304
+ }
305
+
306
+ private _onMouseMoveOverOverflowWidgetsDomNode ( e :EditorMouseEvent ) :void {
307
+ this . _onMouseMove ( e , this . _createMouseTargetForOverflowWidgetsDomNode ( e ) ) ;
308
+ }
309
+
310
+ private _onMouseMove ( e :EditorMouseEvent , target :IMouseTarget ) :void {
311
+ const shouldIgnoreMouseMoveEvent = this . _shouldIgnoreMouseMoveEvent ( e ) ;
312
+ if ( shouldIgnoreMouseMoveEvent ) {
313
+ return undefined ;
314
+ }
315
+ this . viewController . emitMouseMove ( {
316
+ event :e ,
317
+ target
261
318
} ) ;
262
319
}
263
320
264
- protected _onMouseMove ( e :EditorMouseEvent ) :void {
321
+ private _shouldIgnoreMouseMoveEvent ( e :EditorMouseEvent ) :boolean {
265
322
const targetIsWidget = this . mouseTargetFactory . mouseTargetIsWidget ( e ) ;
266
323
if ( ! targetIsWidget ) {
267
324
e . preventDefault ( ) ;
268
325
}
269
326
270
327
if ( this . _mouseDownOperation . isActive ( ) ) {
271
328
// In selection/drag operation
272
- return ;
329
+ return true ;
273
330
}
274
331
const actualMouseMoveTime = e . timestamp ;
275
332
if ( actualMouseMoveTime < this . lastMouseLeaveTime ) {
276
333
// Due to throttling, this event occurred before the mouse left the editor, therefore ignore it.
277
- return ;
334
+ return true ;
278
335
}
279
-
280
- this . viewController . emitMouseMove ( {
281
- event :e ,
282
- target :this . _createMouseTarget ( e , true )
283
- } ) ;
336
+ return false ;
284
337
}
285
338
286
339
protected _onMouseLeave ( e :EditorMouseEvent ) :void {
@@ -298,12 +351,12 @@ export class MouseHandler extends ViewEventHandler {
298
351
protected _onMouseUp ( e :EditorMouseEvent ) :void {
299
352
this . viewController . emitMouseUp ( {
300
353
event :e ,
301
- target :this . _createMouseTarget ( e , true )
354
+ target :this . _createMouseTargetForView ( e , true )
302
355
} ) ;
303
356
}
304
357
305
358
protected _onMouseDown ( e :EditorMouseEvent , pointerId :number ) :void {
306
- const t = this . _createMouseTarget ( e , true ) ;
359
+ const t = this . _createMouseTargetForView ( e , true ) ;
307
360
308
361
const targetIsContent = ( t . type === MouseTargetType . CONTENT_TEXT || t . type === MouseTargetType . CONTENT_EMPTY ) ;
309
362
const targetIsGutter = ( t . type === MouseTargetType . GUTTER_GLYPH_MARGIN || t . type === MouseTargetType . GUTTER_LINE_NUMBERS || t . type === MouseTargetType . GUTTER_LINE_DECORATIONS ) ;
@@ -742,7 +795,7 @@ class TopBottomDragScrollingOperation extends Disposable {
742
795
const horizontalScrollbarHeight = this . _context . configuration . options . get ( EditorOption . layoutInfo ) . horizontalScrollbarHeight ;
743
796
const pos = new PageCoordinates ( this . _mouseEvent . pos . x , editorPos . y + editorPos . height - horizontalScrollbarHeight - 0.1 ) ;
744
797
const relativePos = createCoordinatesRelativeToEditor ( this . _viewHelper . viewDomNode , editorPos , pos ) ;
745
- mouseTarget = this . _mouseTargetFactory . createMouseTarget ( this . _viewHelper . getLastRenderData ( ) , editorPos , pos , relativePos , null ) ;
798
+ mouseTarget = this . _mouseTargetFactory . createMouseTargetForView ( this . _viewHelper . getLastRenderData ( ) , editorPos , pos , relativePos , null ) ;
746
799
}
747
800
if ( ! mouseTarget . position || mouseTarget . position . lineNumber !== edgeLineNumber ) {
748
801
if ( this . _position . outsidePosition === 'above' ) {