Skip to content

Commit f495013

Browse files
authored
Merge 3f1a78d into 12e17fc
2 parents 12e17fc + 3f1a78d commit f495013

9 files changed

Lines changed: 49 additions & 17 deletions

File tree

source/NVDAObjects/behaviors.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,9 @@ class EditableText(editableText.EditableText, NVDAObject):
168168

169169
def initOverlayClass(self):
170170
# #4264: the caret_newLine script can only be bound for processes other than NVDA's process
171-
# As Pressing enter on an edit field can cause modal dialogs to appear, yet gesture.send and api.processPendingEvents may call.wx.yield which ends in a freeze.
172-
if self.announceNewLineText and self.processID!=os.getpid():
171+
# As Pressing enter on an edit field can cause modal dialogs to appear,
172+
# yet gesture.send and api.processPendingEvents may call.wx.yield which ends in a freeze.
173+
if self.announceNewLineText and self.processID != globalVars.appPid:
173174
self.bindGesture("kb:enter","caret_newLine")
174175
self.bindGesture("kb:numpadEnter","caret_newLine")
175176

source/UIAHandler/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import api
3636
import appModuleHandler
3737
import controlTypes
38+
import globalVars
3839
import winKernel
3940
import winUser
4041
import winVersion
@@ -747,7 +748,7 @@ def IUIAutomationActiveTextPositionChangedEventHandler_HandleActiveTextPositionC
747748
def _isUIAWindowHelper(self,hwnd):
748749
# UIA in NVDA's process freezes in Windows 7 and below
749750
processID=winUser.getWindowThreadProcessID(hwnd)[0]
750-
if windll.kernel32.GetCurrentProcessId()==processID:
751+
if globalVars.appPid == processID:
751752
return False
752753
import NVDAObjects.window
753754
windowClass=NVDAObjects.window.Window.normalizeWindowClassName(winUser.getClassName(hwnd))
@@ -921,12 +922,13 @@ def _emitMSAAFocusForWordDocIfNecessary(self, element: UIA.IUIAutomationElement)
921922

922923
def isNativeUIAElement(self,UIAElement):
923924
#Due to issues dealing with UIA elements coming from the same process, we do not class these UIA elements as usable.
924-
#It seems to be safe enough to retreave the cached processID, but using tree walkers or fetching other properties causes a freeze.
925+
# It seems to be safe enough to retrieve the cached processID,
926+
# but using tree walkers or fetching other properties causes a freeze.
925927
try:
926928
processID=UIAElement.cachedProcessId
927929
except COMError:
928930
return False
929-
if processID==windll.kernel32.GetCurrentProcessId():
931+
if processID == globalVars.appPid:
930932
return False
931933
# Whether this is a native element depends on whether its window natively supports UIA.
932934
windowHandle=self.getNearestWindowHandle(UIAElement)

source/appModuleHandler.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import sys
1818
from types import ModuleType
1919
from typing import (
20+
Any,
2021
Dict,
2122
List,
2223
Optional,
@@ -42,12 +43,12 @@
4243
import exceptions
4344
import extensionPoints
4445
from fileUtils import getFileVersionInfo
46+
import globalVars
47+
4548

4649
_KNOWN_IMPORTERS_T = Union[importlib.machinery.FileFinder, zipimport.zipimporter]
4750
# Dictionary of processID:appModule pairs used to hold the currently running modules
4851
runningTable: Dict[int, AppModule] = {}
49-
#: The process ID of NVDA itself.
50-
NVDAProcessID=None
5152
_CORE_APP_MODULES_PATH: os.PathLike = appModules.__path__[0]
5253
_importers: Optional[List[_KNOWN_IMPORTERS_T]] = None
5354
_getAppModuleLock=threading.RLock()
@@ -80,6 +81,22 @@ class processEntry32W(ctypes.Structure):
8081
]
8182

8283

84+
def __getattr__(attrName: str) -> Any:
85+
"""Module level `__getattr__` used to preserve backward compatibility.
86+
The module level variable `NVDAProcessID` is deprecated
87+
and usages should be replaced with `globalVars.appPid`.
88+
We cannot simply assign the value from `globalVars` to the old attribute
89+
since add-ons are initialized before `appModuleHandler`
90+
and when `appModuleHandler` was not yet initialized the variable was set to `None`.
91+
"""
92+
if attrName == "NVDAProcessID":
93+
log.warning("appModuleHandler.NVDAProcessID is deprecated, use globalVars.appPid instead.")
94+
if initialize._alreadyInitialized:
95+
return globalVars.appPid
96+
return None
97+
raise AttributeError(f"module {repr(__name__)} has no attribute {repr(attrName)}")
98+
99+
83100
def _warnDeprecatedAliasAppModule() -> None:
84101
"""This function should be executed at the top level of an alias App Module,
85102
to log a deprecation warning when the module is imported.
@@ -195,7 +212,7 @@ def getAppNameFromProcessID(processID: int, includeExt: bool = False) -> str:
195212
C{False} to exclude it.
196213
@returns: application name
197214
"""
198-
if processID==NVDAProcessID:
215+
if processID == globalVars.appPid:
199216
return "nvda.exe" if includeExt else "nvda"
200217
FSnapshotHandle = winKernel.kernel32.CreateToolhelp32Snapshot (2,0)
201218
FProcessEntry32 = processEntry32W()
@@ -345,13 +362,19 @@ def reloadAppModules():
345362
# Fetch and cache right away; the process could die any time.
346363
obj.appModule
347364

