Skip to content

Commit 07d6218

Browse files
Merge 7316138 into 9a4074b
2 parents 9a4074b + 7316138 commit 07d6218

2 files changed

Lines changed: 31 additions & 7 deletions

File tree

source/IAccessibleHandler/__init__.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# This file is covered by the GNU General Public License.
55
# See the file COPYING for more details.
66

7+
from typing import Tuple
78
import struct
89
import weakref
910
# Kept for backwards compatibility
@@ -100,6 +101,12 @@
100101
IA2_ROLE_MARK,
101102
)
102103

104+
IAccessibleObjectIdentifierType = Tuple[
105+
int, # windowHandle
106+
int, # objectID
107+
int, # childID
108+
]
109+
103110
from . import internalWinEventHandler
104111
# Imported for backwards compat
105112
from .internalWinEventHandler import ( # noqa: F401
@@ -126,8 +133,6 @@
126133

127134
from .orderedWinEventLimiter import MENU_EVENTIDS
128135

129-
MAX_WINEVENTS = 500
130-
131136
# Special Mozilla gecko MSAA constant additions
132137
NAVRELATION_LABEL_FOR = 0x1002
133138
NAVRELATION_LABELLED_BY = 0x1003
@@ -857,9 +862,14 @@ def pumpAll(): # noqa: C901
857862
fakeFocusEvent = None
858863
focus = eventHandler.lastQueuedFocusObject
859864

865+
alwaysAllowedObjects = []
866+
# winEvents for the currently focused object are special,
867+
# and should be never filtered out.
868+
if isinstance(focus, NVDAObjects.IAccessible.IAccessible) and focus.event_objectID is not None:
869+
alwaysAllowedObjects.append((focus.event_windowHandle, focus.event_objectID, focus.event_childID))
870+
860871
# Receive all the winEvents from the limiter for this cycle
861-
winEvents = winEventLimiter.flushEvents()
862-
winEvents = winEvents[0 - MAX_WINEVENTS:]
872+
winEvents = winEventLimiter.flushEvents(alwaysAllowedObjects)
863873

864874
for winEvent in winEvents:
865875
isEventOnCaret = winEvent[2] == winUser.OBJID_CARET

source/IAccessibleHandler/orderedWinEventLimiter.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
from typing import Optional, List
12
import heapq
23
import itertools
34

45
import winUser
6+
from . import IAccessibleObjectIdentifierType
7+
58

69
MAX_WINEVENTS_PER_THREAD = 10
710

@@ -75,10 +78,15 @@ def addEvent(
7578
self._genericEventCache[(eventID, window, objectID, childID, threadID)] = next(self._eventCounter)
7679
return True
7780

78-
def flushEvents(self):
81+
def flushEvents(
82+
self,
83+
alwaysAllowedObjects: Optional[List[IAccessibleObjectIdentifierType]] = None
84+
):
7985
"""Returns a list of winEvents that have been added.
8086
Due to limiting, it will not necessarily be all the winEvents that were originally added.
8187
They are definitely guaranteed to be in the correct order though.
88+
winEvents for objects listed in alwaysAllowedObjects will always be emitted,
89+
Even if the winEvent limit for that thread has been exceeded.
8290
@return Tuple[eventID,window,objectID,childID]
8391
"""
8492
if self._lastMenuEvent is not None:
@@ -88,11 +96,17 @@ def flushEvents(self):
8896
self._genericEventCache = {}
8997
threadCounters = {}
9098
for k, v in sorted(g.items(), key=lambda item: item[1], reverse=True):
99+
# Increase the event count for this thread by 1.
91100
threadCount = threadCounters.get(k[-1], 0)
92-
if threadCount > MAX_WINEVENTS_PER_THREAD:
101+
threadCount += 1
102+
threadCounters[k[-1]] = threadCount
103+
# Find out if this event is for an object whos events are always allowed.
104+
eventsForObjectAlwaysAllowed = alwaysAllowedObjects and k[1:-1] in alwaysAllowedObjects
105+
if threadCount > MAX_WINEVENTS_PER_THREAD and not eventsForObjectAlwaysAllowed:
106+
# Skip this event if too many events have already been emitted for this thread
107+
# and this event is not for an object whos events are always allowed.
93108
continue
94109
heapq.heappush(self._eventHeap, (v,) + k)
95-
threadCounters[k[-1]] = threadCount + 1
96110
f = self._focusEventCache
97111
self._focusEventCache = {}
98112
for k, v in sorted(f.items(), key=lambda item: item[1])[0 - self.maxFocusItems:]:

0 commit comments

Comments
 (0)