@@ -88,14 +88,27 @@ export class DragEngine extends CoordinatesEngine<'drag'> {
88
88
)
89
89
return
90
90
91
- this . ctrl . setEventIds ( event )
91
+ const ctrlIds = this . ctrl . setEventIds ( event )
92
92
// We need to capture all pointer ids so that we can keep track of them when
93
93
// they're released off the target
94
94
if ( config . pointerCapture ) {
95
95
; ( event . target as HTMLElement ) . setPointerCapture ( event . pointerId )
96
96
}
97
97
98
- if ( state . _pointerActive ) return
98
+ if (
99
+ // in some situations (https://github.com/pmndrs/use-gesture/issues/494#issuecomment-1127584116)
100
+ // like when a new browser tab is opened during a drag gesture, the drag
101
+ // can be interrupted mid-way, and can stall. This happens because the
102
+ // pointerId that initiated the gesture is lost, and since the drag
103
+ // persists until that pointerId is lifted with pointerup, it never ends.
104
+ //
105
+ // Therefore, when we detect that only one pointer is pressing the screen,
106
+ // we consider that the gesture can proceed.
107
+ ctrlIds &&
108
+ ctrlIds . size > 1 &&
109
+ state . _pointerActive
110
+ )
111
+ return
99
112
100
113
this . start ( event )
101
114
this . setupPointer ( event )
@@ -271,9 +284,9 @@ export class DragEngine extends CoordinatesEngine<'drag'> {
271
284
}
272
285
273
286
if ( ! config . pointerCapture ) {
274
- this . eventStore . add ( this . sharedConfig . window ! , device , 'change' , this . pointerMove . bind ( this ) )
275
- this . eventStore . add ( this . sharedConfig . window ! , device , 'end' , this . pointerUp . bind ( this ) )
276
- this . eventStore . add ( this . sharedConfig . window ! , device , 'cancel' , this . pointerUp . bind ( this ) )
287
+ this . eventStore . add ( this . sharedConfig . window , device , 'change' , this . pointerMove . bind ( this ) )
288
+ this . eventStore . add ( this . sharedConfig . window , device , 'end' , this . pointerUp . bind ( this ) )
289
+ this . eventStore . add ( this . sharedConfig . window , device , 'cancel' , this . pointerUp . bind ( this ) )
277
290
}
278
291
}
279
292
@@ -292,7 +305,11 @@ export class DragEngine extends CoordinatesEngine<'drag'> {
292
305
setupScrollPrevention ( event : PointerEvent ) {
293
306
persistEvent ( event )
294
307
// we add window listeners that will prevent the scroll when the user has started dragging
295
- this . eventStore . add ( this . sharedConfig . window ! , 'touch' , 'change' , this . preventScroll . bind ( this ) , { passive : false } )
308
+ const remove = this . eventStore . add ( this . sharedConfig . window , 'touch' , 'change' , this . preventScroll . bind ( this ) , {
309
+ passive : false
310
+ } )
311
+ this . eventStore . add ( this . sharedConfig . window , 'touch' , 'end' , remove )
312
+ this . eventStore . add ( this . sharedConfig . window , 'touch' , 'cancel' , remove )
296
313
this . timeoutStore . add ( 'startPointerDrag' , this . startPointerDrag . bind ( this ) , this . config . preventScrollDelay ! , event )
297
314
}
298
315
0 commit comments