def injectRawKeyboardInput(isPress, code, isExtended): """Inject raw input from a system keyboard that is not handled natively by Windows. For example, this might be used for input from a QWERTY keyboard on a braille display. NVDA will treat the key as if it had been pressed on a normal system keyboard. If it is not handled by NVDA, it will be sent to the operating system. @param isPress: Whether the key is being pressed. @type isPress: bool @param code: The scan code (PC set 1) of the key. @type code: int @param isExtended: Whether this is an extended key. @type isExtended: bool """ mapScan = code if isExtended: # Change what we pass to MapVirtualKeyEx, but don't change what NVDA gets. mapScan |= 0xE000 vkCode = winUser.user32.MapVirtualKeyExW(mapScan, winUser.MAPVK_VSC_TO_VK_EX, getInputHkl()) if isPress: shouldSend = internal_keyDownEvent(vkCode, code, isExtended, False) else: shouldSend = internal_keyUpEvent(vkCode, code, isExtended, False) if shouldSend: flags = 0 if not isPress: flags |= 2 if isExtended: flags |= 1 global ignoreInjected ignoreInjected = True try: winUser.keybd_event(vkCode, code, flags, None) wx.Yield() finally: ignoreInjected = False
def injectRawKeyboardInput(isPress, code, isExtended): """Inject raw input from a system keyboard that is not handled natively by Windows. For example, this might be used for input from a QWERTY keyboard on a braille display. NVDA will treat the key as if it had been pressed on a normal system keyboard. If it is not handled by NVDA, it will be sent to the operating system. @param isPress: Whether the key is being pressed. @type isPress: bool @param code: The scan code (PC set 1) of the key. @type code: int @param isExtended: Whether this is an extended key. @type isExtended: bool """ mapScan = code if isExtended: # Change what we pass to MapVirtualKeyEx, but don't change what NVDA gets. mapScan |= 0xE000 vkCode = winUser.user32.MapVirtualKeyExW(mapScan, winUser.MAPVK_VSC_TO_VK_EX, getInputHkl()) flags = 0 if not isPress: flags |= 2 if isExtended: flags |= 1 winUser.keybd_event(vkCode, code, flags, None)
def executeScript(self, script): super().executeScript(script) if self.sendCount == 0 and canModifiersPerformAction( self.generalizedModifiers): # #3472: These modifiers can perform an action if pressed alone # and we've just totally consumed the main key. # Send special reserved vkcode VK_NONE (0xff) # to at least notify the app's key state that something happened. # This allows alt and windows to be bound to scripts and # stops control+shift from switching keyboard layouts in cursorManager selection scripts. with ignoreInjection(): winUser.keybd_event(winUser.VK_NONE, 0, 0, 0) winUser.keybd_event(winUser.VK_NONE, 0, winUser.KEYEVENTF_KEYUP, 0)
def executeScript(self, script): if canModifiersPerformAction(self.generalizedModifiers): # #3472: These modifiers can perform an action if pressed alone # and we've just totally consumed the main key. # Send special reserved vkcode VK_NONE (0xff) # to at least notify the app's key state that something happened. # This allows alt and windows to be bound to scripts and # stops control+shift from switching keyboard layouts in cursorManager selection scripts. # This must be done before executing the script, # As if the script takes a long time and the user releases these modifier keys before the script finishes, # it is already too late. with ignoreInjection(): winUser.keybd_event(winUser.VK_NONE, 0, 0, 0) winUser.keybd_event(winUser.VK_NONE, 0, winUser.KEYEVENTF_KEYUP, 0) # Now actually execute the script. super().executeScript(script)
def send(self): keys = [] for vk, ext in self.generalizedModifiers: if vk == VK_WIN: if winUser.getKeyState(winUser.VK_LWIN) & 32768 or winUser.getKeyState(winUser.VK_RWIN) & 32768: # Already down. continue vk = winUser.VK_LWIN elif winUser.getKeyState(vk) & 32768: # Already down. continue keys.append((vk, ext)) keys.append((self.vkCode, self.isExtended)) if winUser.getKeyState(self.vkCode) & 32768: # This key is already down, so send a key up for it first. winUser.keybd_event(self.vkCode, 0, self.isExtended + 2, 0) # Send key down events for these keys. for vk, ext in keys: winUser.keybd_event(vk, 0, ext, 0) # Send key up events for the keys in reverse order. for vk, ext in reversed(keys): winUser.keybd_event(vk, 0, ext + 2, 0) if not queueHandler.isPendingItems(queueHandler.eventQueue): time.sleep(0.01) wx.Yield()
def send(self): keys = [] for vk, ext in self.generalizedModifiers: if vk == VK_WIN: if winUser.getKeyState( winUser.VK_LWIN) & 32768 or winUser.getKeyState( winUser.VK_RWIN) & 32768: # Already down. continue vk = winUser.VK_LWIN elif winUser.getKeyState(vk) & 32768: # Already down. continue keys.append((vk, 0, ext)) keys.append((self.vkCode, self.scanCode, self.isExtended)) with ignoreInjection(): if winUser.getKeyState(self.vkCode) & 32768: # This key is already down, so send a key up for it first. winUser.keybd_event(self.vkCode, self.scanCode, self.isExtended + 2, 0) # Send key down events for these keys. for vk, scan, ext in keys: winUser.keybd_event(vk, scan, ext, 0) # Send key up events for the keys in reverse order. for vk, scan, ext in reversed(keys): winUser.keybd_event(vk, scan, ext + 2, 0) if not queueHandler.isPendingItems(queueHandler.eventQueue): # We want to guarantee that by the time that # this function returns,the keyboard input generated # has been injected and NVDA has received and processed it. time.sleep(0.01) wx.Yield()
def send(self): global ignoreInjected keys = [] for vk, ext in self.generalizedModifiers: if vk == VK_WIN: if winUser.getKeyState(winUser.VK_LWIN) & 32768 or winUser.getKeyState(winUser.VK_RWIN) & 32768: # Already down. continue vk = winUser.VK_LWIN elif winUser.getKeyState(vk) & 32768: # Already down. continue keys.append((vk, 0, ext)) keys.append((self.vkCode, self.scanCode, self.isExtended)) try: ignoreInjected=True if winUser.getKeyState(self.vkCode) & 32768: # This key is already down, so send a key up for it first. winUser.keybd_event(self.vkCode, self.scanCode, self.isExtended + 2, 0) # Send key down events for these keys. for vk, scan, ext in keys: winUser.keybd_event(vk, scan, ext, 0) # Send key up events for the keys in reverse order. for vk, scan, ext in reversed(keys): winUser.keybd_event(vk, scan, ext + 2, 0) if not queueHandler.isPendingItems(queueHandler.eventQueue): time.sleep(0.01) wx.Yield() finally: ignoreInjected=False