Skip to content

Commit 3b1ce99

Browse files
Merge afb7392 into d1ce3bc
2 parents d1ce3bc + afb7392 commit 3b1ce99

8 files changed

Lines changed: 29 additions & 97 deletions

File tree

source/IAccessibleHandler/internalWinEventHandler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def winEventCallback(handle, eventID, window, objectID, childID, threadID, times
177177
f"Adding winEvent to limiter: {getWinEventLogInfo(window, objectID, childID, eventID, threadID)}"
178178
)
179179
if winEventLimiter.addEvent(eventID, window, objectID, childID, threadID):
180-
core.requestPump(immediate=eventID == winUser.EVENT_OBJECT_FOCUS)
180+
core.requestPump()
181181
except Exception:
182182
log.error("winEventCallback", exc_info=True)
183183

source/NVDAObjects/behaviors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ def _monitor(self):
446446
# so ignore it.
447447
del outLines[0]
448448
if outLines:
449-
queueHandler.queueFunction(queueHandler.eventQueue, self._reportNewLines, outLines, _immediate=True)
449+
queueHandler.queueFunction(queueHandler.eventQueue, self._reportNewLines, outLines)
450450
oldText = newText
451451
except:
452452
log.exception("Error getting or calculating new text")

source/core.py

Lines changed: 20 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import os
2121
import time
2222
import ctypes
23-
from enum import Enum
2423
import logHandler
2524
import languageHandler
2625
import globalVars
@@ -53,16 +52,7 @@ def __getattr__(attrName: str) -> Any:
5352
mainThreadId = threading.get_ident()
5453

5554
_pump = None
56-
57-
58-
class _PumpPending(Enum):
59-
NONE = 0
60-
DELAYED = 1
61-
IMMEDIATE = 2
62-
63-
def __bool__(self):
64-
return self is not self.NONE
65-
55+
_isPumpPending = False
6656

6757
_hasShutdownBeenTriggered = False
6858
_shuttingDownFlagLock = threading.Lock()
@@ -716,29 +706,11 @@ def onEndSession(evt):
716706
# Doing this here is a bit ugly, but we don't want these modules imported
717707
# at module level, including wx.
718708
log.debug("Initializing core pump")
719-
720-
class CorePump(wx.Timer):
709+
class CorePump(gui.NonReEntrantTimer):
721710
"Checks the queues and executes functions."
722-
pending = _PumpPending.NONE
723-
isPumping = False
724-
725-
def request(self):
726-
if self.isPumping:
727-
return # Prevent re-entry.
728-
if self.pending == _PumpPending.IMMEDIATE:
729-
# A delayed pump might have been scheduled. If so, cancel it.
730-
self.Stop()
731-
self.Notify()
732-
elif self.pending == _PumpPending.DELAYED:
733-
self.Start(PUMP_MAX_DELAY, True)
734-
735-
def Notify(self):
736-
if self.isPumping:
737-
log.error("Pumping while already pumping", stack_info=True)
738-
if not self.pending:
739-
log.error("Pumping but pump wasn't pending", stack_info=True)
740-
self.isPumping = True
741-
self.pending = _PumpPending.NONE
711+
def run(self):
712+
global _isPumpPending
713+
_isPumpPending = False
742714
watchdog.alive()
743715
try:
744716
if touchHandler.handler:
@@ -754,11 +726,10 @@ def Notify(self):
754726
log.exception("errors in this core pump cycle")
755727
baseObject.AutoPropertyObject.invalidateCaches()
756728
watchdog.asleep()
757-
self.isPumping = False
758-
if self.pending:
729+
if _isPumpPending and not _pump.IsRunning():
759730
# #3803: Another pump was requested during this pump execution.
760731
# As our pump is not re-entrant, schedule another pump.
761-
self.request()
732+
_pump.Start(PUMP_MAX_DELAY, True)
762733
global _pump
763734
_pump = CorePump()
764735
requestPump()
@@ -864,28 +835,23 @@ def _terminate(module, name=None):
864835
except:
865836
log.exception("Error terminating %s" % name)
866837

867-
868-
def requestPump(immediate: bool = False):
838+
def requestPump():
869839
"""Request a core pump.
870840
This will perform any queued activity.
871-
@param immediate: If True, the pump will happen as soon as possible. This
872-
should be used where response time is most important; e.g. user input or
873-
focus events.
874-
If False, it is delayed slightly so that queues can implement rate limiting,
875-
filter extraneous events, etc.
841+
It is delayed slightly so that queues can implement rate limiting,
842+
filter extraneous events, etc.
876843
"""
877-
if not _pump:
844+
global _isPumpPending
845+
if not _pump or _isPumpPending:
878846
return
879-
# We only need to do something if:
880-
if (
881-
# There is no pending pump.
882-
_pump.pending == _PumpPending.NONE
883-
# There is a pending delayed pump but an immediate pump was just requested.
884-
or (immediate and _pump.pending == _PumpPending.DELAYED)
885-
):
886-
_pump.pending = _PumpPending.IMMEDIATE if immediate else _PumpPending.DELAYED
887-
import wx
888-
wx.CallAfter(_pump.request)
847+
_isPumpPending = True
848+
if threading.get_ident() == mainThreadId:
849+
_pump.Start(PUMP_MAX_DELAY, True)
850+
return
851+
# This isn't the main thread. wx timers cannot be run outside the main thread.
852+
# Therefore, Have wx start it in the main thread with a CallAfter.
853+
import wx
854+
wx.CallAfter(_pump.Start,PUMP_MAX_DELAY, True)
889855

890856

