def construct(self):
        """
        Singleton constructor, runs only once.
        """
        EventSource.__init__(self, self._event_names)

        self._frozen = False
Example #2
0
 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)
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
 def construct(self):
     """
     Singleton constructor, runs only once.
     """
     EventSource.__init__(self, self._event_names)
     self._udev = None
     self._keyboard_device_detected = None
Example #8
0
    def construct(self):
        """
        Singleton constructor, runs only once.
        """
        EventSource.__init__(self, self._event_names)

        self._state = {}
        self._frozen = False
Example #9
0
    def construct(self):
        """
        Singleton constructor, runs only once.
        """
        EventSource.__init__(self, self._event_names)

        self._device_manager = None
        self._keyboard_slave_devices = None
Example #10
0
    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
Example #11
0
 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
Example #12
0
    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")
Example #13
0
    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")
Example #14
0
    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)
Example #17
0
    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)
Example #18
0
 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)
Example #19
0
    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()
Example #20
0
    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()
Example #23
0
    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()
Example #24
0
    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)
Example #25
0
 def connect(self, event_name, callback):
     EventSource.connect(self, event_name, callback)
     self._update_listeners()
Example #26
0
 def cleanup(self):
     EventSource.cleanup(self)
     self._register_atspi_listeners(False)
Example #27
0
 def connect(self, event_name, callback):
     EventSource.connect(self, event_name, callback)
     self._update_registered_events()
Example #28
0
    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)
Example #29
0
 def connect(self, event_name, callback):
     EventSource.connect(self, event_name, callback)
     self._update_listeners()
Example #30
0
 def emit_async(self, event_name, *args, **kwargs):
     if not self._frozen:
         EventSource.emit_async(self, event_name, *args, **kwargs)
Example #31
0
 def connect(self, event_name, callback):
     EventSource.connect(self, event_name, callback)
     self.update_sensor_sources()
Example #32
0
 def emit_async(self, event_name, *args, **kwargs):
     if not self._frozen:
         EventSource.emit_async(self, event_name, *args, **kwargs)
Example #33
0
 def cleanup(self):
     EventSource.cleanup(self)
     self._register_atspi_listeners(False)