Skip to content

Commit dbca3e5

Browse files
authored
Merge 90c8503 into 814f11e
2 parents 814f11e + 90c8503 commit dbca3e5

3 files changed

Lines changed: 83 additions & 10 deletions

File tree

source/core.py

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,78 @@ def _handleNVDAModuleCleanupBeforeGUIExit():
419419
brailleViewer.destroyBrailleViewer()
420420

421421

422+
def _pollForForegroundHWND() -> int:
423+
import ui
424+
import winUser
425+
426+
foregroundHWND = winUser.getForegroundWindow()
427+
_hasWarned = False
428+
WARN_AFTER_SECS = 5
429+
MAX_WAIT_TIME_SECS = 20
430+
POLL_INTERVAL_SECS = 0.1
431+
waitForForegroundHWND_startTime = time.time()
432+
433+
while not foregroundHWND:
434+
# The foreground window can be NULL in certain circumstances,
435+
# such as when a window is losing activation.
436+
# This should not remain the case for an extended period of time.
437+
438+
_timeElapsed = time.time() - waitForForegroundHWND_startTime
439+
if (
440+
not _hasWarned
441+
and _timeElapsed > WARN_AFTER_SECS
442+
):
443+
_hasWarned = True
444+
# Allow for braille / speech to be understood before exiting.
445+
# Unfortunately we cannot block with a dialog as NVDA cannot read dialogs yet.
446+
ui.message(_(
447+
# Translators: Message when NVDA is having an issue starting up
448+
"NVDA is failing to fetch the foreground window. "
449+
"If this continues, NVDA will quit starting in %d seconds." % (MAX_WAIT_TIME_SECS - WARN_AFTER_SECS)
450+
))
451+
452+
if _timeElapsed > MAX_WAIT_TIME_SECS:
453+
log.critical("NVDA could not fetch the foreground window. Exiting NVDA.")
454+
# Raising exception here causes core.main to exit and NVDA to fail to start
455+
raise NVDANotInitializedError("Could not fetch foreground window")
456+
457+
log.debugWarning("Foreground window not found, fetching again")
458+
time.sleep(POLL_INTERVAL_SECS)
459+
foregroundHWND = winUser.getForegroundWindow()
460+
461+
return foregroundHWND
462+
463+
464+
def _initializeObjectCaches():
465+
"""
466+
Caches the desktop object.
467+
This may make information from the desktop window available on the lock screen,
468+
however no known exploit is known for this.
469+
2023.1 plans to ensure the desktopObject is available only when signed-in.
470+
471+
Also initializes other object caches to the foreground window.
472+
Previously the object that was cached was the desktopObject,
473+
however this may leak secure information to the lock screen.
474+
The foreground window is set as the object cache,
475+
as the foreground window would already be accessible on the lock screen (e.g. Magnifier).
476+
It also is more intuitive that NVDA focuses the foreground window,
477+
as opposed to the desktop object.
478+
"""
479+
import api
480+
import NVDAObjects
481+
import winUser
482+
483+
desktopObject = NVDAObjects.window.Window(windowHandle=winUser.getDesktopWindow())
484+
api.setDesktopObject(desktopObject)
485+
486+
foregroundHWND = _pollForForegroundHWND()
487+
foregroundObject = NVDAObjects.window.Window(windowHandle=foregroundHWND)
488+
api.setForegroundObject(foregroundObject)
489+
api.setFocusObject(foregroundObject)
490+
api.setNavigatorObject(foregroundObject)
491+
api.setMouseObject(foregroundObject)
492+
493+
422494
def main():
423495
"""NVDA's core main loop.
424496
This initializes all modules such as audio, IAccessible, keyboard, mouse, and GUI.
@@ -667,14 +739,8 @@ def handlePowerStatusChange(self):
667739
log.debug("Initializing garbageHandler")
668740
garbageHandler.initialize()
669741

670-
import api
671-
import winUser
672-
import NVDAObjects.window
673-
desktopObject=NVDAObjects.window.Window(windowHandle=winUser.getDesktopWindow())
674-
api.setDesktopObject(desktopObject)
675-
api.setFocusObject(desktopObject)
676-
api.setNavigatorObject(desktopObject)
677-
api.setMouseObject(desktopObject)
742+
_initializeObjectCaches()
743+
678744
import JABHandler
679745
log.debug("initializing Java Access Bridge support")
680746
try:

source/winUser.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#dll handles
1919
user32=windll.user32
2020

21+
# rather than using the ctypes.c_void_p type, which may encourage attempting to dereference
22+
# what may be an invalid or illegal pointer, we'll treat it as an opaque value.
23+
HWNDVal = int
24+
2125
LRESULT=c_long
2226
HCURSOR=c_long
2327

@@ -458,7 +462,7 @@ def isDescendantWindow(parentHwnd,childHwnd):
458462
return False
459463

460464

461-
def getForegroundWindow() -> HWND:
465+
def getForegroundWindow() -> HWNDVal:
462466
return user32.GetForegroundWindow()
463467

464468
def setForegroundWindow(hwnd):
@@ -467,9 +471,11 @@ def setForegroundWindow(hwnd):
467471
def setFocus(hwnd):
468472
user32.SetFocus(hwnd)
469473

470-
def getDesktopWindow():
474+
475+
def getDesktopWindow() -> HWNDVal:
471476
return user32.GetDesktopWindow()
472477

478+
473479
def getControlID(hwnd):
474480
return user32.GetWindowLongW(hwnd,GWL_ID)
475481

user_docs/en/changes.t2t

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ This is a minor release to fix regressions with 2022.3.1 and address a security
1111

1212
== Bug Fixes ==
1313
- Fixes a regression from 2022.3.1 where certain functionality was disabled on secure screens. (#14286)
14+
- Fixes a regression from 2022.3.1 where certain functionality was disabled after sign-in, if NVDA started on the lock screen. (#14301)
1415
-
1516

1617

0 commit comments

Comments
 (0)