Skip to content

Commit

Permalink
Merge 3b31a3c into 9823556
Browse files Browse the repository at this point in the history
  • Loading branch information
seanbudd authored Dec 7, 2022
2 parents 9823556 + 3b31a3c commit 7ea24b5
Show file tree
Hide file tree
Showing 13 changed files with 455 additions and 296 deletions.
9 changes: 9 additions & 0 deletions source/NVDAObjects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
TreeInterceptor,
)
import braille
from utils.security import _isObjectAboveLockScreen
import vision
import globalPluginHandler
import brailleInput
Expand Down Expand Up @@ -1433,3 +1434,11 @@ def getSelectedItemsCount(self,maxCount=2):
For performance, this method will only count up to the given maxCount number, and if there is one more above that, then sys.maxint is returned stating that many items are selected.
"""
return 0

#: Type definition for auto prop '_get_isAboveLockScreen'
isAboveLockScreen: bool

def _get_isAboveLockScreen(self) -> bool:
if not isWindowsLocked():
return True
return _isObjectAboveLockScreen(self)
5 changes: 4 additions & 1 deletion source/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,10 @@ def setReviewPosition(
@param isCaret: Whether the review position is changed due to caret following.
@param isMouse: Whether the review position is changed due to mouse following.
"""
if _isSecureObjectWhileLockScreenActivated(reviewPosition.obj):
reviewObj = reviewPosition.obj
if isinstance(reviewObj, treeInterceptorHandler.TreeInterceptor):
reviewObj = reviewObj.rootNVDAObject
if _isSecureObjectWhileLockScreenActivated(reviewObj):
return False
globalVars.reviewPosition=reviewPosition.copy()
globalVars.reviewPositionObj=reviewPosition.obj
Expand Down
30 changes: 26 additions & 4 deletions source/baseObject.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2007-2020 NV Access Limited, Christopher Toth, Babbage B.V., Julien Cochuyt
# Copyright (C) 2007-2022 NV Access Limited, Christopher Toth, Babbage B.V., Julien Cochuyt
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

"""Contains the base classes that many of NVDA's classes such as NVDAObjects, virtualBuffers, appModules, synthDrivers inherit from. These base classes provide such things as auto properties, and methods and properties for scripting and key binding.
"""

from typing import (
Any,
Callable,
Optional,
Set,
Union,
)
import weakref
import garbageHandler
from logHandler import log
from abc import ABCMeta, abstractproperty

GetterReturnT = Any
GetterMethodT = Callable[["AutoPropertyObject"], GetterReturnT]


class Getter(object):

def __init__(self,fget, abstract=False):
self.fget=fget
if abstract:
self._abstract = self.__isabstractmethod__ = abstract

def __get__(self,instance,owner):
def __get__(
self,
instance: Union[Any, None, "AutoPropertyObject"],
owner,
) -> Union[GetterReturnT, "Getter"]:
if isinstance(self.fget, classmethod):
return self.fget.__get__(instance, owner)()
elif instance is None:
Expand All @@ -31,16 +46,22 @@ def setter(self,func):
def deleter(self,func):
return (abstractproperty if self._abstract else property)(fget=self.fget,fdel=func)


class CachingGetter(Getter):

def __get__(self, instance, owner):
def __get__(
self,
instance: Union[Any, None, "AutoPropertyObject"],
owner,
) -> Union[GetterReturnT, "CachingGetter"]:
if isinstance(self.fget, classmethod):
log.warning("Class properties do not support caching")
return self.fget.__get__(instance, owner)()
elif instance is None:
return self
return instance._getPropertyViaCache(self.fget)


class AutoPropertyType(ABCMeta):

