def construct(self): """ Singleton constructor, runs only once. """ EventSource.__init__(self, self._event_names) self._frozen = False
def cleanup(self): """ Should not need to be called as long connect and disconnect calls are balanced. """ EventSource.cleanup(self) self._register_input_events_xinput(False)
def _register_atspi_focus_listeners(self, register): if "Atspi" not in globals(): return if self._focus_listeners_registered != register: if register: self.atspi_connect("_listener_focus", "focus", self._on_atspi_global_focus) self.atspi_connect("_listener_object_focus", "object:state-changed:focused", self._on_atspi_object_focus) # private asynchronous events for name in self._async_event_names: handler = "_on_" + name.replace("-", "_") EventSource.connect(self, name, getattr(self, handler)) else: self.atspi_disconnect("_listener_focus", "focus") self.atspi_disconnect("_listener_object_focus", "object:state-changed:focused") for name in self._async_event_names: handler = "_on_" + name.replace("-", "_") EventSource.disconnect(self, name, getattr(self, handler)) self._focus_listeners_registered = register
def __init__(self): # There is only button-release to subscribe to currently, # as this is all CSButtonRemapper needs to detect the end of a click. EventSource.__init__(self, ["button-release"]) XIDeviceEventLogger.__init__(self) self._gtk_handler_ids = None self._device_manager = None self._master_device = None # receives enter/leave events self._master_device_id = None # for convenience/performance self._slave_devices = None # receive pointer and touch events self._slave_device_ids = None # for convenience/performance self._xi_grab_active = False self._xi_grab_events_selected = False self._xi_event_handled = False self._touch_active = set() # set of id(XIDevice/GdkX11DeviceXI2) # For devices not contained here only # pointer events are considered. # Wacom devices with enabled gestures never # become touch-active, i.e. they don't # generate touch events. self.connect("realize", self._on_realize_event) self.connect("unrealize", self._on_unrealize_event)
def construct(self): """ Singleton constructor, runs only once. """ EventSource.__init__(self, self._event_names) self._udev = None self._keyboard_device_detected = None
def construct(self): """ Singleton constructor, runs only once. """ EventSource.__init__(self, self._event_names) self._state = {} self._frozen = False
def construct(self): """ Singleton constructor, runs only once. """ EventSource.__init__(self, self._event_names) self._device_manager = None self._keyboard_slave_devices = None
def __init__(self, keyboard): # There is only button-release to subscribe to currently, # as this is all CSButtonRemapper needs to detect the end of a click. EventSource.__init__(self, ["button-release"]) self._keyboard = keyboard self._device_manager = None self._keyboard_slave_devices = None
def construct(self): """ Singleton constructor, runs only once. """ EventSource.__init__(self, self._event_names) self._acpid_listener = None self._tablet_mode = None self._key_listener = None
def disconnect(self, event_name, callback): had_listeners = self.has_listeners(self._event_names) EventSource.disconnect(self, event_name, callback) self._update_listeners() # help debugging disconnecting events on exit if had_listeners and not self.has_listeners(self._event_names): _logger.info("all listeners disconnected")
def construct(self): """ Singleton constructor, runs only once. """ EventSource.__init__(self, ["device-event"]) self._devices = {} self._osk_devices = osk.Devices(event_handler=self._device_event_handler) self.update_devices()
def _begin_mapping(self, event_source, button, click_type): # remap button if button != self.PRIMARY_BUTTON and \ click_type == self.CLICK_TYPE_SINGLE: # "grab" the pointer so we can detect button-release # anywhere on screen. Works only with XInput as InputEventSource. self._grab_event_source = event_source event_source.grab_xi_pointer(True) EventSource.connect(event_source, "button-release", self._on_xi_button_release) self._osk_cm.map_pointer_button(button) self._osk_cm.button = button self._osk_cm.click_type = click_type else: self._set_next_mouse_click(button, click_type)
def end_mapping(self): if self._grab_event_source: EventSource.disconnect(self._grab_event_source, "button-release", self._on_xi_button_release) self._grab_event_source.grab_xi_pointer(False) self._grab_event_source = None if self._osk_cm: if self._osk_cm.click_type == self.CLICK_TYPE_SINGLE: self._osk_cm.restore_pointer_buttons() self._osk_cm.button = self.PRIMARY_BUTTON self._osk_cm.click_type = self.CLICK_TYPE_SINGLE else: self._set_next_mouse_click(self.PRIMARY_BUTTON, self.CLICK_TYPE_SINGLE)
def construct(self): """ Singleton constructor, runs only once. """ EventSource.__init__(self, ["device-event"]) self._devices = {} self._osk_devices = None try: self._osk_devices = osk.Devices(event_handler = \ self._device_event_handler) except Exception as ex: _logger.warning("Failed to create osk.Devices: " + \ unicode_str(ex)) if self.is_valid(): self.update_devices()
def __init__(self): # There is only button-release to subscribe to currently, # as this is all CSButtonRemapper needs to detect the end of a click. EventSource.__init__(self, ["button-release"]) self._gtk_handler_ids = None self._device_manager = None self._master_device = None # receives enter/leave events self._master_device_id = None # for convenience/performance self._slave_devices = None # receive pointer and touch events self._slave_device_ids = None # for convenience/performance self._xi_grab_active = False self._xi_grab_events_selected = False self._xi_event_handled = False self.connect("realize", self._on_realize_event) self.connect("unrealize", self._on_unrealize_event)
def construct(self): """ Singleton constructor, runs only once. """ EventSource.__init__(self, ["device-event", "device-grab"]) self._devices = {} self._osk_devices = None try: self._osk_devices = osk.Devices(event_handler = \ self._on_device_event) except Exception as ex: _logger.warning("Failed to create osk.Devices: " + \ unicode_str(ex)) self._last_motion_device_id = None self._last_click_device_id = None self._last_device_blacklist_ids = [] self._grabbed_devices_ids = set() if self.is_valid(): self.update_devices()
def construct(self): """ Singleton constructor, runs only once. """ EventSource.__init__(self, ["device-event", "device-grab", "devices-updated"]) self._devices = {} self._osk_devices = None try: self._osk_devices = osk.Devices(event_handler = \ self._on_device_event) except Exception as ex: _logger.warning("Failed to create osk.Devices: " + \ unicode_str(ex)) self._last_motion_device_id = None self._last_click_device_id = None self._last_device_blacklist_ids = [] self._grabbed_devices_ids = set() if self.is_valid(): self.update_devices()
def _on_device_event(self, event): """ Handler for XI2 events. """ event_type = event.xi_type device_id = event.device_id log = self._log_event_stub if _logger.isEnabledFor(logging.DEBUG) and \ event_type != XIEventType.Motion and \ event_type != XIEventType.TouchUpdate: self._log_device_event(event) log = self.log_event # re-select devices on changes to the device hierarchy if event_type in XIEventType.HierarchyEvents or \ event_type == XIEventType.DeviceChanged: self.select_xinput_devices() return log("_on_device_event1") if event_type == XIEventType.KeyPress or \ event_type == XIEventType.KeyRelease: return # check device_id, discard duplicate and unknown events if event_type == XIEventType.Enter or \ event_type == XIEventType.Leave: log("_on_device_event2 {} {}", device_id, self._master_device_id) # enter/leave are only expected from the master device if not device_id == self._master_device_id: log("_on_device_event3") return else: # all other pointer/touch events have to come from slaves log("_on_device_event4 {} {}", event.device_id, self._slave_device_ids) if not event.device_id in self._slave_device_ids: log("_on_device_event5") return # bail if the window isn't realized yet win = self.get_window() if not win: log("_on_device_event6") return # scale coordinates in response to changes to # org.gnome.desktop.interface scaling-factor try: scale = win.get_scale_factor() # from Gdk 3.10 log("_on_device_event7 {}", scale) if scale and scale != 1.0: scale = 1.0 / scale event.x = event.x * scale event.y = event.y * scale event.x_root = event.x_root * scale event.y_root = event.y_root * scale except AttributeError: pass # Slaves aren't grabbed for moving/resizing when simulating a drag # operation (drag click button), or when multiple slave devices are # involved (one for button press, another for motion). # -> Simulate pointer grab, select root events we can track even # outside the keyboard window. # None of these problems are assumed to exist for touch devices. log("_on_device_event8 {}", self._xi_grab_active) if self._xi_grab_active and \ (event_type == XIEventType.Motion or event_type == XIEventType.ButtonRelease): if not self._xi_grab_events_selected: self._select_xi_grab_events(True) log("_on_device_event9") # We only get root window coordinates for root window events, # so convert them to our target window's coordinates. rx, ry = win.get_root_coords(0, 0) event.x = event.x_root - rx event.y = event.y_root - ry else: # Is self the hit window? # We need this only for the multi-touch case with open # long press popup, e.g. while shift is held down with # one finger, touching anything in a long press popup must # not also affect the keyboard below. xid_event = event.xid_event xid_win = self.get_xid() log("_on_device_event10 {} {}", xid_event, xid_win) if xid_event != 0 and \ xid_event != xid_win: log("_on_device_event11") return # Dispatch events self._xi_event_handled = False if event_type == XIEventType.Motion: self._on_motion_event(self, event) elif event_type == XIEventType.TouchUpdate or \ event_type == XIEventType.TouchBegin or \ event_type == XIEventType.TouchEnd: self._on_touch_event(self, event) elif event_type == XIEventType.ButtonPress: self._on_button_press_event(self, event) elif event_type == XIEventType.ButtonRelease: self._on_button_release_event(self, event) # Notify CSButtonMapper, end remapped click. if not self._xi_event_handled: EventSource.emit(self, "button-release", event) elif event_type == XIEventType.Enter: self._on_enter_notify(self, event) elif event_type == XIEventType.Leave: self._on_leave_notify(self, event)
def connect(self, event_name, callback): EventSource.connect(self, event_name, callback) self._update_listeners()
def cleanup(self): EventSource.cleanup(self) self._register_atspi_listeners(False)
def connect(self, event_name, callback): EventSource.connect(self, event_name, callback) self._update_registered_events()
def _on_device_event(self, event): """ Handler for XI2 events. """ event_type = event.xi_type device_id = event.device_id log = self._log_event_stub if _logger.isEnabledFor(logging.DEBUG) and \ event_type != XIEventType.Motion and \ event_type != XIEventType.TouchUpdate: self._log_device_event(event) log = self.log_event # re-select devices on changes to the device hierarchy if event_type in XIEventType.HierarchyEvents or \ event_type == XIEventType.DeviceChanged: self.select_xinput_devices() return log("_on_device_event1") if event_type == XIEventType.KeyPress or \ event_type == XIEventType.KeyRelease: return # check device_id, discard duplicate and unknown events if event_type == XIEventType.Enter or \ event_type == XIEventType.Leave: log("_on_device_event2 {} {}", device_id, self._master_device_id) # enter/leave are only expected from the master device if not device_id == self._master_device_id: log("_on_device_event3") return else: # all other pointer/touch events have to come from slaves log("_on_device_event4 {} {}", event.device_id, self._slave_device_ids) if not event.device_id in self._slave_device_ids: log("_on_device_event5") return # bail if the window isn't realized yet win = self.get_window() if not win: log("_on_device_event6") return # scale coordinates in response to changes to # org.gnome.desktop.interface scaling-factor try: scale = win.get_scale_factor() # from Gdk 3.10 log("_on_device_event7 {}", scale) if scale and scale != 1.0: scale = 1.0 / scale event.x = event.x * scale event.y = event.y * scale event.x_root = event.x_root * scale event.y_root = event.y_root * scale except AttributeError: pass # Slaves aren't grabbed for moving/resizing when simulating a drag # operation (drag click button), or when multiple slave devices are # involved (one for button press, another for motion). # -> Simulate pointer grab, select root events we can track even # outside the keyboard window. # None of these problems are assumed to exist for touch devices. log("_on_device_event8 {}", self._xi_grab_active) if self._xi_grab_active and \ (event_type == XIEventType.Motion or \ event_type == XIEventType.ButtonRelease): if not self._xi_grab_events_selected: self._select_xi_grab_events(True) log("_on_device_event9") # We only get root window coordinates for root window events, # so convert them to our target window's coordinates. rx, ry = win.get_root_coords(0, 0) event.x = event.x_root - rx event.y = event.y_root - ry else: # Is self the hit window? # We need this only for the multi-touch case with open # long press popup, e.g. while shift is held down with # one finger, touching anything in a long press popup must # not also affect the keyboard below. xid_event = event.xid_event xid_win = win.get_xid() log("_on_device_event10 {} {}", xid_event, xid_win) if xid_event != 0 and \ xid_event != xid_win: log("_on_device_event11") return # Dispatch events self._xi_event_handled = False if event_type == XIEventType.Motion: self._on_motion_event(self, event) elif event_type == XIEventType.TouchUpdate or \ event_type == XIEventType.TouchBegin or \ event_type == XIEventType.TouchEnd: self._on_touch_event(self, event) elif event_type == XIEventType.ButtonPress: self._on_button_press_event(self, event) elif event_type == XIEventType.ButtonRelease: self._on_button_release_event(self, event) # Notify CSButtonMapper, end remapped click. if not self._xi_event_handled: EventSource.emit(self, "button-release", event) elif event_type == XIEventType.Enter: self._on_enter_notify(self, event) elif event_type == XIEventType.Leave: self._on_leave_notify(self, event)
def emit_async(self, event_name, *args, **kwargs): if not self._frozen: EventSource.emit_async(self, event_name, *args, **kwargs)
def connect(self, event_name, callback): EventSource.connect(self, event_name, callback) self.update_sensor_sources()