|
1 | 1 | # A part of NonVisual Desktop Access (NVDA) |
2 | 2 | # Copyright (C) 2006-2023 NV Access Limited, Dinesh Kaushal, Siddhartha Gupta, Accessolutions, Julien Cochuyt, |
3 | | -# Cyrille Bougot |
| 3 | +# Cyrille Bougot, Leonard de Ruijter |
4 | 4 | # This file is covered by the GNU General Public License. |
5 | 5 | # See the file COPYING for more details. |
6 | 6 |
|
@@ -712,7 +712,6 @@ class ExcelWorksheet(ExcelBase): |
712 | 712 |
|
713 | 713 |
|
714 | 714 | treeInterceptorClass=ExcelBrowseModeTreeInterceptor |
715 | | - |
716 | 715 | role=controlTypes.Role.TABLE |
717 | 716 |
|
718 | 717 | def _get_excelApplicationObject(self): |
@@ -953,28 +952,43 @@ def _get_states(self): |
953 | 952 | ), canPropagate=True) |
954 | 953 |
|
955 | 954 | def script_changeSelection(self,gesture): |
956 | | - oldSelection=api.getFocusObject() |
| 955 | + oldSelection = self._getSelection() |
957 | 956 | gesture.send() |
958 | | - import eventHandler |
959 | | - import time |
960 | | - newSelection=None |
961 | | - curTime=startTime=time.time() |
962 | | - while (curTime-startTime)<=0.15: |
| 957 | + newSelection = None |
| 958 | + start = time.time() |
| 959 | + retryInterval = 0.01 |
| 960 | + maxTimeout = 0.15 |
| 961 | + elapsed = 0 |
| 962 | + retries = 0 |
| 963 | + while True: |
963 | 964 | if scriptHandler.isScriptWaiting(): |
964 | 965 | # Prevent lag if keys are pressed rapidly |
965 | 966 | return |
| 967 | + api.processPendingEvents(processEventQueue=False) |
966 | 968 | if eventHandler.isPendingEvents('gainFocus'): |
| 969 | + # This object is no longer focused. |
967 | 970 | return |
968 | | - newSelection=self._getSelection() |
969 | | - if newSelection and newSelection!=oldSelection: |
| 971 | + newSelection = self._getSelection() |
| 972 | + if newSelection and newSelection != oldSelection: |
| 973 | + log.debug(f"Detected new selection after {elapsed} sec") |
970 | 974 | break |
971 | | - api.processPendingEvents(processEventQueue=False) |
972 | | - time.sleep(0.015) |
973 | | - curTime=time.time() |
| 975 | + elapsed = time.time() - start |
| 976 | + if elapsed >= maxTimeout: |
| 977 | + log.debug(f"Canceled detecting new selection after {elapsed} sec") |
| 978 | + break |
| 979 | + # We spin the first few tries, as sleep is not accurate for tiny periods |
| 980 | + # and we might end up sleeping longer than we need to. Spinning improves |
| 981 | + # responsiveness in the case that the app responds fairly quickly. |
| 982 | + if retries > 2: |
| 983 | + # Don't spin too long, though. If we get to this point, the app is |
| 984 | + # probably taking a while to respond, so super fast response is |
| 985 | + # already lost. |
| 986 | + time.sleep(retryInterval) |
| 987 | + retries += 1 |
974 | 988 | if newSelection: |
975 | 989 | if oldSelection.parent==newSelection.parent: |
976 | 990 | newSelection.parent=oldSelection.parent |
977 | | - eventHandler.executeEvent('gainFocus',newSelection) |
| 991 | + eventHandler.executeEvent('gainFocus', newSelection) |
978 | 992 |
|
979 | 993 | def _WaitForValueChangeForAction(self, action, fetcher, timeout=0.15): |
980 | 994 | oldVal = fetcher() |
|
0 commit comments