Пример #1
0
    def _keyevent(self, event):
        # Store key press time (approximate to the current time
        # as the X event.time isn't synced with that)
        self.last_key_time = time.time()

        wmanager.debug('keys', '%s %d %d, keyhandler %s',
                       event.__class__.__name__, event.detail, event.state,
                       self)

        # Add in our release "modifier"
        if event.type == X.KeyRelease:
            extrastate = ReleaseModifier
        else:
            extrastate = 0

        # First check for an exact modifier match
        match = hash_keycode(event.detail, event.state | extrastate)
        if self.bindings.has_key(match):
            self.bindings[match](event)

        # else, check for an AnyModifier key
        else:
            match = hash_keycode(event.detail, X.AnyModifier | extrastate)
            if self.bindings.has_key(match):
                self.bindings[match](event)
Пример #2
0
 def _accept(self, ev):
     wmanager.debug('mozilla', 'Accepting popup')
     self.status_msg.pop()
     # Deiconify-by-moving-back...
     # self.client.moveresize(0, 20, self.client.width, self.client.height, 1)
     self.client.deiconify()
     self._cleanup()
Пример #3
0
    def inspect_disable(self, force=0):
        # Inspect already disabled
        if self.inspect_socket is None:
            return

        if self.inspect_clients:

            # Shut down all clients
            if force:
                for c in self.inspect_clients.values():
                    c.close()

            # Beep and abort
            else:
                self.display.bell(50)
                return

        wmanager.debug('inspect', 'disabling inspect server')

        for s in self.screens:
            try:
                s.modewindow_remove_message(self.inspect_message)
            except AttributeError:
                pass

        self.inspect_message = None
        self.inspect_clients = None
        self.default_screen.root.delete_property(self.PLWM_INSPECT_SERVER)
        self.inspect_cookie = None
        self.inspect_socket_event.cancel()
        self.inspect_socket_event = None
        self.inspect_socket.close()
        self.inspect_socket = None
Пример #4
0
    def view_reorder_before_move(self, method):
        """Internal function.

        Moves this view to the front of the list, if reorder is
        enabled and the view has been visible for long enough.  Also
        move if the enter method differs from the previous move type.

        Call this in any view changing methods that steps or searches
        among views, to get the go-to-most-recently-visited
        functionality.
        """

        if not self.view_reorder_views:
            return

        wmanager.debug('view', 'reordering, method %s', method)
        old_method = self.view_enter_method
        self.view_enter_method = method

        if self.view_index == 0:
            return

        now = time.time()
        if (now - self.view_enter_time >= self.view_reorder_delay
                or old_method != method):

            wmanager.debug(
                'view', 'reordering, moving view %d from index %d to front',
                self.view_current.id, self.view_list.index(self.view_current))

            self.view_list.remove(self.view_current)
            self.view_list.insert(0, self.view_current)
            self.view_index = 0
Пример #5
0
    def comp_send_plcm_message(self, message, source, target):
        if self.comp_control_window is None:
            # Try to find the control window on demand, instead of
            # being fancy and waiting for events about it

            root = self.display.screen(0).root

            r = root.get_full_property(self._PLCM_CONTROL_WINDOW, Xatom.WINDOW)
            if r is None or r.format != 32 or len(r.value) != 1:
                wmanager.debug('composite',
                               'no plcm control window, not doing anything')
                return 0

            self.comp_control_window = self.display.create_resource_object(
                'window', r.value[0])

            wmanager.debug('composite', 'plcm control window: %s',
                           self.comp_control_window)

        # We knows the ID of the control window now

        ev = Xlib.protocol.event.ClientMessage(
            window=self.comp_control_window,
            client_type=message,
            data=(32, [source.id, target.id, 0, 0, 0]))

        self.comp_control_window.send_event(
            ev, onerror=self.comp_send_message_error)
        return 1
Пример #6
0
    def __init__(self, keyhandler, event):
        # Always initialize the keyhandler, otherwise
        # we'll get problems in the __del__ method.

        try:
            keys.KeyGrabKeyboard.__init__(self, keyhandler.wm, event.time)
        except keys.error, status:
            wmanager.debug('keys', 'Grabbing keyboard failed: %d', status)
