def update_timestamps(pos: int, e: InputEvent) -> None: """ Update timestamps of last key press. """ global last_press_timestamps new_value = e.timestamp() if e.value == KeyEvent.key_down else None last_press_timestamps[pos] = new_value debug(f'updated timestamp at [{pos}] to {new_value}')
def read(self): ''' Read multiple input events from device. Return a generator object that yields :class:`InputEvent <evdev.events.InputEvent>` instances. Raises `BlockingIOError` if there are no available events at the moment. ''' # events -> [(sec, usec, type, code, val), ...] events = _input.device_read_many(self.fd) for i in events: yield InputEvent(*i)
def read(self): ''' Read multiple input events from device. Return a generator object that yields :class:`InputEvent <evdev.events.InputEvent>` instances. ''' # events -> [(sec, usec, type, code, val), ...] events = _input.device_read_many(self.fd) for i in events: yield InputEvent(*i)
async def listen(dev, ui, config): if int(dev.path[-1]) == main_dev_id: # Main device async for ev in dev.async_read_loop(): if e.KEY[ev.code][4:] in digits_str and ev.value == 1 and len(dev.active_keys()) == 1: # Change i3wm desktop, while still allowing for symbols with LEFTSHIFT ui.write_event(InputEvent(ev.sec, ev.usec, ev.type, e.KEY_LEFTALT, 1)) # ALT On ui.syn() ui.write_event(InputEvent(ev.sec, ev.usec, ev.type, ev.code, 1)) # Digit On ui.syn() ui.write_event(InputEvent(ev.sec, ev.usec, ev.type, ev.code, 0)) # Digit Off ui.syn() ui.write_event(InputEvent(ev.sec, ev.usec, ev.type, e.KEY_LEFTALT, 0)) # ALT Off ui.syn() else: ui.write_event(ev) # Passthrough else: # Secondary device async for ev in dev.async_read_loop(): if ev.code == e.KEY_ESC: # Safe exit with ESC for device in devices: device.ungrab() exit() elif ev.code == e.KEY_RESERVED: # Synchronization events ui.write_event(ev) elif e.KEY[ev.code][4:] in config.keys() and ev.value == 1: # Detect only keydown of keys in config file out_codes = [e.ecodes['KEY_' + code] for code in config[e.KEY[ev.code][4:]]] for code in out_codes: new_ev = InputEvent(ev.sec, ev.usec, ev.type, code, 1) ui.write_event(new_ev) ui.syn() for code in reversed(out_codes): new_ev = InputEvent(ev.sec, ev.usec, ev.type, code, 0) ui.write_event(new_ev) ui.syn()
def read_one(self): ''' Read and return a single input event as an instance of :class:`InputEvent <evdev.events.InputEvent>`. Return ``None`` if there are no pending input events. ''' # event -> (sec, usec, type, code, val) event = _input.device_read(self.fd) if event: return InputEvent(*event)
def handle(self, ui: UInput, e: InputEvent, config: Config, pos: int, *args) -> None: debug('-- handling mod tap action --') if e.value == KeyEvent.key_down: mapper.active_tap_actions[pos] = self debug('MT is pressed, pressing modifiers') host.write_press(ui, *self.modifiers) else: mapper.active_tap_actions.pop(pos) host.release_weak_keys(ui, config) debug('MT is released, releasing modifiers') host.write_release(ui, *self.modifiers) since_last_press = (e.timestamp() - mapper.last_press_timestamps[pos]) * 1000 debug(f'since last press: {since_last_press}') debug(f'action is used: {self.used}') if not self.used and since_last_press <= config.tapping_term: debug('writing key press') host.write_tap(ui, self.code) self.used = False
def handle(self, ui: UInput, e: InputEvent, config: Config, pos: int, *args) -> None: debug('-- handling layer tap action --') if e.value == KeyEvent.key_down: mapper.active_tap_actions[pos] = self debug(f'LT is pressed, enabling layer [{self.layer_index}]') mapper.enable_layer(self.layer_index, self, config) else: mapper.active_tap_actions.pop(pos) host.release_weak_keys(ui, config) debug(f'LT is released, disabling layer [{self.layer_index}]') mapper.disable_layer(ui, self.layer_index, config) since_last_press = (e.timestamp() - mapper.last_press_timestamps[pos]) * 1000 debug(f'since last press: {since_last_press}') debug(f'action is used: {self.used}') if not self.used and since_last_press <= config.tapping_term: debug('writing key press') host.write_tap(ui, self.code) self.used = False
virt = UInput.from_device(dev, name=dev.name + ' Virtual Stylus') def handleExit(s, f): dev.ungrab() sys.exit(0) # Take over complete control over the device - no events will be passed to # other listeners. They are relayed to the virtual stylus created above. signal(SIGINT, handleExit) dev.grab() for event in dev.read_loop(): # When putting the eraser down, IPTS first sends an event that puts # down the Pen, and after that puts down the eraser. As far as the # system is concerned, you put down BOTH, the eraser and the pen. # # To fix this, we wait for all eraser events, and inject an event that # lifts up the pen again, before relaying the event to put down the # eraser. if event.code == BTN_TOOL_RUBBER: e = InputEvent(event.sec, event.usec, EV_KEY, BTN_TOOL_PEN, 0) virt.write_event(e) virt.syn() virt.write_event(event) dev.ungrab()
def generate_key_event(code, is_press): return InputEvent(int(time.time()), (time.time() * 1000000) % 1000000, 1, code, KeyEvent.key_down if is_press else KeyEvent.key_up)