@@ -4,11 +4,11 @@ import quickTools from "components/quickTools";
44import { description } from "components/quickTools/items" ;
55import { hideTooltip , showTooltip } from "components/tooltip" ;
66import config from "lib/config" ;
7- import appSettings from "lib/settings" ;
8- import actions , { cancelQuickToolsModifierInput , key } from "./quickTools" ;
7+ import { syncQuickToolsVisibility } from "lib/editorFile" ;
98import quickToolsAdapters from "lib/quickToolsAdapter" ;
109import { watchQuickToolsOverlays } from "lib/quickToolsOverlays" ;
11- import { syncQuickToolsVisibility } from "lib/editorFile" ;
10+ import appSettings from "lib/settings" ;
11+ import actions , { cancelQuickToolsModifierInput , key } from "./quickTools" ;
1212
1313const CONTEXT_MENU_TIMEOUT = 500 ;
1414const MOVE_X_THRESHOLD = 50 ;
@@ -53,6 +53,12 @@ function clearTouchFeedback() {
5353 }
5454}
5555
56+ function discardAdapterCapture ( ) {
57+ // Modifier sequences keep their selection until a key is dispatched.
58+ if ( ! key . shift && ! key . ctrl && ! key . alt && ! key . meta )
59+ quickToolsAdapters . discardCapture ( ) ;
60+ }
61+
5662/**
5763 * Initialize quick tools
5864 * @param {HTMLElement } $footer
@@ -88,12 +94,24 @@ export default function init() {
8894 refreshAdapter ( ) ;
8995 } ) ;
9096 watchQuickToolsOverlays ( quickToolsAdapters , cancelAdapterInput ) ;
91- $footer . addEventListener (
92- "pointerdown" ,
93- ( ) => quickToolsAdapters . capture ( ) ,
94- true ,
95- ) ;
96- $footer . addEventListener ( "keydown" , ( ) => quickToolsAdapters . capture ( ) , true ) ;
97+ const capture = ( ) => {
98+ discardAdapterCapture ( ) ;
99+ quickToolsAdapters . capture ( ) ;
100+ } ;
101+ $footer . addEventListener ( "pointerdown" , capture , true ) ;
102+ $footer . addEventListener ( "keydown" , capture , true ) ;
103+ $footer . addEventListener ( "pointercancel" , discardAdapterCapture , true ) ;
104+ $footer . addEventListener ( "scroll" , discardAdapterCapture , true ) ;
105+ const leaveQuickTools = ( event ) => {
106+ if ( ! quickToolsAdapters . has ( ) ) return ;
107+ const path = event . composedPath ( ) ;
108+ if ( path . includes ( $footer ) || path . includes ( $input ) ) return ;
109+ quickToolsAdapters . discardCapture ( ) ;
110+ if ( key . shift || key . ctrl || key . alt || key . meta )
111+ cancelQuickToolsModifierInput ( ) ;
112+ } ;
113+ document . addEventListener ( "pointerdown" , leaveQuickTools , true ) ;
114+ document . addEventListener ( "focusin" , leaveQuickTools , true ) ;
97115
98116 $toggler . addEventListener ( "click" , ( e ) => {
99117 e . preventDefault ( ) ;
@@ -189,6 +207,7 @@ export default function init() {
189207
190208function onwheel ( e ) {
191209 e . preventDefault ( ) ;
210+ discardAdapterCapture ( ) ;
192211 const $el = e . target ;
193212 const { $row1, $row2 } = quickTools ;
194213 let $row ;
@@ -208,6 +227,7 @@ function onclick(e) {
208227 reset ( ) ;
209228
210229 if ( e . target . disabled ) {
230+ discardAdapterCapture ( ) ;
211231 e . preventDefault ( ) ;
212232 e . stopPropagation ( ) ;
213233 return ;
@@ -344,11 +364,10 @@ function touchend(e) {
344364 }
345365
346366 $row . scrollLeft = scroll ;
347- touchcancel ( e ) ;
348-
349- if ( $el === $touchstart && performance . now ( ) - startTime < 100 ) {
350- click ( $el ) ;
351- }
367+ const shouldClick =
368+ $el === $touchstart && performance . now ( ) - startTime < 100 ;
369+ touchcancel ( e , { preserveCapture : shouldClick } ) ;
370+ if ( shouldClick ) click ( $el ) ;
352371 return ;
353372 }
354373
@@ -357,15 +376,15 @@ function touchend(e) {
357376 return ;
358377 }
359378
360- touchcancel ( e ) ;
379+ touchcancel ( e , { preserveCapture : true } ) ;
361380 click ( $el ) ;
362381}
363382
364383/**
365384 *
366385 * @param {TouchEvent } e
367386 */
368- function touchcancel ( e ) {
387+ function touchcancel ( e , { preserveCapture = false } = { } ) {
369388 document . removeEventListener ( "keyup" , touchcancel ) ;
370389 document . removeEventListener ( "touchend" , touchend ) ;
371390 document . removeEventListener ( "touchcancel" , touchcancel ) ;
@@ -374,6 +393,7 @@ function touchcancel(e) {
374393 clearTimeout ( contextmenuTimeout ) ;
375394 clearTouchFeedback ( ) ;
376395 hideTooltip ( ) ;
396+ if ( ! preserveCapture ) discardAdapterCapture ( ) ;
377397}
378398
379399/**
@@ -414,7 +434,10 @@ function oncontextmenu(e) {
414434 * @param {HTMLElement } $el
415435 */
416436function click ( $el ) {
417- if ( $el . disabled ) return ;
437+ if ( $el . disabled ) {
438+ discardAdapterCapture ( ) ;
439+ return ;
440+ }
418441
419442 $el . classList . add ( "click" ) ;
420443 clearTimeout ( $el . dataset . timeout ) ;
@@ -427,15 +450,22 @@ function click($el) {
427450 }
428451
429452 const { action } = $el . dataset ;
430- if ( ! action ) return ;
453+ if ( ! action ) {
454+ discardAdapterCapture ( ) ;
455+ return ;
456+ }
431457
432458 let { value } = $el . dataset ;
433459
434460 if ( ! value ) {
435461 value = $el . value ;
436462 }
437463
438- actions ( action , value ) ;
464+ try {
465+ actions ( action , value ) ;
466+ } finally {
467+ discardAdapterCapture ( ) ;
468+ }
439469}
440470
441471function scheduleUpdateQuickToolsState ( ) {
0 commit comments