Пример #7
0
    def inspect_create_new_client(self):
        conn, addr = self.inspect_socket.accept()

        wmanager.debug('inspect', 'connection from %s', addr)

        client = InspectClient(self, conn, addr)
        self.inspect_clients[client.event] = client
        self.inspect_set_message()
Пример #8
0
    def _timeout(self, ev):
        wmanager.debug('mozilla', 'Rejecting popup')
        self.status_msg.pop()

        # Delete the window, unless the user already has deiconified it
        if not self.client.is_mapped():
            self.client.delete(1)

        self._cleanup()
Пример #9
0
    def __client_del__(self):
        if self.outline_windows is None:
            return

        # Drop the resources held by the outline windows
        wmanager.debug('outline', 'freeing windows')
        for w in self.outline_windows:
            w.destroy()
        self.outline_name_gc.free()
        self.outline_name_window.destroy()
Пример #10
0
    def comp_send_message_error(self, error, request):
        wmanager.debug('composite', 'error when sending message to plcm: %s',
                       error)
        wmanager.debug('composite', 'disabling all enabled clients')

        for client in self.comp_clients.iterkeys():
            self.comp_remove_redirection(client)

        self.comp_clients = {}
        self.comp_control_window = None
Пример #11
0
    def comp_enable_client(self, client, settings=None):
        """Explicitly enable composition effects for CLIENT.

        Normally, this is done by calling
        e.g. comp_change_brightness().
        """

        # Is client already composition enabled?
        if client in self.comp_clients:
            return

        # Is composition disabled due to strange visuals?
        if client.window._composition_disabled:
            wmanager.debug('composite', 'composition disabled for client %s',
                           client)
            return

        # When render redirection is enabled for the client, it will
        # be unmapped and then remapped. Block those events so they
        # aren't misinterpreted as a withdrawal.

        # This is an disadvantage of splitting the main work of
        # composition into plcm: it would be much more natural for
        # plcm to handle everything there is about composition, but it
        # is nigh on impossible to reliably block plwm from receiving
        # these events then.

        client.window._proxy.change_attributes(event_mask=X.NoEventMask)
        client.event_mask.block(X.StructureNotifyMask)
        client.window._window.composite_redirect_window(RedirectManual)
        client.event_mask.unblock(X.StructureNotifyMask)
        client.window._proxy.change_attributes(
            event_mask=X.SubstructureRedirectMask)

        if self.comp_send_plcm_message(self._PLCM_ENABLE,
                                       client.window._window,
                                       client.window._proxy):

            wmanager.debug('composite', 'enabled composition for client %s',
                           client)

            if settings is None:
                settings = ClientSettings()

            self.comp_clients[client] = settings
        else:
            self.comp_remove_redirection(client)
Пример #12
0
    def _redraw(self):
        wmanager.debug('frame', 'redrawing')
        self._frame.clear_area()

        # Don't draw text in frame border
        g = self._frame.get_geometry()

        self._gc.set_clip_rectangles(
            0, 0,
            [(self._frame_width, self._frame_width,
              g.width - self._extra_width, g.height - self._extra_height)],
            X.YXBanded)

        self._frame.draw_text(self._gc, self._title_x, self._title_base,
                              self._client.get_title())

        self._gc.change(clip_mask=X.NONE)
Пример #13
0
    def comp_disable_client(self, client):
        """Explicitly disable composition effects for CLIENT.

        Normally, this is done by calling
        e.g. comp_set_brightness() with value 0.
        """

        # Is client composition enabled?
        if client not in self.comp_clients:
            return

        self.comp_send_plcm_message(self._PLCM_DISABLE, client.window._window,
                                    client.window._proxy)

        wmanager.debug('composite', 'disabled composition for client %s',
                       client)

        del self.comp_clients[client]
        self.comp_remove_redirection(client)
