Bug 1838983: When dispatching a focus event, clear the stored active item if it is different to the target. r=eeejay

When the Accessible is recreated for the focused node, DocAccessible::CreateSubtree calls FocusManager::DispatchFocusEvent directly.
If FocusManager::mActiveItem was set, DispatchFocusEvent previously didn't clear it, even though DispatchFocusEvent was given a new target overriding mActiveItem.
This meant that the old mActiveItem would remain until it was next set or cleared, causing assertions if it died and potentially other problems.
To fix this, DispatchFocusEvent clears mActiveItem if it is different to the target, since the target should override.

Differential Revision: https://phabricator.services.mozilla.com/D181605
This commit is contained in:
James Teh 2023-06-23 22:56:19 +00:00
Родитель a62f40b927
Коммит 00fb437d8e
2 изменённых файлов: 22 добавлений и 0 удалений

Просмотреть файл

@ -261,6 +261,11 @@ void FocusManager::DispatchFocusEvent(DocAccessible* aDocument,
AccEvent::eCoalesceOfSameType);
aDocument->FireDelayedEvent(event);
mLastFocus = aTarget;
if (mActiveItem != aTarget) {
// This new focus overrides the stored active item, so clear the active
// item. Among other things, the old active item might die.
mActiveItem = nullptr;
}
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eFocus)) logging::FocusDispatched(aTarget);

Просмотреть файл

@ -131,6 +131,19 @@
getNode("cb_orange").selected = true;
await p;
// Bug 1838983: Make sure we don't fail a C++ assertion when the focused
// active item is destroyed.
info("Focusing recreate");
p = waitForEvent(EVENT_FOCUS, "recreateA");
const recreate = getNode("recreate");
recreate.focus();
await p;
info("Changing recreate size");
p = waitForEvent(EVENT_FOCUS, recreate);
// This will recreate the select and its children.
recreate.size = 1;
await p;
SimpleTest.finish();
}
@ -168,6 +181,10 @@
<option id="cb_apple">Apple</option>
</select>
<select id="recreate" size="5">
<option id="recreateA">a</option>
</select>
<div id="eventdump"></div>
</body>
</html>