Skip to content

Commit b8265c6

Browse files
LeonarddeRmichaelDCurran
authored andcommitted
displayModel.getCaretRect: return a locationHelper.RectLTRB instance (#10233)
* displayModel.getCaretRect: return a locationHelper.RectLTRB instance * RuntimeError
1 parent 348c350 commit b8265c6

2 files changed

Lines changed: 31 additions & 22 deletions

File tree

‎source/displayModel.py‎

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#See the file COPYING for more details.
55
#Copyright (C) 2006-2017 NV Access Limited, Babbage B.V.
66

7+
import ctypes
78
from ctypes import *
89
from ctypes.wintypes import RECT
910
from comtypes import BSTR
@@ -169,14 +170,22 @@ def initialize():
169170
_requestTextChangeNotificationsForWindow=NVDAHelper.localLib.displayModel_requestTextChangeNotificationsForWindow
170171

171172
def getCaretRect(obj):
172-
left=c_long()
173-
top=c_long()
174-
right=c_long()
175-
bottom=c_long()
176-
res=watchdog.cancellableExecute(NVDAHelper.localLib.displayModel_getCaretRect, obj.appModule.helperLocalBindingHandle, obj.windowThreadID, byref(left),byref(top),byref(right),byref(bottom))
177-
if res!=0:
178-
raise RuntimeError("displayModel_getCaretRect failed with res %d"%res)
179-
return RECT(left,top,right,bottom)
173+
left = ctypes.c_long()
174+
top = ctypes.c_long()
175+
right = ctypes.c_long()
176+
bottom = ctypes.c_long()
177+
res = watchdog.cancellableExecute(
178+
NVDAHelper.localLib.displayModel_getCaretRect,
179+
obj.appModule.helperLocalBindingHandle,
180+
obj.windowThreadID,
181+
ctypes.byref(left),
182+
ctypes.byref(top),
183+
ctypes.byref(right),
184+
ctypes.byref(bottom)
185+
)
186+
if res != 0:
187+
raise RuntimeError(f"displayModel_getCaretRect failed with res {res}")
188+
return RectLTRB(left, top, right, bottom)
180189

181190
def getWindowTextInRect(bindingHandle, windowHandle, left, top, right, bottom,minHorizontalWhitespace,minVerticalWhitespace,stripOuterWhitespace=True,includeDescendantWindows=True):
182191
text, cpBuf = watchdog.cancellableExecute(_getWindowTextInRect, bindingHandle, windowHandle, includeDescendantWindows, left, top, right, bottom,minHorizontalWhitespace,minVerticalWhitespace,stripOuterWhitespace)
@@ -555,7 +564,12 @@ class EditableTextDisplayModelTextInfo(DisplayModelTextInfo):
555564
minVerticalWhitespace=4
556565
stripOuterWhitespace=False
557566

558-
def _findCaretOffsetFromLocation(self,caretRect,validateBaseline=True,validateDirection=True):
567+
def _findCaretOffsetFromLocation(
568+
selff,
569+
caretRect: RectLTRB,
570+
validateBaseline: bool = True,
571+
validateDirection: bool = True
572+
):
559573
# Accepts logical coordinates.
560574
for charOffset, ((charLeft, charTop, charRight, charBottom),charBaseline,charDirection) in enumerate(self._getStoryOffsetLocations()):
561575
# Skip any character that does not overlap the caret vertically
@@ -577,17 +591,12 @@ def _findCaretOffsetFromLocation(self,caretRect,validateBaseline=True,validateDi
577591
raise LookupError
578592

579593
def _getCaretOffset(self):
580-
caretRect=getCaretRect(self.obj)
581-
objLocation=self.obj.location
582-
objRect=RECT(objLocation[0],objLocation[1],objLocation[0]+objLocation[2],objLocation[1]+objLocation[3])
583-
objRect.left,objRect.top=windowUtils.physicalToLogicalPoint(
584-
self.obj.windowHandle,objRect.left,objRect.top)
585-
objRect.right,objRect.bottom=windowUtils.physicalToLogicalPoint(
586-
self.obj.windowHandle,objRect.right,objRect.bottom)
587-
caretRect.left=max(objRect.left,caretRect.left)
588-
caretRect.top=max(objRect.top,caretRect.top)
589-
caretRect.right=min(objRect.right,caretRect.right)
590-
caretRect.bottom=min(objRect.bottom,caretRect.bottom)
594+
caretRect = getCaretRect(self.obj)
595+
objLocation = self.obj.location
596+
objRect = objLocation.toLTRB().toLogical(self.obj.windowHandle)
597+
caretRect = caretRect.intersection(objRect)
598+
if not any(caretRect):
599+
raise RuntimeError("The caret rectangle does not overlap with the window")
591600
# Find a character offset where the caret overlaps vertically, overlaps horizontally, overlaps the baseline and is totally within or on the correct side for the reading order
592601
try:
593602
return self._findCaretOffsetFromLocation(caretRect,validateBaseline=True,validateDirection=True)

‎source/vision/util.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ def getCaretRect(obj: Optional[TextContainerObject] = None) -> locationHelper.Re
2727
obj = obj.treeInterceptor
2828
if api.isNVDAObject(obj):
2929
# Import late to avoid circular import
30-
from displayModel import getCaretRect
30+
import displayModel
3131
# Check whether there is a caret in the window.
3232
# Note that, even windows that don't have navigable text could have a caret, such as in Excel.
3333
try:
34-
return locationHelper.RectLTRB.fromCompatibleType(getCaretRect(obj))
34+
return displayModel.getCaretRect(obj)
3535
except RuntimeError:
3636
if not obj._hasNavigableText:
3737
raise LookupError

0 commit comments

Comments
 (0)