Пример #14
0
    def _internal_timeout(self, ev):
        """Called when the timer event times out.
        Don't override this, override _timeout instead.
        """

        # Call _timeout if it has been at least self.timeout
        # seconds since the last keypress
        if self.last_key_time is None \
           or ev.time - self.last_key_time >= self.timeout:
            wmanager.debug('keys', 'timeout, last_key = %s, now = %s',
                           self.last_key_time, ev.time)
            self._timeout(ev)

        # If not: reschedule a timeout
        else:
            wmanager.debug('keys', 'rescheduling timeout at %s',
                           self.last_key_time + self.timeout)
            self.timer = event.TimerEvent(self.timer_id,
                                          at=self.last_key_time + self.timeout)
            self.wm.events.add_timer(self.timer)
Пример #15
0
    def comp_do_set_brightness(self, client, settings, value):
        wmanager.debug('composite', 'changing brightness from %d to %d for %s',
                       settings.brightness, value, client)

        settings.brightness = value

        if value != 0:

            # value must be unsigned
            if value < 0:
                value = struct.unpack('=L', struct.pack('=l', value))[0]

            client.window._proxy.change_property(self._PLCM_BRIGHTNESS,
                                                 Xatom.INTEGER, 32, [value])
        else:
            client.window._proxy.delete_property(self._PLCM_BRIGHTNESS)

        # No longer any settings in effect?
        if settings.no_effects():
            self.comp_disable_client(client)
Пример #16
0
    def __client_init__(self):
        assert self.mozpopup_keymap is not None

        # Recognize Netscape 6.1 popups in this manner:
        # They have class Mozilla-bin.
        # They are not WM_TRANSIENT_FOR windows.
        # They have _MOTIF_WM_HINTS set, where MwmHints.flags have
        # MWM_HINTS_DECORATIONS set,
        # and MwmHints.decorations not in (MWM_DECOR_ALL, 0x7e)
        # (struct and flags defined in MwmUtil.h)

        # Only act when the window was found thanks to a maprequest.
        if not self.from_maprequest:
            return

        if self.res_class != 'Mozilla-bin':
            return

        MWM_HINTS = self.wm.display.intern_atom("_MOTIF_WM_HINTS")
        WM_TRANSIENT_FOR = self.wm.display.intern_atom("WM_TRANSIENT_FOR")

        r = self.window.get_property(WM_TRANSIENT_FOR, Xatom.WINDOW, 0, 1)
        if r is not None:
            return

        r = self.window.get_property(MWM_HINTS, MWM_HINTS, 0, 5)
        if r is None or r.format != 32 or len(r.value) != 5:
            return

        # Check flags and decoration
        if r.value[0] & 2 and r.value[2] not in (1, 0x7edd):
            wmanager.debug('mozilla', 'detected mozilla popup')

            # Don't map window immediately, and install
            # a temporary keymap to allow activating the window
            self.start_iconified = 1
            self.mozpopup_keymap(self)
            self.wm.display.bell(0)
Пример #17
0
    def inspect_enable(self):
        # Inspection already enabled
        if self.inspect_socket is not None:
            return

        wmanager.debug('inspect', 'enabling inspect server')

        # Listen on any port on the local interfaces
        self.inspect_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.inspect_socket.bind(('', 0))
        self.inspect_socket.listen(5)

        self.inspect_socket_event = event.FileEvent(InspectFileEventType,
                                                    self.inspect_socket,
                                                    event.FileEvent.READ)

        self.events.add_file(self.inspect_socket_event)

        # Create a authentication cookie, and store it and the
        # portnumber in a property on screen 0

        addr, port = self.inspect_socket.getsockname()
        self.inspect_cookie = random.randint(0, 0x7ffffffe)

        self.default_screen.root.change_property(self.PLWM_INSPECT_SERVER,
                                                 self.PLWM_INSPECT_SERVER, 32,
                                                 [port, self.inspect_cookie])

        self.inspect_clients = {}

        self.inspect_message = modewindow.Message(.2, modewindow.LEFT, 0,
                                                  '[Inspect]')
        for s in self.screens:
            try:
                s.modewindow_add_message(self.inspect_message)
            except AttributeError:
                pass
Пример #18
0
 def _cycle_abort(self, evt):
     wmanager.debug('keys', 'Aborting cycle mode')
     self.cycle.abort()
     self._cleanup()