def __init__(self,name,bases,dict):
Expand Down Expand Up @@ -125,6 +146,7 @@ class AutoPropertyObject(garbageHandler.TrackedObject, metaclass=AutoPropertyTyp
#: @type: bool
cachePropertiesByDefault = False

_propertyCache: Set[GetterMethodT]

def __new__(cls, *args, **kwargs):
self = super(AutoPropertyObject, cls).__new__(cls)
Expand All @@ -134,7 +156,7 @@ def __new__(cls, *args, **kwargs):
self.__instances[self]=None
return self

def _getPropertyViaCache(self,getterMethod=None):
def _getPropertyViaCache(self, getterMethod: Optional[GetterMethodT] = None) -> GetterReturnT:
if not getterMethod:
raise ValueError("getterMethod is None")
missing=False
Expand Down
22 changes: 5 additions & 17 deletions source/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,6 @@ def onEndSession(evt):
wx.CallAfter(audioDucking.initialize)

from winAPI.messageWindow import WindowMessage
from winAPI import sessionTracking
import winUser
# #3763: In wxPython 3, the class name of frame windows changed from wxWindowClassNR to wxWindowNR.
# NVDA uses the main frame to check for and quit another instance of NVDA.
Expand Down Expand Up @@ -630,27 +629,12 @@ def __init__(self, windowName=None):
self.orientationCoordsCache = (0,0)
self.handlePowerStatusChange()

# Call must be paired with a call to sessionTracking.unregister
if not sessionTracking.register(self.handle):
import utils.security
wx.CallAfter(utils.security.warnSessionLockStateUnknown)

def destroy(self):
"""
NVDA must unregister session tracking before destroying the message window.
"""
# Requires an active message window and a handle to unregister.
sessionTracking.unregister(self.handle)
super().destroy()

def windowProc(self, hwnd, msg, wParam, lParam):
post_windowMessageReceipt.notify(msg=msg, wParam=wParam, lParam=lParam)
if msg == WindowMessage.POWER_BROADCAST and wParam == self.PBT_APMPOWERSTATUSCHANGE:
self.handlePowerStatusChange()
elif msg == winUser.WM_DISPLAYCHANGE:
self.handleScreenOrientationChange(lParam)
elif msg == WindowMessage.WTS_SESSION_CHANGE:
sessionTracking.handleSessionChange(sessionTracking.WindowsTrackedSession(wParam), lParam)

def handleScreenOrientationChange(self, lParam):
# TODO: move to winAPI
Expand Down Expand Up @@ -809,7 +793,8 @@ def run(self):
mouseHandler.pumpAll()
braille.pumpAll()
vision.pumpAll()
except:
sessionTracking.pumpAll()
except Exception:
log.exception("errors in this core pump cycle")
baseObject.AutoPropertyObject.invalidateCaches()
watchdog.asleep()
Expand All @@ -832,6 +817,9 @@ def run(self):
log.debug("initializing updateCheck")
updateCheck.initialize()

from winAPI import sessionTracking
sessionTracking.initialize()

_TrackNVDAInitialization.markInitializationComplete()

log.info("NVDA initialized")
Expand Down
3 changes: 2 additions & 1 deletion source/globalVars.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

if typing.TYPE_CHECKING:
import NVDAObjects # noqa: F401 used for type checking only
import textInfos # noqa: F401 used for type checking only


class DefaultAppArgs(argparse.Namespace):
Expand Down Expand Up @@ -70,7 +71,7 @@ class DefaultAppArgs(argparse.Namespace):
mouseOldY=None
navigatorObject: typing.Optional['NVDAObjects.NVDAObject'] = None
reviewPosition=None
reviewPositionObj=None
reviewPositionObj: typing.Optional["textInfos.TextInfoObjT"] = None
lastProgressValue=0
appArgs = DefaultAppArgs()
unknownAppArgs: typing.List[str] = []
Expand Down
12 changes: 9 additions & 3 deletions source/nvda.pyw
Original file line number Diff line number Diff line change
Expand Up @@ -350,13 +350,19 @@ if mutex is None:
sys.exit(1)


if _isSecureDesktop():
def _serviceDebugEnabled() -> bool:
import winreg
try:
k = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\NVDA")
if not winreg.QueryValueEx(k, u"serviceDebug")[0]:
globalVars.appArgs.secure = True
if winreg.QueryValueEx(k, "serviceDebug")[0]:
return True
except WindowsError:
pass
return False


if _isSecureDesktop():
if not _serviceDebugEnabled():
globalVars.appArgs.secure = True
globalVars.appArgs.changeScreenReaderFlag = False
globalVars.appArgs.minimal = True
Expand Down
16 changes: 12 additions & 4 deletions source/textInfos/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# A part of NonVisual Desktop Access (NVDA)
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.
# Copyright (C) 2006-2021 NV Access Limited, Babbage B.V., Accessolutions, Julien Cochuyt
# Copyright (C) 2006-2022 NV Access Limited, Babbage B.V., Accessolutions, Julien Cochuyt

"""Framework for accessing text content in widgets.
The core component of this framework is the L{TextInfo} class.
Expand Down Expand Up @@ -32,6 +32,7 @@

if typing.TYPE_CHECKING:
import NVDAObjects
import treeInterceptorHandler # noqa: F401 used for type checking only

SpeechSequence = List[Union[Any, str]]

Expand Down Expand Up @@ -287,6 +288,9 @@ def _logBadSequenceTypes(sequence: SpeechSequence, shouldRaise: bool = True):
return speech.types.logBadSequenceTypes(sequence, raiseExceptionOnError=shouldRaise)


TextInfoObjT = Union["NVDAObjects.NVDAObject", "treeInterceptorHandler.TreeInterceptor"]


class TextInfo(baseObject.AutoPropertyObject):
"""Provides information about a range of text in an object and facilitates access to all text in the widget.
A TextInfo represents a specific range of text, providing access to the text itself, as well as information about the text such as its formatting and any associated controls.
Expand All @@ -307,7 +311,11 @@ class TextInfo(baseObject.AutoPropertyObject):
@type bookmark: L{Bookmark}
"""

def __init__(self,obj,position):
def __init__(
self,
obj: TextInfoObjT,
position
):
"""Constructor.
Subclasses must extend this, calling the superclass method first.
@param position: The initial position of this range; one of the POSITION_* constants or a position object supported by the implementation.
Expand Down Expand Up @@ -338,9 +346,9 @@ def _set_end(self, otherEndpoint: "TextInfoEndpoint"):
self.end.moveTo(otherEndpoint)

#: Typing information for auto-property: _get_obj
obj: "NVDAObjects.NVDAObject"
obj: TextInfoObjT

def _get_obj(self) -> "NVDAObjects.NVDAObject":
def _get_obj(self) -> TextInfoObjT:
"""The object containing the range of text being represented."""
return self._obj()

Expand Down
18 changes: 12 additions & 6 deletions source/treeInterceptorHandler.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# treeInterceptorHandler.py
# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2006-2020 NV Access Limited, Davy Kager, Accessolutions, Julien Cochuyt
# Copyright (C) 2006-2022 NV Access Limited, Davy Kager, Accessolutions, Julien Cochuyt
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

from typing import Optional, Dict
from typing import (
TYPE_CHECKING,
Dict,
Optional,
)

from logHandler import log
import baseObject
Expand All @@ -18,6 +21,10 @@
from speech.types import SpeechSequence
from controlTypes import OutputReason

if TYPE_CHECKING:
import NVDAObjects


runningTable=set()

def getTreeInterceptor(obj):
Expand Down Expand Up @@ -84,12 +91,11 @@ class TreeInterceptor(baseObject.ScriptableObject):

shouldTrapNonCommandGestures=False #: If true then gestures that do not have a script and are not a command gesture should be trapped from going through to Windows.

def __init__(self, rootNVDAObject):
def __init__(self, rootNVDAObject: "NVDAObjects.NVDAObject"):
super(TreeInterceptor, self).__init__()
self._passThrough = False
#: The root object of the tree wherein events and scripts are intercepted.
#: @type: L{NVDAObjects.NVDAObject}
self.rootNVDAObject = rootNVDAObject
self.rootNVDAObject: "NVDAObjects.NVDAObject" = rootNVDAObject

def terminate(self):
"""Terminate this interceptor.
Expand Down
Loading

0 comments on commit 7ea24b5

Please sign in to comment.