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 _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)