Пример #19
0
 def _cycle_end(self, evt):
     wmanager.debug('keys', 'Leaving cycle mode')
     self.cycle.end()
     self._cleanup()
Пример #20
0
class CycleKeys(keys.KeyGrabKeyboard):
    """CycleKeys is a template keyhandler for cycling clients.
    You should subclass it to define your own keybindings and setting
    the approriate client filter.

    The filter for the cycle is specified by the attribute _cycle_filter.
    This can be set to any client filter, by default `true' is used.

    CycleKeys defines a number of event handler methods:

      _cycle_next      Cycle to the next client
      _cycle_previous  Cycle to the previous client
      _cycle_end       Finish, selecting the current client
      _cycle_abort     Abort, reverting to the previous state (if possible)

    By default outline cycling is used with the CycleOutline class.
    This can be changed by redefining the attribute _cycle_class to
    any subclass of Cycle.

    A small CycleKeys subclass example:

      class MyCycleKeys(CycleKeys):
         _cycle_class = CycleActivate
         _cycle_filter = cfilter.Not(cfilter.iconified)

         Tab = CycleKeys._cycle_next
         C_Tab = CycleKeys._cycle_next
         S_Tab = CycleKeys._cycle_previous
         S_C_Tab = CycleKeys._cycle_previous

         Return = CycleKeys._cycle_end
         Escape = CycleKeys._cycle_abort


    To activate your cycle keys, write a keyhandler event method like
    this in your basic keyhandler:

      def C_Tab(self, evt):
         MyCycleKeys(self, evt)

    """

    propagate_keys = 0
    timeout = 10

    _cycle_class = CycleOutline
    _cycle_filter = cfilter.true

    def __init__(self, keyhandler, event):
        # Always initialize the keyhandler, otherwise
        # we'll get problems in the __del__ method.

        try:
            keys.KeyGrabKeyboard.__init__(self, keyhandler.wm, event.time)
        except keys.error, status:
            wmanager.debug('keys', 'Grabbing keyboard failed: %d', status)

        # Create the cycle object, but clean up and return immediately
        # if no clients match the filter
        try:
            wmanager.debug('keys', 'Entering cycle mode')
            self.cycle = self._cycle_class(keyhandler.wm.current_screen,
                                           self._cycle_filter)
        except NoClientsError:
            wmanager.debug(
                'keys', 'No clients matching cycle filter, leaving cycle mode')
            self._cleanup()
Пример #21
0
    def __init__(self, screen, window, *args, **keys):
        wmanager.WindowProxyBase.__init__(self, screen, window, *args, **keys)

        # Create a proxy window that will contain the real window as a
        # clone of the source window.

        g = window.get_geometry()
        a = window.get_attributes()

        # Never trust an X server.  The visual and depth as returned
        # by the methods just called can result in a BadMatch, despite
        # the reasonable assumption that if the client could create a
        # window with those specs, then we can also do it.

        # The reason for this sad state of affairs is OpenGL: a GLX
        # visual that have 24 bits of colour info _and_ 8 bits of
        # alpha info appears to a non-GL application (e.g. plwm) to
        # have depth 24, but you can't create windows of that depth on
        # it.  An example of an application that does this is
        # OpenOffice 2.0, which is how I found it.

        # In this case, just create a window on the default visual for
        # the proxy and disable composition for this client (as plcm
        # require that the proxy and the client windows use the same
        # visual).

        self._composition_disabled = 0

        ec = error.CatchError(error.BadMatch)
        self._proxy = screen.root.create_window(g.x,
                                                g.y,
                                                g.width,
                                                g.height,
                                                g.border_width,
                                                g.depth,
                                                a.win_class,
                                                a.visual,
                                                onerror=ec)

        # Check if the mismatch was triggered
        self._wm.display.sync()

        if ec.get_error():
            wmanager.debug('composite',
                           'strange visual, disabling composition for %s',
                           window)

            self._composition_disabled = 1
            self._proxy = screen.root.create_window(g.x, g.y, g.width,
                                                    g.height, g.border_width,
                                                    X.CopyFromParent)

        # The proxy window must have the SubstructureRedirectMask set, so
        # we still get MapRequest, ConfigureRequest etc for the client window.
        self._proxy.change_attributes(event_mask=X.SubstructureRedirectMask)

        # Reparent the real window into the proxy window, blocking any
        # UnmapNotify that might generate

        screen.event_mask.block(X.SubstructureNotifyMask)
        window.configure(border_width=0)
        window.reparent(self._proxy, 0, 0)
        screen.event_mask.unblock(X.SubstructureNotifyMask)

        # Some methods can be overridden simply by only working on the proxy window
        self.get_geometry = self._proxy.get_geometry
        self.circulate = self._proxy.circulate
        self.reparent = self._proxy.reparent

        self._screen.add_proxy_window(self._proxy, window)