365+
348366
def initialize():
349367
"""Initializes the appModule subsystem.
350368
"""
351-
global NVDAProcessID,_importers
352-
NVDAProcessID=os.getpid()
369+
global _importers
353370
config.addConfigDirsToPythonPackagePath(appModules)
354371
_importers=list(pkgutil.iter_importers("appModules.__init__"))
372+
if not initialize._alreadyInitialized:
373+
initialize._alreadyInitialized = True
374+
375+
376+
initialize._alreadyInitialized = False
377+
355378

356379
def terminate():
357380
for processID, app in runningTable.items():

source/globalVars.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,7 @@ class DefaultAppArgs(argparse.Namespace):
6565
settingsRing = None
6666
speechDictionaryProcessing=True
6767
exitCode=0
68+
69+
appPid: int = 0
70+
"""The process ID of NVDA itself.
71+
"""

source/gui/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,17 @@ def prePopup(self):
107107
L{postPopup} should be called after the dialog or menu has been shown.
108108
@postcondition: A dialog or menu may be shown.
109109
"""
110-
nvdaPid = os.getpid()
111110
focus = api.getFocusObject()
112111
# Do not set prevFocus if the focus is on a control rendered by NVDA itself, such as the NVDA menu.
113112
# This allows to refer to the control that had focus before opening the menu while still using NVDA
114-
# on its own controls. The L{nvdaPid} check can be bypassed by setting the optional attribute
113+
# on its own controls.
114+
# The check for NVDA process ID can be bypassed by setting the optional attribute
115115
# L{isPrevFocusOnNvdaPopup} to L{True} when a NVDA dialog offers customizable bound gestures,
116116
# eg. the NVDA Python Console.
117-
if focus.processID != nvdaPid or getattr(focus, "isPrevFocusOnNvdaPopup", False):
117+
if focus.processID != globalVars.appPid or getattr(focus, "isPrevFocusOnNvdaPopup", False):
118118
self.prevFocus = focus
119119
self.prevFocusAncestors = api.getFocusAncestors()
120-
if winUser.getWindowThreadProcessID(winUser.getForegroundWindow())[0] != nvdaPid:
120+
if winUser.getWindowThreadProcessID(winUser.getForegroundWindow())[0] != globalVars.appPid:
121121
# This process is not the foreground process, so bring it to the foreground.
122122
self.Raise()
123123

source/logHandler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def __init__(self):
293293
def emit(self, record):
294294
msg = self.format(record)
295295
try:
296-
self._remoteLib.nvdaControllerInternal_logMessage(record.levelno, ctypes.windll.kernel32.GetCurrentProcessId(), msg)
296+
self._remoteLib.nvdaControllerInternal_logMessage(record.levelno, globalVars.appPid, msg)
297297
except WindowsError:
298298
pass
299299

source/nvda.pyw

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ else:
5454
appDir = os.path.abspath(appDir)
5555
os.chdir(appDir)
5656
globalVars.appDir = appDir
57+
globalVars.appPid = os.getpid()
5758

5859

5960
import locale

source/nvda_slave.pyw

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ else:
2626

2727
# #2391: some functions may still require the current directory to be set to NVDA's app dir
2828
os.chdir(globalVars.appDir)
29+
globalVars.appPid = os.getpid()
2930

3031

3132
import gettext

source/watchdog.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ def _crashHandler(exceptionInfo):
194194
mdExc = MINIDUMP_EXCEPTION_INFORMATION(ThreadId=threadId,
195195
ExceptionPointers=exceptionInfo, ClientPointers=False)
196196
if not ctypes.windll.DbgHelp.MiniDumpWriteDump(
197-
ctypes.windll.kernel32.GetCurrentProcess(),
198-
os.getpid(),
197+
winKernel.kernel32.GetCurrentProcess(),
198+
globalVars.appPid,
199199
msvcrt.get_osfhandle(mdf.fileno()),
200200
0, # MiniDumpNormal
201201
ctypes.byref(mdExc),

0 commit comments

Comments
 (0)