Fix pointer navigation in Quattro launcher menus (#6343)

Accumulate sub-threshold movement so slow motion with a flat acceleration profile updates selection. Sample pointer state on row entry and carry pointer intent through subordinate menus while preserving predictable keyboard selection.
This commit is contained in:
ssupt
2026-07-22 15:27:56 -07:00
committed by GitHub
parent 4a02da20d5
commit 3481b5614b
7 changed files with 184 additions and 17 deletions
+20 -2
View File
@@ -174,8 +174,8 @@ assert(
'menu filter changes disarm pointer selection'
)
assert(
/function setActiveMenu\(id, pushHistory\)[\s\S]*root\.disarmPointer\(\)/.test(menuQml),
'menu route changes disarm pointer selection'
/function setActiveMenu\(id, pushHistory, fromPointer\)[\s\S]*if \(fromPointer\) pointerGate\.allowInitialSample\(\)\s*else root\.disarmPointer\(\)/.test(menuQml),
'menu route changes only accept an initial pointer sample for mouse activation'
)
assert(
/\(event\.key === Qt\.Key_Backspace \|\| event\.key === Qt\.Key_Left\) && !root\.filterText[\s\S]*root\.goBack\(\)/.test(menuQml),
@@ -189,6 +189,15 @@ assert(
/function disarmPointer\(\)[\s\S]*pointerGate\.reset\(\)/.test(menuQml),
'menu resets pointer movement gate when pointer selection is disarmed'
)
for (const functionName of ['openExistingMenu', 'openDmenu']) {
const openMatch = menuQml.match(new RegExp(`function ${functionName}\\([^)]*\\) \\{([\\s\\S]*?)\\n \\}`))
assert(openMatch, `menu ${functionName} function exists`)
assert(
openMatch[1].indexOf('root.disarmPointer()') < openMatch[1].indexOf('opened = true')
&& !openMatch[1].includes('pointerGate.allowInitialSample()'),
`menu ${functionName} ignores a stale hidden-pointer position when becoming visible`
)
}
assert(
/function selectFromPointer\(index, item, mouse\)[\s\S]*pointerGate\.moved\(item, mouse\)[\s\S]*root\.selectedIndex = index/.test(menuQml),
'menu only selects from pointer after real movement'
@@ -197,4 +206,13 @@ assert(
/onPositionChanged: function\(mouse\) \{\s*root\.selectFromPointer\(row\.index, row, mouse\)\s*\}/.test(menuQml),
'menu row hover routes through pointer movement gate'
)
assert(
/onEntered: root\.selectFromPointer\(row\.index, row, \{\s*x: mouseArea\.mouseX,\s*y: mouseArea\.mouseY\s*\}\)/.test(menuQml),
'menu samples pointer movement immediately when entering a row'
)
assert(
/function activateIndex\(index, fromPointer\)[\s\S]*root\.setActiveMenu\(row\.target \|\| row\.itemId, true, fromPointer\)/.test(menuQml)
&& /onClicked:[\s\S]*root\.activateIndex\(row\.index, true\)/.test(menuQml),
'mouse activation carries pointer intent into subordinate menus'
)
JS