Пример #22
0
    def __init__(self, screen, window, *args, **keys):
        wmanager.WindowProxyBase.__init__(self, screen, window, *args, **keys)

        if FrameProxy._NET_WM_STATE is None:
            FrameProxy._NET_WM_STATE = self._wm.display.intern_atom(
                "_NET_WM_STATE")
            FrameProxy._NET_WM_STATE_DEMANDS_ATTENTION = self._wm.display.intern_atom(
                "_NET_WM_STATE_DEMANDS_ATTENTION")

        self._font = self._wm.get_font(self._title_font)
        self._title_pixel = self._screen.get_color(self._title_color)
        self._unfocused_pixel = self._screen.get_color(self._unfocused_color)
        self._focused_pixel = self._screen.get_color(self._focused_color)
        self._urgent_pixel = self._screen.get_color(self._urgent_color)

        fq = self._font.query()

        self._extra_height = fq.font_ascent + fq.font_descent + 3 * self._frame_width
        self._extra_width = 2 * self._frame_width

        self._title_x = self._frame_width
        self._title_y = self._frame_width
        self._title_base = self._frame_width + fq.font_ascent
        self._client_x = self._frame_width
        self._client_y = fq.font_ascent + fq.font_descent + 2 * self._frame_width
        self._focused = False

        # Create a proxy window for the frame that will contain the
        # real window

        g = window.get_geometry()

        self._frame = self._screen.root.create_window(
            g.x - self._client_x - g.border_width,
            g.y - self._client_y - g.border_width,
            g.width + self._extra_width,
            g.height + self._extra_height,
            0,
            X.CopyFromParent,
            X.InputOutput,
            X.CopyFromParent,
            background_pixel=self._unfocused_pixel,
            event_mask=X.ExposureMask | X.SubstructureRedirectMask)

        wmanager.debug('frame', 'created frame %s for client %s', self._frame,
                       self._window)

        self._gc = self._frame.create_gc(foreground=self._title_pixel,
                                         font=self._font)

        # Reparent the real window into the frame window, blocking any
        # UnmapNotify that might generate

        screen.event_mask.block(X.SubstructureNotifyMask)
        window.configure(border_width=0)
        window.reparent(self._frame, self._client_x, self._client_y)
        screen.event_mask.unblock(X.SubstructureNotifyMask)

        # Some methods can be overridden simply by only working on the proxy window
        self.get_geometry = self._frame.get_geometry
        self.circulate = self._frame.circulate
        self.reparent = self._frame.reparent

        self._screen.add_proxy_window(self._frame, window)
