From eb0f0a9790fc336d7089344c2b5645f5c55f6801 Mon Sep 17 00:00:00 2001 From: James Teh Date: Wed, 23 Apr 2025 23:46:12 +0000 Subject: [PATCH] Bug 1961832: When queuing an event, don't append it to the array at all if it is a duplicate and duplicates aren't allowed. r=eeejay Differential Revision: https://phabricator.services.mozilla.com/D246400 --- accessible/base/EventQueue.cpp | 46 +++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/accessible/base/EventQueue.cpp b/accessible/base/EventQueue.cpp index cbb0b81ad9ab..2bcbd0aab61e 100644 --- a/accessible/base/EventQueue.cpp +++ b/accessible/base/EventQueue.cpp @@ -38,6 +38,26 @@ bool EventQueue::PushEvent(AccEvent* aEvent) { return true; } + if (aEvent->mEventRule == AccEvent::eRemoveDupes && !mEvents.IsEmpty()) { + // Check for duplicate events. If aEvent is identical to an older event, do + // not append aEvent. We do this here rather than in CoalesceEvents because + // CoalesceEvents never *removes* events; it only sets them to eDoNotEmit. + // If there are many duplicate events and we appended them, this would + // result in a massive event queue and coalescing would become increasingly + // slow with each event queued. Doing it here, we avoid appending a + // duplicate event in the first place. + uint32_t last = mEvents.Length() - 1; + for (uint32_t index = last; index <= last; --index) { + AccEvent* checkEvent = mEvents[index]; + if (checkEvent->mEventType == aEvent->mEventType && + checkEvent->mEventRule == aEvent->mEventRule && + checkEvent->mAccessible == aEvent->mAccessible) { + aEvent->mEventRule = AccEvent::eDoNotEmit; + return true; + } + } + } + // XXX(Bug 1631371) Check if this should use a fallible operation as it // pretended earlier, or change the return type to void. mEvents.AppendElement(aEvent); @@ -45,10 +65,10 @@ bool EventQueue::PushEvent(AccEvent* aEvent) { // Filter events. CoalesceEvents(); - if (aEvent->mEventRule != AccEvent::eDoNotEmit && - (aEvent->mEventType == nsIAccessibleEvent::EVENT_NAME_CHANGE || - aEvent->mEventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED || - aEvent->mEventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED)) { + if (aEvent->mEventType == nsIAccessibleEvent::EVENT_NAME_CHANGE || + aEvent->mEventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED || + aEvent->mEventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) { + MOZ_ASSERT(aEvent->mEventRule != AccEvent::eDoNotEmit); PushNameOrDescriptionChange(aEvent); } return true; @@ -258,23 +278,9 @@ void EventQueue::CoalesceEvents() { break; // eCoalesceTextSelChange } - case AccEvent::eRemoveDupes: { - // Check for repeat events, coalesce newly appended event by more older - // event. - for (uint32_t index = tail - 1; index < tail; index--) { - AccEvent* accEvent = mEvents[index]; - if (accEvent->mEventType == tailEvent->mEventType && - accEvent->mEventRule == tailEvent->mEventRule && - accEvent->mAccessible == tailEvent->mAccessible) { - tailEvent->mEventRule = AccEvent::eDoNotEmit; - return; - } - } - break; // case eRemoveDupes - } - default: - break; // case eAllowDupes, eDoNotEmit + // eRemoveDupes is handled in PushEvent. + break; // case eRemoveDupes, eAllowDupes, eDoNotEmit } // switch }