891857
class NVDANotInitializedError(Exception):

source/eventHandler.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,7 @@ def queueEvent(eventName,obj,**kwargs):
4747
_pendingEventCountsByName[eventName]=_pendingEventCountsByName.get(eventName,0)+1
4848
_pendingEventCountsByObj[obj]=_pendingEventCountsByObj.get(obj,0)+1
4949
_pendingEventCountsByNameAndObj[(eventName,obj)]=_pendingEventCountsByNameAndObj.get((eventName,obj),0)+1
50-
queueHandler.queueFunction(
51-
queueHandler.eventQueue,
52-
_queueEventCallback,
53-
eventName,
54-
obj,
55-
kwargs,
56-
_immediate=eventName == "gainFocus"
57-
)
50+
queueHandler.queueFunction(queueHandler.eventQueue,_queueEventCallback,eventName,obj,kwargs)
5851

5952

6053
def _queueEventCallback(eventName,obj,kwargs):

source/inputCore.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ def executeGesture(self, gesture):
524524

525525
speechEffect = gesture.speechEffectWhenExecuted
526526
if speechEffect == gesture.SPEECHEFFECT_CANCEL:
527-
queueHandler.queueFunction(queueHandler.eventQueue, speech.cancelSpeech, _immediate=True)
527+
queueHandler.queueFunction(queueHandler.eventQueue, speech.cancelSpeech)
528528
elif speechEffect in (gesture.SPEECHEFFECT_PAUSE, gesture.SPEECHEFFECT_RESUME):
529529
queueHandler.queueFunction(queueHandler.eventQueue, speech.pauseSpeech, speechEffect == gesture.SPEECHEFFECT_PAUSE)
530530

@@ -547,12 +547,7 @@ def executeGesture(self, gesture):
547547
raise NoInputGestureAction
548548

549549
if config.conf["keyboard"]["speakCommandKeys"] and gesture.shouldReportAsCommand:
550-
queueHandler.queueFunction(
551-
queueHandler.eventQueue,
552-
speech.speakMessage,
553-
gesture.displayName,
554-
_immediate=True
555-
)
550+
queueHandler.queueFunction(queueHandler.eventQueue, speech.speakMessage, gesture.displayName)
556551

557552
gesture.reportExtra()
558553

@@ -585,13 +580,7 @@ def _set_isInputHelpActive(self, enable):
585580

586581
def _inputHelpCaptor(self, gesture):
587582
bypass = gesture.bypassInputHelp or getattr(gesture.script, "bypassInputHelp", False)
588-
queueHandler.queueFunction(
589-
queueHandler.eventQueue,
590-
self._handleInputHelp,
591-
gesture,
592-
onlyLog=bypass or not gesture.reportInInputHelp,
593-
_immediate=True
594-
)
583+
queueHandler.queueFunction(queueHandler.eventQueue, self._handleInputHelp, gesture, onlyLog=bypass or not gesture.reportInInputHelp)
595584
return bypass
596585

597586
def _handleInputHelp(self, gesture, onlyLog=False):

source/queueHandler.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,9 @@ def cancelGeneratorObject(generatorObjID):
3838
except KeyError:
3939
pass
4040

41-
42-
def queueFunction(queue, func, *args, _immediate: bool = False, **kwargs):
43-
"""Queue a function to be executed in a specific queue.
44-
@param queue: The queue to use. Currently, this can only be
45-
L{queueHandler.eventQueue}.
46-
@param func: The function to run.
47-
@param _immediate: Whether to run this as soon as possible (e.g. input) or
48-
to delay it slightly (e.g. events). See the immediate argument to
49-
L{core.requestPump}.
50-
"""
41+
def queueFunction(queue,func,*args,**kwargs):
5142
queue.put_nowait((func,args,kwargs))
52-
core.requestPump(immediate=_immediate)
43+
core.requestPump()
5344

5445
def isRunningGenerators():
5546
res=len(generators)>0

source/scriptHandler.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,7 @@ def queueScript(script,gesture):
249249
_numScriptsQueued+=1
250250
if _isInterceptedCommandScript(script):
251251
_numIncompleteInterceptedCommandScripts+=1
252-
queueHandler.queueFunction(
253-
queueHandler.eventQueue,
254-
_queueScriptCallback,
255-
script,
256-
gesture,
257-
_immediate=True
258-
)
252+
queueHandler.queueFunction(queueHandler.eventQueue,_queueScriptCallback,script,gesture)
259253

260254
def willSayAllResume(gesture):
261255
return (

user_docs/en/changes.t2t

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ There are now gestures for showing the braille settings dialog, accessing the st
2929
- Dash and em-dash symbols will always be sent to the synthesizer. (#13830)
3030
- Distance reported in Microsoft Word will now honour the unit defined in Word's advanced options even when using UIA to access Word documents. (#14542)
3131
- When reporting the review cursor location, the current cursor/caret location is now reported relative to the current page in LibreOffice Writer for LibreOffice versions >= 7.6, similar to what is done for Microsoft Word. (#11696)
32-
- NVDA now responds slightly faster to commands and focus changes. (#14701)
3332
- NVDA responds faster when moving the cursor in edit controls. (#14708)
3433
- Baum Braille driver: addes several Braille chord gestures for performing common keyboard commands such as windows+d, alt+tab etc. Please refer to the NVDA user guide for a full list. (#14714)
3534
- When using a Braille Display via the Standard HID braille driver, the dpad can be used to emulate the arrow keys and enter. Also space+dot1 and space+dot4 now map to up and down arrow respectively. (#14713)

0 commit comments

Comments
 (0)