Пример #23
0
class InspectClient:
    def __init__(self, wm, sock, addr):
        self.wm = wm
        self.socket = sock
        self.addr = addr
        self.authed = 0

        self.event = event.FileEvent(InspectFileEventType, self.socket,
                                     event.FileEvent.READ)
        self.wm.events.add_file(self.event)

        self.recv_len = 0
        self.recv_buf = ''
        self.send_buf = ''

        self.globals = __builtins__.copy()
        self.globals['wm'] = self.wm

    def handle_file_event(self, evt):
        if evt.state & event.FileEvent.READ:
            try:
                d = self.socket.recv(500)
            except socket.error, err:
                wmanager.debug('inspect',
                               'client %s closed on failed recv: %s',
                               self.addr, err)
                self.close()
                return

            if not d:
                wmanager.debug('inspect', 'client %s closed', self.addr)
                self.close()
                return

            self.recv_buf = self.recv_buf + d

            # First four bytes sent must the the authentication cookie
            if not self.authed:
                if len(self.recv_buf) >= 4:
                    cookie = struct.unpack('>l', self.recv_buf[:4])[0]
                    self.recv_buf = self.recv_buf[4:]

                    if cookie == self.wm.inspect_cookie:
                        self.authed = 1
                        self.output('Welcome to PLWM at %s\n' %
                                    self.wm.display.get_display_name())
                    else:
                        wmanager.debug('inspect',
                                       'client %s closed on wrong cookie: %d',
                                       self.addr, cookie)
                        self.close()
                        return

            while 1:
                # No length recieved yet, parse a little-endian fourbyte length
                if self.recv_len == 0:
                    if len(self.recv_buf) >= 4:
                        self.recv_len = struct.unpack('>l',
                                                      self.recv_buf[:4])[0]

                        # Do sanity check on length, abort connection if it is < 0
                        if self.recv_len < 0:
                            wmanager.debug(
                                'inspect',
                                'client %s closed, sent negative length: %d',
                                self.addr, self.recv_len)
                            self.close()
                            return

                        self.recv_buf = self.recv_buf[4:]
                    else:
                        break

                # All data of expression read, execute it
                if self.recv_len <= len(self.recv_buf):
                    data = self.recv_buf[:self.recv_len]
                    self.recv_buf = self.recv_buf[self.recv_len:]
                    self.recv_len = 0

                    self.exec_data(data)
                else:
                    break

        if evt.state & event.FileEvent.WRITE:
            # Send any unsent data
            try:
                n = self.socket.send(self.send_buf)
            except socket.error, err:
                wmanager.debug('inspect',
                               'client %s closed on failed send: %s',
                               self.addr, err)
                self.close()
                return

            self.send_buf = self.send_buf[n:]

            # If there are no data left to send, clear the
            # WRITE flag in the event to avoid a lot of
            # select follies.

            if len(self.send_buf) == 0:
                evt.set_mode(clear=event.FileEvent.WRITE)
Пример #24
0
    def handle_file_event(self, evt):
        if evt.state & event.FileEvent.READ:
            try:
                d = self.socket.recv(500)
            except socket.error, err:
                wmanager.debug('inspect',
                               'client %s closed on failed recv: %s',
                               self.addr, err)
                self.close()
                return

            if not d:
                wmanager.debug('inspect', 'client %s closed', self.addr)
                self.close()
                return

            self.recv_buf = self.recv_buf + d

            # First four bytes sent must the the authentication cookie
            if not self.authed:
                if len(self.recv_buf) >= 4:
                    cookie = struct.unpack('>l', self.recv_buf[:4])[0]
                    self.recv_buf = self.recv_buf[4:]

                    if cookie == self.wm.inspect_cookie:
                        self.authed = 1
                        self.output('Welcome to PLWM at %s\n' %
                                    self.wm.display.get_display_name())
                    else:
                        wmanager.debug('inspect',
                                       'client %s closed on wrong cookie: %d',
                                       self.addr, cookie)
                        self.close()
                        return

            while 1:
                # No length recieved yet, parse a little-endian fourbyte length
                if self.recv_len == 0:
                    if len(self.recv_buf) >= 4:
                        self.recv_len = struct.unpack('>l',
                                                      self.recv_buf[:4])[0]

                        # Do sanity check on length, abort connection if it is < 0
                        if self.recv_len < 0:
                            wmanager.debug(
                                'inspect',
                                'client %s closed, sent negative length: %d',
                                self.addr, self.recv_len)
                            self.close()
                            return

                        self.recv_buf = self.recv_buf[4:]
                    else:
                        break

                # All data of expression read, execute it
                if self.recv_len <= len(self.recv_buf):
                    data = self.recv_buf[:self.recv_len]
                    self.recv_buf = self.recv_buf[self.recv_len:]
                    self.recv_len = 0

                    self.exec_data(data)
                else:
                    break
