def _getCaretOffset(self): caretRect = winUser.getGUIThreadInfo(self.obj.windowThreadID).rcCaret objLocation = self.obj.location objRect = RECT(objLocation[0], objLocation[1], objLocation[0] + objLocation[2], objLocation[1] + objLocation[3]) tempPoint = winUser.POINT() tempPoint.x = caretRect.left tempPoint.y = caretRect.top winUser.user32.ClientToScreen(self.obj.windowHandle, byref(tempPoint)) caretRect.left = max(objRect.left, tempPoint.x) caretRect.top = max(objRect.top, tempPoint.y) tempPoint.x = caretRect.right tempPoint.y = caretRect.bottom winUser.user32.ClientToScreen(self.obj.windowHandle, byref(tempPoint)) caretRect.right = min(objRect.right, tempPoint.x) caretRect.bottom = min(objRect.bottom, tempPoint.y) for charOffset, (charLeft, charTop, charRight, charBottom, charBaseline) in enumerate(self._textAndRects[1]): # Real text with a character baseline # The caret must be anywhere before the horizontal center of the character and the bottom of the caret must touch or go through the character baseline if ( charBaseline >= 0 and caretRect.left < ((charLeft + charRight) / 2) and caretRect.top < charBaseline <= caretRect.bottom ): return charOffset for charOffset, (charLeft, charTop, charRight, charBottom, charBaseline) in enumerate(self._textAndRects[1]): # vertical whitespace (possible blank lines) # The caret must be fully contained in the whitespace to match if ( charBaseline == -1 and caretRect.left >= charLeft and caretRect.right <= charRight and not (caretRect.bottom <= charTop or charBottom <= caretRect.top) ): return charOffset raise RuntimeError
def _getCaretOffset(self): caretRect = winUser.getGUIThreadInfo(self.obj.windowThreadID).rcCaret objLocation = self.obj.location objRect = RECT(objLocation[0], objLocation[1], objLocation[0] + objLocation[2], objLocation[1] + objLocation[3]) tempPoint = winUser.POINT() tempPoint.x = caretRect.left tempPoint.y = caretRect.top winUser.user32.ClientToScreen(self.obj.windowHandle, byref(tempPoint)) caretRect.left = max(objRect.left, tempPoint.x) caretRect.top = max(objRect.top, tempPoint.y) tempPoint.x = caretRect.right tempPoint.y = caretRect.bottom winUser.user32.ClientToScreen(self.obj.windowHandle, byref(tempPoint)) caretRect.right = min(objRect.right, tempPoint.x) caretRect.bottom = min(objRect.bottom, tempPoint.y) for charOffset, (charLeft, charTop, charRight, charBottom, charBaseline) in enumerate(self._textAndRects[1]): #Real text with a character baseline #The caret must be anywhere before the horizontal center of the character and the bottom of the caret must touch or go through the character baseline if charBaseline >= 0 and caretRect.left < ( (charLeft + charRight) / 2) and caretRect.top < charBaseline <= caretRect.bottom: return charOffset for charOffset, (charLeft, charTop, charRight, charBottom, charBaseline) in enumerate(self._textAndRects[1]): #vertical whitespace (possible blank lines) #The caret must be fully contained in the whitespace to match if charBaseline == -1 and caretRect.left >= charLeft and caretRect.right <= charRight and not ( caretRect.bottom <= charTop or charBottom <= caretRect.top): return charOffset raise RuntimeError
def _get_shouldAllowIAccessibleFocusEvent(self): focusWindow = winUser.getGUIThreadInfo(self.windowThreadID).hwndFocus if self.windowHandle != focusWindow: # This window doesn't have the focus, which means the embedded object's window probably already has the focus. # We don't want to override the focus event fired by the embedded object. return False return super(EmbeddedObject, self).shouldAllowIAccessibleFocusEvent
def findOverlayClasses(self, clsList): windowClassName = self.normalizeWindowClassName(self.windowClassName) newCls = None if windowClassName == "#32769": newCls = Desktop elif windowClassName == "Edit": from .edit import Edit as newCls elif windowClassName == "RichEdit": from .edit import RichEdit as newCls elif windowClassName in ("RichEdit20", "REComboBox20W"): from .edit import RichEdit20 as newCls elif windowClassName == "RICHEDIT50W": from .edit import RichEdit50 as newCls elif windowClassName in ("Scintilla", "TScintilla"): from .scintilla import Scintilla as newCls elif windowClassName in ("AkelEditW", "AkelEditA"): from .akelEdit import AkelEdit as newCls elif windowClassName == "ConsoleWindowClass": from .winConsole import WinConsole as newCls elif windowClassName == "EXCEL7": from .excel import Excel7Window as newCls if newCls: clsList.append(newCls) #If none of the chosen classes seem to support text editing #But there is a caret currently in the window #Then use the displayModelEditableText class to emulate text editing capabilities if not any(issubclass(cls, EditableText) for cls in clsList): gi = winUser.getGUIThreadInfo(self.windowThreadID) if gi.hwndCaret == self.windowHandle and gi.flags & winUser.GUI_CARETBLINKING: clsList.append(DisplayModelEditableText) clsList.append(Window) super(Window, self).findOverlayClasses(clsList)
def event_NVDAObject_init(self,obj): if controlTypes.STATE_FOCUSED in obj.states: obj.windowHandle=winUser.getGUIThreadInfo(None).hwndFocus obj.windowClassName=winUser.getClassName(obj.windowHandle) if obj.value and obj.windowClassName in ["TMainUserList", "TConversationList", "TInboxList", "TActiveConversationList", "TConversationsControl"] and not obj.role in [controlTypes.ROLE_MENUBAR, controlTypes.ROLE_MENUITEM, controlTypes.ROLE_POPUPMENU]: obj.name=obj.value obj.value=None
def _get_shouldAllowIAccessibleFocusEvent(self): # The window must really have focus. # Outlook can sometimes fire invalid focus events when showing daily tasks within the calendar. if winUser.getGUIThreadInfo( self.windowThreadID).hwndFocus != self.windowHandle: return False return super(SuperGridClient2010, self).shouldAllowIAccessibleFocusEvent
def _get_SDMChild(self): if controlTypes.STATE_FOCUSED in self.states: hwndFocus=winUser.getGUIThreadInfo(0).hwndFocus if hwndFocus and hwndFocus!=self.windowHandle and not winUser.getClassName(hwndFocus).startswith('bosa_sdm'): obj=getNVDAObjectFromEvent(hwndFocus,winUser.OBJID_CLIENT,0) if not obj: return None if getattr(obj,'parentSDMCanOverrideName',True): obj.name=self.name return obj return None
def WindowSelectionChange(self,sel): i=winUser.getGUIThreadInfo(0) oldFocus=api.getFocusObject() if not isinstance(oldFocus,Window) or i.hwndFocus!=oldFocus.windowHandle: return if isinstance(oldFocus,DocumentWindow): documentWindow=oldFocus elif isinstance(oldFocus,PpObject): documentWindow=oldFocus.documentWindow else: return documentWindow.ppSelection=sel documentWindow.handleSelectionChange()
def event_NVDAObject_init(self, obj): if controlTypes.STATE_FOCUSED in obj.states and obj.role not in ( controlTypes.ROLE_POPUPMENU, controlTypes.ROLE_MENUITEM): obj.windowHandle = winUser.getGUIThreadInfo(None).hwndFocus obj.windowClassName = winUser.getClassName(obj.windowHandle) if obj.value and obj.windowClassName in [ "TMainUserList", "TConversationList", "TInboxList", "TActiveConversationList", "TConversationsControl" ] and not obj.role in [ controlTypes.ROLE_MENUBAR, controlTypes.ROLE_MENUITEM, controlTypes.ROLE_POPUPMENU ]: obj.name = obj.value obj.value = None
def event_NVDAObject_init(self,obj): if isinstance(obj, NVDAObjects.IAccessible.IAccessible) and obj.event_objectID is None and controlTypes.STATE_FOCUSED in obj.states and obj.role not in (controlTypes.ROLE_POPUPMENU,controlTypes.ROLE_MENUITEM,controlTypes.ROLE_MENUBAR): # The window handle reported by Skype accessibles is sometimes incorrect. # This object is focused, so we can override with the focus window. obj.windowHandle=winUser.getGUIThreadInfo(None).hwndFocus obj.windowClassName=winUser.getClassName(obj.windowHandle) if obj.value and obj.windowClassName in ("TMainUserList", "TConversationList", "TInboxList", "TActiveConversationList", "TConversationsControl"): # The name and value both include the user's name, so kill the value to avoid doubling up. # The value includes the Skype name, # but we care more about the additional info (e.g. new event count) included in the name. obj.value=None elif isinstance(obj, NVDAObjects.IAccessible.IAccessible) and obj.IAccessibleRole == oleacc.ROLE_SYSTEM_PANE and not obj.name: # Prevent extraneous reporting of pane when tabbing through a conversation form. obj.shouldAllowIAccessibleFocusEvent = False
def shouldConfigProfileTriggersBeSuspended(): """Determine whether configuration profile triggers should be suspended in relation to NVDA's GUI. For NVDA configuration dialogs, the configuration should remain the same as it was before the GUI was popped up so the user can change settings in the correct profile. Top-level windows that require this behavior should have a C{shouldSuspendConfigProfileTriggers} attribute set to C{True}. Because these dialogs are often opened via the NVDA menu, this applies to the NVDA menu as well. """ if winUser.getGUIThreadInfo(ctypes.windll.kernel32.GetCurrentThreadId()).flags & 0x00000010: # The NVDA menu is active. return True for window in wx.GetTopLevelWindows(): if window.IsShown() and getattr(window, "shouldSuspendConfigProfileTriggers", False): return True return False
def kwargsFromSuper(cls,kwargs,relation=None): windowHandle=None if relation in ('focus','foreground'): windowHandle=winUser.getForegroundWindow() if not windowHandle: windowHandle=winUser.getDesktopWindow() if windowHandle and relation=="focus": threadID=winUser.getWindowThreadProcessID(windowHandle)[1] threadInfo=winUser.getGUIThreadInfo(threadID) if threadInfo.hwndFocus: windowHandle=threadInfo.hwndFocus elif isinstance(relation,tuple): windowHandle=_windowFromPoint(ctypes.wintypes.POINT(relation[0],relation[1])) if not windowHandle: return False kwargs['windowHandle']=windowHandle return True
def _shouldRecoverAfterMinTimeout(): info=winUser.getGUIThreadInfo(0) #If hwndFocus is 0, then the OS is clearly busy and we don't want to timeout prematurely. if not info.hwndFocus: return False # Import late to avoid circular import. import api #If a system menu has been activated but NVDA's focus is not yet in the menu then use min timeout if info.flags&winUser.GUI_SYSTEMMENUMODE and info.hwndMenuOwner and api.getFocusObject().windowClassName!='#32768': return True if winUser.getClassName(info.hwndFocus) in safeWindowClassSet: return False if not winUser.isDescendantWindow(info.hwndActive, api.getFocusObject().windowHandle): # The foreground window has changed. return True newHwnd=info.hwndFocus newThreadID=winUser.getWindowThreadProcessID(newHwnd)[1] return newThreadID!=api.getFocusObject().windowThreadID
def _shouldRecoverAfterMinTimeout(): info=winUser.getGUIThreadInfo(0) if not info.hwndFocus: # The foreground thread is frozen or there is no foreground thread (probably due to a freeze elsewhere). return True # Import late to avoid circular import. import api #If a system menu has been activated but NVDA's focus is not yet in the menu then use min timeout if info.flags&winUser.GUI_SYSTEMMENUMODE and info.hwndMenuOwner and api.getFocusObject().windowClassName!='#32768': return True if winUser.getClassName(info.hwndFocus) in safeWindowClassSet: return False if not winUser.isDescendantWindow(info.hwndActive, api.getFocusObject().windowHandle): # The foreground window has changed. return True newHwnd=info.hwndFocus newThreadID=winUser.getWindowThreadProcessID(newHwnd)[1] return newThreadID!=api.getFocusObject().windowThreadID
def _getCaretOffset(self): caretRect = winUser.getGUIThreadInfo(self.obj.windowThreadID).rcCaret objLocation=self.obj.location objRect=RECT(objLocation[0],objLocation[1],objLocation[0]+objLocation[2],objLocation[1]+objLocation[3]) tempPoint = winUser.POINT() tempPoint.x=caretRect.left tempPoint.y=caretRect.top winUser.user32.ClientToScreen(self.obj.windowHandle, byref(tempPoint)) caretRect.left=max(objRect.left,tempPoint.x) caretRect.top=max(objRect.top,tempPoint.y) tempPoint.x=caretRect.right tempPoint.y=caretRect.bottom winUser.user32.ClientToScreen(self.obj.windowHandle, byref(tempPoint)) caretRect.right=min(objRect.right,tempPoint.x) caretRect.bottom=min(objRect.bottom,tempPoint.y) import speech for charOffset, (charLeft, charTop, charRight, charBottom) in enumerate(self._textAndRects[1]): #speech.speakMessage("caret %d,%d char %d,%d"%(caretRect.top,caretRect.bottom,charTop,charBottom)) if caretRect.left>=charLeft and caretRect.right<=charRight and ((caretRect.top<=charTop and caretRect.bottom>=charBottom) or (caretRect.top>=charTop and caretRect.bottom<=charBottom)): return charOffset raise RuntimeError
def findOverlayClasses(self,clsList): windowClassName=self.normalizeWindowClassName(self.windowClassName) newCls=None if windowClassName=="#32769": newCls=Desktop elif windowClassName=="Edit": from .edit import Edit as newCls elif windowClassName=="RichEdit": from .edit import RichEdit as newCls elif windowClassName in ("RichEdit20","REComboBox20W"): from .edit import RichEdit20 as newCls elif windowClassName=="RICHEDIT50W": from .edit import RichEdit50 as newCls elif windowClassName in ("Scintilla","TScintilla"): from .scintilla import Scintilla as newCls elif windowClassName in ("AkelEditW", "AkelEditA"): from .akelEdit import AkelEdit as newCls elif windowClassName=="ConsoleWindowClass": from .winConsole import WinConsole as newCls elif windowClassName=="EXCEL7": from .excel import Excel7Window as newCls if newCls: clsList.append(newCls) # If none of the chosen classes seem to support text editing # but there is a caret currently in the window, # check whether this window exposes its content without using the display model. # If not, use the displayModelEditableText class to emulate text editing capabilities if not any(issubclass(cls,EditableText) for cls in clsList): gi=winUser.getGUIThreadInfo(self.windowThreadID) if gi.hwndCaret==self.windowHandle and gi.flags&winUser.GUI_CARETBLINKING: if self.windowTextLineCount: from .edit import UnidentifiedEdit clsList.append(UnidentifiedEdit) else: clsList.append(DisplayModelEditableText) clsList.append(Window) super(Window,self).findOverlayClasses(clsList)
def findOverlayClasses(self,clsList): windowClassName=self.normalizeWindowClassName(self.windowClassName) newCls=None if windowClassName=="#32769": newCls=Desktop elif windowClassName=="Edit": from .edit import Edit as newCls elif windowClassName=="RichEdit": from .edit import RichEdit as newCls elif windowClassName in ("RichEdit20","REComboBox20W"): from .edit import RichEdit20 as newCls elif windowClassName=="RICHEDIT50W": from .edit import RichEdit50 as newCls elif windowClassName in ("Scintilla","TScintilla"): from .scintilla import Scintilla as newCls elif windowClassName in ("AkelEditW", "AkelEditA"): from .akelEdit import AkelEdit as newCls elif windowClassName=="ConsoleWindowClass": from .winConsole import WinConsole as newCls elif windowClassName=="_WwG": from .winword import WordDocument as newCls elif windowClassName in ("_WwN","_WwO"): from .winword import WordDocument_WwN as newCls elif windowClassName=="EXCEL7": from .excel import Excel7Window as newCls if newCls: clsList.append(newCls) #If none of the chosen classes seem to support text editing #But there is a caret currently in the window #Then use the displayModelEditableText class to emulate text editing capabilities if not any(issubclass(cls,EditableText) for cls in clsList): gi=winUser.getGUIThreadInfo(self.windowThreadID) if gi.hwndCaret==self.windowHandle and gi.flags&winUser.GUI_CARETBLINKING: clsList.append(DisplayModelEditableText) clsList.append(Window) super(Window,self).findOverlayClasses(clsList)
def shouldAcceptEvent(eventName, windowHandle=None): """Check whether an event should be accepted from a platform API. Creating NVDAObjects and executing events can be expensive and might block the main thread noticeably if the object is slow to respond. Therefore, this should be used before NVDAObject creation to filter out any unnecessary events. A platform API handler may do its own filtering before this. """ if not windowHandle: # We can't filter without a window handle. return True wClass = winUser.getClassName(windowHandle) key = (eventName, winUser.getWindowThreadProcessID(windowHandle)[0], wClass) if key in _acceptEvents: return True if eventName == "valueChange" and config.conf["presentation"][ "progressBarUpdates"]["reportBackgroundProgressBars"]: return True if eventName == "hide": return False if eventName == "show": # Only accept 'show' events for specific cases, as otherwise we get flooded. return wClass in ( "Frame Notification Bar", # notification bars "tooltips_class32", # tooltips "mscandui21.candidate", "mscandui40.candidate", "MSCandUIWindow_Candidate", # IMM candidates "TTrayAlert", # 5405: Skype ) if eventName == "alert" and winUser.getClassName( winUser.getAncestor(windowHandle, winUser.GA_PARENT)) == "ToastChildWindowClass": # Toast notifications. return True if eventName in ("menuEnd", "switchEnd", "desktopSwitch"): # #5302, #5462: These events can be fired on the desktop window # or windows that would otherwise be blocked. # Platform API handlers will translate these events to focus events anyway, # so we must allow them here. return True if windowHandle == winUser.getDesktopWindow(): # #5595: Events for the cursor get mapped to the desktop window. return True # #6713: Edge (and soon all UWP apps) will no longer have windows as descendants of the foreground window. # However, it does look like they are always equal to or descendants of the "active" window of the input thread. gi = winUser.getGUIThreadInfo(0) if wClass.startswith('Windows.UI.Core'): if winUser.isDescendantWindow(gi.hwndActive, windowHandle): return True fg = winUser.getForegroundWindow() fgClassName = winUser.getClassName(fg) if wClass == "NetUIHWND" and fgClassName in ("Net UI Tool Window Layered", "Net UI Tool Window"): # #5504: In Office >= 2013 with the ribbon showing only tabs, # when a tab is expanded, the window we get from the focus object is incorrect. # This window isn't beneath the foreground window, # so our foreground application checks fail. # Just compare the root owners. if winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER) == winUser.getAncestor( fg, winUser.GA_ROOTOWNER): return True if (winUser.isDescendantWindow(fg, windowHandle) # #3899, #3905: Covers cases such as the Firefox Page Bookmarked window and OpenOffice/LibreOffice context menus. or winUser.isDescendantWindow( fg, winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER))): # This is for the foreground application. return True if (winUser.user32.GetWindowLongW(windowHandle, winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST or winUser.user32.GetWindowLongW( winUser.getAncestor(windowHandle, winUser.GA_ROOT), winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST): # This window or its root is a topmost window. # This includes menus, combo box pop-ups and the task switching list. return True # This may be an event for a windowless embedded Chrome document # (E.g. Microsoft Loop component). if wClass == "Chrome_RenderWidgetHostHWND": # The event is for a Chromium document if winUser.getClassName(gi.hwndFocus) == "Chrome_WidgetWin_0": # The real win32 focus is on a Chrome embedding window. # See if we can get from the event's Chromium document to the Chrome embedding window # via ancestors in the UIA tree. rootWindowHandle = winUser.getAncestor(windowHandle, winUser.GA_ROOT) import UIAHandler try: rootElement = UIAHandler.handler.clientObject.elementFromHandle( rootWindowHandle) except COMError: log.debugWarning( "Could not create UIA element for root of Chromium document", exc_info=True) else: condition = UIAHandler.handler.clientObject.CreatePropertyCondition( UIAHandler.UIA_NativeWindowHandlePropertyId, gi.hwndFocus) try: walker = UIAHandler.handler.clientObject.CreateTreeWalker( condition) ancestorElement = walker.NormalizeElement(rootElement) except COMError: log.debugWarning( "Unable to normalize root Chromium element to focused ancestor", exc_info=True) ancestorElement = None if ancestorElement: # The real focused window is an ancestor of the Chromium document in the UIA tree. return True return False
def _get_shouldAllowIAccessibleFocusEvent(self): # The window must really have focus. # Outlook can sometimes fire invalid focus events when showing daily tasks within the calendar. if winUser.getGUIThreadInfo(self.windowThreadID).hwndFocus!=self.windowHandle: return False return super(SuperGridClient2010,self).shouldAllowIAccessibleFocusEvent
def SlideShowNextSlide(self,slideShowWindow=None): i=winUser.getGUIThreadInfo(0) oldFocus=api.getFocusObject() if not isinstance(oldFocus,SlideShowWindow) or i.hwndFocus!=oldFocus.windowHandle: return oldFocus.treeInterceptor.rootNVDAObject.handleSlideChange()
def _get_shouldAllowIAccessibleFocusEvent(self): # #4199: Some SDM controls can incorrectly firefocus when they are not focused # E.g. File recovery pane, clipboard manager pane if winUser.getGUIThreadInfo(0).hwndFocus != self.windowHandle: return False return super(SDM, self).shouldAllowIAccessibleFocusEvent
def shouldAcceptEvent(eventName, windowHandle=None): """Check whether an event should be accepted from a platform API. Creating NVDAObjects and executing events can be expensive and might block the main thread noticeably if the object is slow to respond. Therefore, this should be used before NVDAObject creation to filter out any unnecessary events. A platform API handler may do its own filtering before this. """ if not windowHandle: # We can't filter without a window handle. return True wClass = winUser.getClassName(windowHandle) key = (eventName, winUser.getWindowThreadProcessID(windowHandle)[0], wClass) if key in _acceptEvents: return True if eventName == "valueChange" and config.conf["presentation"][ "progressBarUpdates"]["reportBackgroundProgressBars"]: return True if eventName == "show": # Only accept 'show' events for specific cases, as otherwise we get flooded. return wClass in ( "Frame Notification Bar", # notification bars "tooltips_class32", # tooltips "mscandui21.candidate", "mscandui40.candidate", "MSCandUIWindow_Candidate", # IMM candidates "TTrayAlert", # 5405: Skype ) if eventName == "reorder": # Prevent another flood risk. return wClass == "TTrayAlert" # #4841: Skype if eventName == "alert" and winUser.getClassName( winUser.getAncestor(windowHandle, winUser.GA_PARENT)) == "ToastChildWindowClass": # Toast notifications. return True if eventName in ("menuEnd", "switchEnd", "desktopSwitch"): # #5302, #5462: These events can be fired on the desktop window # or windows that would otherwise be blocked. # Platform API handlers will translate these events to focus events anyway, # so we must allow them here. return True if windowHandle == winUser.getDesktopWindow(): # #5595: Events for the cursor get mapped to the desktop window. return True # #6713: Edge (and soon all UWP apps) will no longer have windows as descendants of the foreground window. # However, it does look like they are always equal to or descendants of the "active" window of the input thread. if wClass.startswith('Windows.UI.Core'): gi = winUser.getGUIThreadInfo(0) if winUser.isDescendantWindow(gi.hwndActive, windowHandle): return True fg = winUser.getForegroundWindow() if wClass == "NetUIHWND" and winUser.getClassName( fg) == "Net UI Tool Window Layered": # #5504: In Office >= 2013 with the ribbon showing only tabs, # when a tab is expanded, the window we get from the focus object is incorrect. # This window isn't beneath the foreground window, # so our foreground application checks fail. # Just compare the root owners. if winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER) == winUser.getAncestor( fg, winUser.GA_ROOTOWNER): return True if (winUser.isDescendantWindow(fg, windowHandle) # #3899, #3905: Covers cases such as the Firefox Page Bookmarked window and OpenOffice/LibreOffice context menus. or winUser.isDescendantWindow( fg, winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER))): # This is for the foreground application. return True if (winUser.user32.GetWindowLongW(windowHandle, winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST or winUser.user32.GetWindowLongW( winUser.getAncestor(windowHandle, winUser.GA_ROOT), winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST): # This window or its root is a topmost window. # This includes menus, combo box pop-ups and the task switching list. return True return False
def shouldAcceptEvent(eventName, windowHandle=None): """Check whether an event should be accepted from a platform API. Creating NVDAObjects and executing events can be expensive and might block the main thread noticeably if the object is slow to respond. Therefore, this should be used before NVDAObject creation to filter out any unnecessary events. A platform API handler may do its own filtering before this. """ if not windowHandle: # We can't filter without a window handle. return True wClass = winUser.getClassName(windowHandle) key = (eventName, winUser.getWindowThreadProcessID(windowHandle)[0], wClass) if key in _acceptEvents: return True if eventName == "valueChange" and config.conf["presentation"]["progressBarUpdates"]["reportBackgroundProgressBars"]: return True if eventName == "show": # Only accept 'show' events for specific cases, as otherwise we get flooded. return wClass in ( "Frame Notification Bar", # notification bars "tooltips_class32", # tooltips "mscandui21.candidate", "mscandui40.candidate", "MSCandUIWindow_Candidate", # IMM candidates "TTrayAlert", # 5405: Skype ) if eventName == "reorder": # Prevent another flood risk. return wClass == "TTrayAlert" # #4841: Skype if eventName == "alert" and winUser.getClassName(winUser.getAncestor(windowHandle, winUser.GA_PARENT)) == "ToastChildWindowClass": # Toast notifications. return True if eventName in ("menuEnd", "switchEnd", "desktopSwitch"): # #5302, #5462: These events can be fired on the desktop window # or windows that would otherwise be blocked. # Platform API handlers will translate these events to focus events anyway, # so we must allow them here. return True if windowHandle == winUser.getDesktopWindow(): # #5595: Events for the cursor get mapped to the desktop window. return True # #6713: Edge (and soon all UWP apps) will no longer have windows as descendants of the foreground window. # However, it does look like they are always equal to or descendants of the "active" window of the input thread. if wClass.startswith('Windows.UI.Core'): gi=winUser.getGUIThreadInfo(0) if winUser.isDescendantWindow(gi.hwndActive,windowHandle): return True fg = winUser.getForegroundWindow() if wClass == "NetUIHWND" and winUser.getClassName(fg) == "Net UI Tool Window Layered": # #5504: In Office >= 2013 with the ribbon showing only tabs, # when a tab is expanded, the window we get from the focus object is incorrect. # This window isn't beneath the foreground window, # so our foreground application checks fail. # Just compare the root owners. if winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER) == winUser.getAncestor(fg, winUser.GA_ROOTOWNER): return True if (winUser.isDescendantWindow(fg, windowHandle) # #3899, #3905: Covers cases such as the Firefox Page Bookmarked window and OpenOffice/LibreOffice context menus. or winUser.isDescendantWindow(fg, winUser.getAncestor(windowHandle, winUser.GA_ROOTOWNER))): # This is for the foreground application. return True if (winUser.user32.GetWindowLongW(windowHandle, winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST or winUser.user32.GetWindowLongW(winUser.getAncestor(windowHandle, winUser.GA_ROOT), winUser.GWL_EXSTYLE) & winUser.WS_EX_TOPMOST): # This window or its root is a topmost window. # This includes menus, combo box pop-ups and the task switching list. return True return False