Пример #25
0
    def __init__(self, obj, deprecated_arg=None):
        """Instantiate a KeyHandler object.
        """

        # Warn if the deprecated and unused former "dispatch" argument
        # is used.
        if deprecated_arg is not None:
            sys.stderr.write(
                "%s: warning: using deprecated KeyHandler __init__ interface\n"
                % sys.argv[0])

        wmanager.debug('mem', 'Initing keyhandler %s for %s', self, obj)

        # Figure out if we have been added to a WindowManager, Screen
        # or Client object.  Set up KeygrabManager objects if not
        # already done on screens or clients.

        if isinstance(obj, wmanager.WindowManager):
            wm = obj
            grabmgrs = []
            for s in obj.screens:
                if not hasattr(s, 'keygrab_mgr'):
                    s.keygrab_mgr = KeygrabManager(obj, s.root)
                grabmgrs.append(s.keygrab_mgr)

        elif isinstance(obj, wmanager.Screen):
            wm = obj.wm
            if not hasattr(obj, 'keygrab_mgr'):
                obj.keygrab_mgr = KeygrabManager(obj.wm, obj.root)
            grabmgrs = [obj.keygrab_mgr]

        elif isinstance(obj, wmanager.Window):
            wm = obj.wm
            if not hasattr(obj, 'keygrab_mgr'):
                obj.keygrab_mgr = KeygrabManager(obj.wm, obj.window)
            grabmgrs = [obj.keygrab_mgr]

        else:
            raise TypeError('expected WindowManager, Screen or Client object')

        # Dig through all names in this object, ignoring those beginning with
        # an underscore.

        # First collect all method names in this and it's base classes
        names = {}
        c = [self.__class__]
        while len(c):
            names.update(c[0].__dict__)
            c = c + list(c[0].__bases__)
            del c[0]

        names.update(self.__dict__)

        # And now parse the names
        rawbinds = []
        for name in names.keys():
            if name[0] != '_':

                # Find modifiers in name
                mask = 0
                parts = string.split(name, '_')
                while len(parts) >= 2 and modifiers.has_key(parts[0]):
                    mask = mask | modifiers[parts[0]]
                    del parts[0]

                # Find name keysym
                rest = string.join(parts, '_')
                keysym = XK.string_to_keysym(rest)
                if keysym != X.NoSymbol:
                    rawbinds.append((keysym, mask, getattr(self, name)))

        self.wm = wm
        self.dispatch = obj.dispatch
        self.grabmgrs = grabmgrs
        self.rawbindings = rawbinds
        self.grabs = []

        # Add handlers
        if self.propagate_keys:
            self.dispatch.add_handler(X.KeyPress,
                                      self._keyevent,
                                      handlerid=self)
            self.dispatch.add_handler(X.KeyRelease,
                                      self._keyevent,
                                      handlerid=self)
        else:
            self.dispatch.add_grab_handler(X.KeyPress,
                                           self._keyevent,
                                           handlerid=self)
            self.dispatch.add_grab_handler(X.KeyRelease,
                                           self._keyevent,
                                           handlerid=self)

        # Okay, so we will remap and regrab once for every
        # screen, but I'm not worried.  xmodmap isn't the most
        # frequently used command...
        self.dispatch.add_handler(X.MappingNotify,
                                  self._mappingnotify,
                                  handlerid=self)

        if self.timeout:
            self.last_key_time = None
            self.timer_id = event.new_event_type()
            self.timer = event.TimerEvent(self.timer_id, after=self.timeout)
            self.wm.events.add_timer(self.timer)
            self.dispatch.add_handler(self.timer_id,
                                      self._internal_timeout,
                                      handlerid=self)

        self._buildmap()
Пример #26
0
 def __del__(self):
     wmanager.debug('mem', 'Freeing keyhandler %s', self)
     self._cleanup()
Пример #27
0
 def focus_leave(self, evt):
     wmanager.debug('focus', 'Pointer leave %s', evt.window)
     self.set_current_client(self.ptfocus_get_focused_client(), evt.time)