Example #1
0
def main():
    # current display
    global display,root
    display = Display()
    root = display.screen().root
    # we tell the X server we want to catch keyPress event
    root.change_attributes(event_mask = X.KeyPressMask|X.KeyReleaseMask)
    # just grab the "1"-key for now
    # Common keys without state
    for key_code in key_codes.keys():
        root.grab_key(key_code, 0, True,X.GrabModeSync, X.GrabModeSync)
    # F Keys with shift
    for key_code in f_keys.keys():
        root.grab_key(key_code, 1, True,X.GrabModeSync, X.GrabModeSync)
    # F Keys with ctrl
    for key_code in f_keys.keys():
        root.grab_key(key_code, 4, True,X.GrabModeSync, X.GrabModeSync)
    # Keys with ctrl
    for key_code in ctrl_codes:
        root.grab_key(key_code, 4, True,X.GrabModeSync, X.GrabModeSync)
    # Switcher key
    root.grab_key(KEY_SWITCHER, 4, True,X.GrabModeSync, X.GrabModeSync)
    # signal.signal(signal.SIGALRM, lambda a,b:sys.exit(1))
    # signal.alarm(30)
    while 1:
        event = display.next_event()
        handle_event(event)
        display.allow_events(X.AsyncKeyboard, X.CurrentTime)
Example #2
0
class PointerMonitor(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
    }

    def __init__(self):
        GObject.GObject.__init__ (self)
        threading.Thread.__init__ (self)
        self.setDaemon (True)
        self.display = Display()
        self.root = self.display.screen().root
        self.windows = []

    # Receives GDK windows
    def addWindowToMonitor(self, window):
        gdk.gdk_x11_drawable_get_xid.argtypes = [c_void_p]
        xWindow = self.display.create_resource_object("window", gdk.gdk_x11_drawable_get_xid(hash(window)))
        self.windows.append(xWindow)

    def grabPointer(self):
        self.root.grab_button(X.AnyButton, X.AnyModifier, True, X.ButtonPressMask, X.GrabModeSync, X.GrabModeAsync, 0, 0)
        self.display.flush()

    def ungrabPointer(self):
        self.root.ungrab_button(X.AnyButton, X.AnyModifier)
        self.display.flush()

    def idle(self):
        self.emit("activate")
        return False

    def activate(self):
        GLib.idle_add(self.run)

    def run(self):
        self.running = True
        while self.running:
            event = self.display.next_event()
            try:
                if event.type == X.ButtonPress:
                    # Check if pointer is inside monitored windows
                    for w in self.windows:
                        p = w.query_pointer()
                        g = w.get_geometry()
                        if p.win_x >= 0 and p.win_y >= 0 and p.win_x <= g.width and p.win_y <= g.height:
                            break
                    else:
                        # Is outside, so activate
                        GLib.idle_add(self.idle)
                    self.display.allow_events(X.ReplayPointer, event.time)
                else:
                    self.display.allow_events(X.ReplayPointer, X.CurrentTime)
            except Exception as e:
                print "Unexpected error: " + str(e)

    def stop(self):
        self.running = False
        self.root.ungrab_button(X.AnyButton, X.AnyModifier)
        self.display.close()
Example #3
0
class PointerMonitor(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
    }
       
    def __init__(self):
        GObject.GObject.__init__ (self)
        threading.Thread.__init__ (self)
        self.setDaemon (True)
        self.display = Display()
        self.root = self.display.screen().root
        self.windows = []
        
    # Receives GDK windows
    def addWindowToMonitor(self, window):
        xWindow = self.display.create_resource_object("window", gdk.gdk_x11_drawable_get_xid(hash(window)))
        self.windows.append(xWindow)
            
    def grabPointer(self):
        self.root.grab_button(X.AnyButton, X.AnyModifier, True, X.ButtonPressMask, X.GrabModeSync, X.GrabModeAsync, 0, 0)
        self.display.flush()
        
    def ungrabPointer(self):
        self.root.ungrab_button(X.AnyButton, X.AnyModifier)
        self.display.flush()

    def idle(self):
        self.emit("activate")
        return False

    def activate(self):
        GLib.idle_add(self.run)
                    
    def run(self):
        self.running = True
        while self.running:
            event = self.display.next_event()
            try:
                if event.type == X.ButtonPress:
                    # Check if pointer is inside monitored windows
                    for w in self.windows:
                        p = w.query_pointer()
                        g = w.get_geometry()
                        if p.win_x >= 0 and p.win_y >= 0 and p.win_x <= g.width and p.win_y <= g.height:
                            break
                    else:
                        # Is outside, so activate
                        GLib.idle_add(self.idle)
                    self.display.allow_events(X.ReplayPointer, event.time)
                else:        
                    self.display.allow_events(X.ReplayPointer, X.CurrentTime)
            except Exception as e:
                print "Unexpected error: " + str(e)

    def stop(self):
        self.running = False
        self.root.ungrab_button(X.AnyButton, X.AnyModifier)
        self.display.close()
Example #4
0
def main():
    # current display
    global display, root
    display = Display()
    root = display.screen().root

    # we tell the X server we want to catch keyPress event
    root.change_attributes(event_mask=X.KeyPressMask | X.KeyReleaseMask)

    # just grab the "1"-key for now
    root.grab_key(10, 0, True, X.GrabModeSync, X.GrabModeSync)

    root.grab_button(1, X.Mod1Mask, 1, X.ButtonPressMask, X.GrabModeAsync,
                     X.GrabModeAsync, X.NONE, X.NONE)

    # only run for 10 seconds
    signal.signal(signal.SIGALRM, lambda a, b: sys.exit(1))
    signal.alarm(10)

    while 1:
        # Handle events without blocking
        event = display.next_event()
        handle_event(event)
        display.allow_events(X.AsyncKeyboard, X.CurrentTime)
Example #5
0
def main():
    # current display
    global display,root
    display = Display()
    root = display.screen().root

    # we tell the X server we want to catch keyPress event
    root.change_attributes(event_mask = X.KeyPressMask|X.KeyReleaseMask)

    # just grab the "1"-key for now
    root.grab_key(10, 0, True, X.GrabModeSync, X.GrabModeSync)

    root.grab_button(1, X.Mod1Mask, 1, X.ButtonPressMask,
                    X.GrabModeAsync, X.GrabModeAsync, X.NONE, X.NONE)

    # only run for 10 seconds
    signal.signal(signal.SIGALRM, lambda a,b:sys.exit(1))
    signal.alarm(10)

    while 1:
        # Handle events without blocking
        event = display.next_event()
        handle_event(event)
        display.allow_events(X.AsyncKeyboard, X.CurrentTime)
Example #6
0
class KeyTools:
    KEY_PRESS = X.KeyPress
    KEY_RELEASE = X.KeyRelease
    def __init__(self):
        self._xdisplay = Display()
        self._xroot = self._xdisplay.screen().root
        self._clipboard = gtk.clipboard_get()
        self._clipPrimay = gtk.clipboard_get("PRIMARY")
        self._entryForPaste = 118, X.ShiftMask
        self._group = 0
        self.loadModifiers()
        self._keymap = gdk.keymap_get_default()  # @UndefinedVariable
        
    def loadModifiers(self):
        self._modifiers = []
        self._modifierList = []
        for key in self._xdisplay.get_modifier_mapping():
            li = [k for k in key if k]
            #for altgr key
            if 92 in li:
                li.append(108)
            self._modifierList += li
            self._modifiers.append(li)
    
    
    def filterGroup(self, entries):
        if entries:
            return [e for e in entries if e[-2] == self._group]
        return []
    
    
    def remapKey(self, keycode, keysyms):
        allKeysyms = list(self._xdisplay.get_keyboard_mapping(keycode, 1)[0])
        keysyms = keysyms + [0]*(4 - len(keysyms))
        allKeysyms[:2] = keysyms[:2]
        allKeysyms[4:6] = keysyms[2:]
        self._xdisplay.change_keyboard_mapping(keycode, [allKeysyms])
        self._xdisplay.sync()
    
    
    
    def resetMapping(self):
        try:
            process = Popen('setxkbmap -print -verbose 7'.split(), stdout=PIPE, stderr=PIPE)
        except OSError:
            print 'install setxkbmap'
        
        for line in process.stderr:
            print 'setxkbmap error: {}'.format(line)
        
        layout = variant = ''
        
        for line in process.stdout:
            line = line.rstrip()
            if line == '':
                break
            
            if line.startswith('layout:'):
                layout = line.split()[1]
            elif line.startswith('variant:'):
                variant = line.split()[1]
                break
                
        command = ['setxkbmap']
        if layout:
            command += ['-layout', layout]
                   
        if variant:
            command += ['-variant', variant]
        if layout or command:
            try:
                process = Popen(command, stdout=PIPE, stderr=PIPE)
            except OSError:
                print 'install setxkbmap'
                
            for line in process.stderr:
                print 'setxkbmap error: {}'.format(line)
    
    def isModifier(self, keycode):
        return keycode in self._modifierList
    
    def getModMask(self, keycode):
        for i, mods in enumerate(self._modifiers):
            if keycode in mods:
                return 2**i
            
        return 0
    
    def modifiersKeycodeList(self):
        return self._modifierList
    
    def numMask(self):
        return X.Mod2Mask
    
    def keycode2char(self, keycode, mods, group=0):
        char = ''
        name = ''
        info = self._keymap.translate_keyboard_state(keycode, mods, group)
        if info:
            keysym = info[0]
            char = gdk.keyval_to_unicode(keysym)  # @UndefinedVariable
            if char:
                char = unichr(char)
            name = gdk.keyval_name(keysym)  # @UndefinedVariable
            
        return char or '', name or ''
    
    def removeNumLockMask(self, keycode, mod):
        if not self.isKeypadKey(keycode) and mod & X.Mod2Mask:
            return mod ^ X.Mod2Mask
        
        return mod
     
    def entry2keysym(self, keycode, modMask):
        info = self._keymap.translate_keyboard_state(keycode, modMask, self._group)
        if info:
            return info[0]
        
        return None
        
    def entry2name(self, keycode, modMask):
        keysym = self.entry2keysym(keycode, modMask)
        if keysym is not None:
            return gdk.keyval_name(keysym)  # @UndefinedVariable
        
        return None
    
    def keycode2entries(self, keycode):
        return self.filterGroup(self._keymap.get_entries_for_keycode(keycode))
    
    def keysym2entry(self, keysym):
        if not keysym:
            return None
        
        infos = self._keymap.get_entries_for_keyval(keysym)  # @UndefinedVariable
        if infos:
            for info in infos:
                keycode, group, level = info
                if group == self._group:
                    if level < len(LEVEL_MOD):
                        mod = LEVEL_MOD[level]
                        return keycode, mod
            
        return None
    
    def keysym2deadEntries(self, keysym):
        resp = ()
        entry = self.keysym2entry(keysym)
        if entry:
            keycode, mod = entry
            resp = ((keycode, mod), )
            
        if not resp:
            deadKeys = self.findWithDeadKey(keysym)
            if deadKeys:
                keyKeysym, deadKeysym = deadKeys
                keyKeycodes = self.keysym2entry(keyKeysym)
                deadKeycodes = self.keysym2entry(deadKeysym)
                if keyKeycodes and deadKeycodes:
                    keyKeycode, keyMod = keyKeycodes
                    deadKeycode, deadMod = deadKeycodes
                    resp = ((deadKeycode, deadMod), (keyKeycode, keyMod))
              
        return resp
        
    
    def keycode2charsAndNames(self, keycode):
        entries = self.keycode2entries(keycode)
        chars = []
        names = []
        for entry in entries:
            chars.append(keysym2char(entry[0]))
            names.append(keysym2name(entry[0]))
            if len(chars) >= 4:
                break
        
        while not names[-1]:
            chars.pop(-1)
            names.pop(-1)
        return chars, names
    
    def keycode2keysyms(self, keycode):
        entries = self.keycode2entries(keycode)
        return [e[0] for e in entries][:4]
                
    def char2entries(self, char):
        keysym = gdk.unicode_to_keyval(ord(char))  # @UndefinedVariable
        if keysym:
            return self.keysym2deadEntries(keysym)
        
        return ()
    
    def findWithDeadKey(self, keysym):
        name = gdk.keyval_name(keysym)  # @UndefinedVariable
        for deadName in DEAD_KEYS:
            if name.endswith(deadName):
                keyName = name[:-len(deadName)]
                deadName = {'ring': 'abovering', 
                           'schwa': 'small_schwa', 
                           'SCHWA': 'capital_schwa'}.get(deadName, deadName)
                deadName = 'dead_' + deadName
                keyKeysym = gdk.keyval_from_name(keyName)  # @UndefinedVariable
                deadSym = gdk.keyval_from_name(deadName)  # @UndefinedVariable
                return keyKeysym, deadSym
        return None
            
    
    def isKeypadKey(self, keycode):
        entry = self._keymap.get_entries_for_keycode(keycode)
        if entry:
            for info in entry:
                if info[2] == self._group:
                    name = gdk.keyval_name(info[0])  # @UndefinedVariable
                    if name and name.startswith('KP_'):
                        return True
                    
        return False
    
        
    def grabKey(self, keycode, modMask):
        self._xroot.grab_key(keycode, modMask, 0, X.GrabModeAsync, X.GrabModeAsync)
        if not self.isKeypadKey(keycode) and not modMask & X.Mod2Mask:
            self._xroot.grab_key(keycode, modMask | X.Mod2Mask, 0, X.GrabModeAsync, X.GrabModeAsync)
            
    def ungrabKey(self, keycode, modMask):
        self._xroot.ungrab_key(keycode, modMask)
        if not self.isKeypadKey(keycode) and not modMask & X.Mod2Mask:
            self._xroot.ungrab_key(keycode, modMask | X.Mod2Mask)
    
    def nextKeyEvent(self, typ=KEY_PRESS):
        if isinstance(typ, int):
            typ = (typ,)
        num = self._xdisplay.pending_events()
        if num:
            for _ in range(num):
                event = self._xdisplay.next_event()
                if event.type in typ:
                    return keyEvent(event.type, event.detail, event.state)
                self._xdisplay.allow_events(X.AsyncKeyboard, X.CurrentTime)
        return None

    
    def slotClipboard(self, clipboard, text, backup):
        self.sendEntry(*self._entryForPaste)
        t = Timer(0.1, self.restoreClipboard, (backup,))
        t.start()
        
        
    def restoreClipboard(self, backup):
        self._clipboard.request_text(lambda a, b, c: None)
        if backup:
            self._clipboard.set_text(backup or '')
            self._clipPrimay.clear()
            self._clipboard.store()
     
    def sendText(self, text):
        backup = self._clipboard.wait_for_text()
        self._clipboard.set_text(text)
        self._clipPrimay.set_text(text)
        self._clipboard.request_text(self.slotClipboard, backup)
        self._clipboard.store()
        self._clipPrimay.store()
                
    def sendKeysym(self, keysym):
        entries = self.keysym2deadEntries(keysym)
        for entry in entries:
            self.sendEntry(*entry)
    
    def sendEntry(self, keycode, mod):
        self.pressKey(keycode, mod)
        self.releaseKey(keycode, mod)
    
    def pressKey(self, keycode, modMask):
        window = self._xdisplay.get_input_focus()._data["focus"]
        evt = Xlib.protocol.event.KeyPress(  # @UndefinedVariable
            time = X.CurrentTime,
            root = self._xroot,
            window = window,
            same_screen = 0, child = Xlib.X.NONE,
            root_x = 0, root_y = 0, event_x = 0, event_y = 0,
            state = modMask,
            detail = keycode
            )
        window.send_event(evt, propagate = True)
        
    def releaseKey(self, keycode, modMask):
        window = self._xdisplay.get_input_focus()._data["focus"]
        evt = Xlib.protocol.event.KeyRelease(  # @UndefinedVariable
            time = X.CurrentTime,
            root = self._xroot,
            window = window,
            same_screen = 0, child = Xlib.X.NONE,
            root_x = 0, root_y = 0, event_x = 0, event_y = 0,
            state = modMask,
            detail = keycode
            )
        window.send_event(evt, propagate = True)
Example #7
0
class GlobalKeyBinding(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate':(GObject.SIGNAL_RUN_LAST, None,()),
        }

    def __init__(self):
        GObject.GObject.__init__(self)
        threading.Thread.__init__(self)
        self.setDaemon(True)

        self.keymap = Gdk.Keymap.get_default()
        self.display = Display()
        self.screen = self.display.screen()
        self.root = self.screen.root
        self.ignored_masks = self.get_mask_combinations(X.LockMask | X.Mod2Mask | X.Mod5Mask)
        self.map_modifiers()

    def map_modifiers(self):
        gdk_modifiers =(Gdk.ModifierType.CONTROL_MASK, Gdk.ModifierType.SHIFT_MASK, Gdk.ModifierType.MOD1_MASK,
                         Gdk.ModifierType.MOD2_MASK, Gdk.ModifierType.MOD3_MASK, Gdk.ModifierType.MOD4_MASK, Gdk.ModifierType.MOD5_MASK,
                         Gdk.ModifierType.SUPER_MASK, Gdk.ModifierType.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            if "Mod" not in Gtk.accelerator_name(0, modifier):
                self.known_modifiers_mask |= modifier

    def grab(self):
        Gdk.threads_enter()

        self.keycode= self.keymap.get_entries_for_keyval(keyval)[1][0].keycode
        self.modifiers = int(modifiers)

        catch = error.CatchError(error.BadAccess)
        for ignored_mask in self.ignored_masks:
            mod = modifiers | ignored_mask
            result = self.root.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeSync, onerror=catch)
        self.display.sync()
        if catch.get_error():
            return False
        return True

    def ungrab(self):
        if self.keycode:
            self.root.ungrab_key(self.keycode, X.AnyModifier, self.root)

    def get_mask_combinations(self, mask):
        return [x for x in xrange(mask+1) if not (x & ~mask)]

    def idle(self):
        Gdk.threads_enter()
        self.emit("activate")
        Gdk.threads_leave()
        return False

    def run(self):
        self.running = True
        wait_for_release = False
        while self.running:
            event = self.display.next_event()
            self.current_event_time = event.time
            if event.detail == self.keycode and event.type == X.KeyPress and not wait_for_release:
                modifiers = event.state & self.known_modifiers_mask
                if modifiers == self.modifiers:
                    wait_for_release = True
                    self.display.allow_events(X.AsyncKeyboard, event.time)
                else:
                    self.display.allow_events(X.ReplayKeyboard, event.time)
            elif event.detail == self.keycode and wait_for_release:
                if event.type == X.KeyRelease:
                    wait_for_release = False
                    GLib.idle_add(self.idle)
                self.display.allow_events(X.AsyncKeyboard, event.time)
            else:
                self.display.allow_events(X.ReplayKeyboard, event.time)

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()
Example #8
0
class GlobalKeyBinding(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
    }

    def __init__(self):
        GObject.GObject.__init__ (self)
        threading.Thread.__init__ (self)
        self.setDaemon (True)

        gdk.gdk_keymap_get_default.restype = c_void_p
        self.keymap = capi.get_widget (gdk.gdk_keymap_get_default())
        self.display = Display()
        self.screen = self.display.screen()
        self.window = self.screen.root
        self.ignored_masks = self.get_mask_combinations(X.LockMask | X.Mod2Mask | X.Mod5Mask)
        self.map_modifiers()
        self.raw_keyval = None
        self.keytext = ""

    def is_hotkey(self, key, modifier):
        keymatch = False
        modmatch = False
        modifier = modifier & ~Gdk.ModifierType.SUPER_MASK
        modint = int(modifier)
        if self.get_keycode(key) == self.keycode:
            keymatch = True
        for ignored_mask in self.ignored_masks:
            if self.modifiers | ignored_mask == modint | ignored_mask:
                modmatch = True
                break
        return keymatch and modmatch

    def map_modifiers(self):
        gdk_modifiers =(Gdk.ModifierType.CONTROL_MASK, Gdk.ModifierType.SHIFT_MASK, Gdk.ModifierType.MOD1_MASK,
                         Gdk.ModifierType.MOD2_MASK, Gdk.ModifierType.MOD3_MASK, Gdk.ModifierType.MOD4_MASK, Gdk.ModifierType.MOD5_MASK,
                         Gdk.ModifierType.SUPER_MASK, Gdk.ModifierType.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            if "Mod" not in Gtk.accelerator_name(0, modifier) or "Mod4" in Gtk.accelerator_name(0, modifier):
                self.known_modifiers_mask |= modifier

    def get_keycode(self, keyval):
        count = c_int()
        array = (KeymapKey * 10)()
        keys = cast(array, POINTER(KeymapKey))
        gdk.gdk_keymap_get_entries_for_keyval.argtypes = [c_void_p, c_uint, c_void_p, c_void_p]
        gdk.gdk_keymap_get_entries_for_keyval(hash(self.keymap), keyval, byref(keys), byref(count))
        return keys[0].keycode

    def grab(self, key):
        accelerator = key
        accelerator = accelerator.replace("<Super>", "<Mod4>")
        keyval, modifiers = Gtk.accelerator_parse(accelerator)
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return False

        self.keytext = key
        self.keycode = self.get_keycode(keyval)
        self.modifiers = int(modifiers)

        catch = error.CatchError(error.BadAccess)
        for ignored_mask in self.ignored_masks:
            mod = modifiers | ignored_mask
            result = self.window.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeSync, onerror=catch)
        self.display.flush()
        # sync has been blocking. Don't know why.
        #self.display.sync()
        if catch.get_error():
            return False
        return True

    def ungrab(self):
        if self.keycode:
            self.window.ungrab_key(self.keycode, X.AnyModifier, self.window)
            
    def rebind(self, key):
        self.ungrab()
        if key != "":
            self.grab(key)
        else:
            self.keytext = ""
    
    def set_focus_window(self, window = None):
        self.ungrab()
        if window is None:
            self.window = self.screen.root
        else:
            gdk.gdk_x11_drawable_get_xid.argtypes = [c_void_p]
            self.window = self.display.create_resource_object("window", gdk.gdk_x11_drawable_get_xid(hash(window)))
        self.grab(self.keytext)

    def get_mask_combinations(self, mask):
        return [x for x in xrange(mask+1) if not (x & ~mask)]

    def idle(self):
        self.emit("activate")
        return False

    def activate(self):
        GLib.idle_add(self.run)

    def run(self):
        self.running = True
        wait_for_release = False
        while self.running:
            event = self.display.next_event()
            try:
                self.current_event_time = event.time
                if event.detail == self.keycode and event.type == X.KeyPress and not wait_for_release:
                    modifiers = event.state & self.known_modifiers_mask
                    if modifiers == self.modifiers:
                        wait_for_release = True
                        self.display.allow_events(X.AsyncKeyboard, event.time)
                    else:
                        self.display.allow_events(X.ReplayKeyboard, event.time)
                elif event.detail == self.keycode and wait_for_release:
                    if event.type == X.KeyRelease:
                        wait_for_release = False
                        GLib.idle_add(self.idle)
                    self.display.allow_events(X.AsyncKeyboard, event.time)
                else:
                    self.display.allow_events(X.ReplayKeyboard, event.time)
            except AttributeError:
                continue

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()
Example #9
0
class LinuxKeyLogger(threading.Thread):
    """
    This implementation of the keylogger is designed to work on linux based
    systems. WILL NOT FUNCTION ON OTHER OPERATING SYSTEMS.
    """
    def __init__(self):
        """
        Constructs the logger and its internal objects
        """
        super().__init__()
        self.display = Display()
        self.root = self.display.screen().root
        self.capturedKeys = []
        self.windowKeys = []
        self.capture = True

    def run(self):
        """
        Starts the logging process
        """
        self.log()

    def log(self):
        """
        Sets up the root window to capture the keys being typed in.
        """
        self.root.change_attributes(event_mask=X.KeyPressMask
                                    | X.KeyReleaseMask)
        self.root.grab_keyboard(0, X.GrabModeAsync, X.GrabModeAsync,
                                X.CurrentTime)

        try:
            while self.capture:
                event = self.display.next_event()
                self.handleEvent(event)
                self.display.allow_events(X.AsyncKeyboard, X.CurrentTime)
        except Exception as e:
            print(e)

    def handleEvent(self, event):
        """
        The Xlib library will produce events when a key is pressed this method
        will analyze those events and extract the pertainent information along
        with passing that information further down the line to be processed by
        the operating system.
        :param event:
        :return: None
        """
        if (event.type == X.KeyRelease):
            char = Xlib.XK.keysym_to_string(
                self.display.keycode_to_keysym(event.detail, event.state))
            if char is not None:
                self.capturedKeys.append(char)
                self.windowKeys.append(char)
            self.send_key(event.detail, event.state)
            self.phrase_check()
            # self.send_keyup(event.detail, event.state)
        elif (event.type == X.KeyPress):
            pass
            # try:
            #     self.send_keydown(event.detail, event.status)
            # except AttributeError as ae:
            #     print(ae)
            # window = self.display.get_input_focus()._data["focus"]
            # window.send_event(event,propagate=True)

    def phrase_check(self):
        """
        This method will check to see if the typed in keys correspond to any
        of the preset phrases that have associated executions.
        :return:
        """
        # will need to create a smarter way of doing this
        stop = self.checkPhrase(self.getStopPhrase())
        if (stop):
            self.capture = False
        openT = self.checkPhrase(self.getTerminalPhrase())
        if (openT):
            self.openterminal()
        # ensure window size is maintained
        maxLength = max(len(self.getStopPhrase()),
                        len(self.getTerminalPhrase()))
        if len(self.windowKeys) > maxLength:
            self.windowKeys = self.windowKeys[len(self.windowKeys) -
                                              maxLength:]

    def checkPhrase(self, phrase):
        """
        Checks whether a phrase matches the most recently
        typed in keys.
        """
        length = len(phrase)
        capLength = len(self.windowKeys)
        if (capLength >= length):
            section = self.windowKeys[capLength - length:capLength]
            lastWords = ''.join(section)
            if (lastWords.upper() == phrase):
                return True
        return False

    def send_key(self, emulated_key, state):
        """Sends a key downstream to be processed by the computer"""
        self.send_keydown(emulated_key, state)
        self.send_keyup(emulated_key, state)

    def send_keyup(self, emulated_key, state):
        """Sends an key up message downstream to be processed by the computer"""
        shift_mask = state  # Xlib.X.ShiftMask
        window = self.display.get_input_focus()._data["focus"]
        event = Xlib.protocol.event.KeyRelease(time=int(time.time()),
                                               root=self.display.screen().root,
                                               window=window,
                                               same_screen=0,
                                               child=Xlib.X.NONE,
                                               root_x=0,
                                               root_y=0,
                                               event_x=0,
                                               event_y=0,
                                               state=shift_mask,
                                               detail=emulated_key)
        window.send_event(event, propagate=True)

    def send_keydown(self, emulated_key, state):
        """Sends a key down message downstream to be processed by the computer"""
        shift_mask = state  # Xlib.X.ShiftMask
        window = self.display.get_input_focus()._data["focus"]
        event = Xlib.protocol.event.KeyPress(time=int(time.time()),
                                             root=self.root,
                                             window=window,
                                             same_screen=0,
                                             child=Xlib.X.NONE,
                                             root_x=0,
                                             root_y=0,
                                             event_x=0,
                                             event_y=0,
                                             state=shift_mask,
                                             detail=emulated_key)
        window.send_event(event, propagate=True)

    def openterminal(self):
        """
        This method will open up a terminal on a linux machine. If this application
        is running with root privileges then the terminal will also be given root
        privileges.
        :return:
        """
        subprocess.call("gnome-terminal")

    def getStopPhrase(self):
        """
        When this phrase is typed in the keylogging will stop running
        """
        return "MISCHIEF MANAGED"

    def getTerminalPhrase(self):
        """
        When this phrase is typed in a terminal will be created and this terminal
        will have the same privileges that the key logger is running as.
        """
        return "ROOT"

    def hasInfoToSend(self):
        """
        Determines whether or not there have been keys that have been captured.
        :return: True if there are captured keys otherwise False
        """
        return len(self.capturedKeys) > 0

    def getInfo(self):
        """
        Provides the caller with a string of the captured keys.  It is important
        to note that a call to this method is a mutating call.  This means that
        once the information is retrieved it is purged from this object.
        :return: A string of the captured keys
        """
        ret = ''.join(self.capturedKeys)
        self.capturedKeys = []
        return ret
Example #10
0
class KeyBindingManager(threading.Thread):
	"""
	An Xlib-based global key bindings manager.
	"""
	__metaclass__ = Singleton

	def __init__(self):
		super(KeyBindingManager, self).__init__()
		self.daemon = True
		self.display = Display()
		self.root = self.display.screen().root
		self._binding_map = {}

		self.known_modifiers_mask = 0
		gdk_modifiers = (gtk.gdk.CONTROL_MASK, gtk.gdk.SHIFT_MASK, gtk.gdk.MOD1_MASK,
			gtk.gdk.MOD2_MASK, gtk.gdk.MOD3_MASK, gtk.gdk.MOD4_MASK, gtk.gdk.MOD5_MASK,
			gtk.gdk.SUPER_MASK, gtk.gdk.HYPER_MASK)
		for mod in gdk_modifiers:
			self.known_modifiers_mask |= mod


	def add_binding_from_string(self, binding_string, action, args=(), kwargs={}):
		"""
		Add a key binding from an accelerator string.
		Uses gtk.accelerator_parse to parse the string; according to the docs,
		this is "fairly liberal" and "allows abbreviations such as '<Ctrl>' and '<Ctl>'".
		"""
		print 'Adding', binding_string
		keyval, modifiers = gtk.accelerator_parse(binding_string)
		print modifiers
		action = (action, args, kwargs)
		keycode = gtk.gdk.keymap_get_default().get_entries_for_keyval(keyval)[0][0]
		self._binding_map[(keycode, modifiers)] = action
		self.regrab()

	def grab(self):
		for (keycode, modifiers) in self._binding_map.keys():
			self.root.grab_key(keycode, int(modifiers), True, X.GrabModeAsync, X.GrabModeSync)

	def ungrab(self):
		for (keycode, modifiers) in self._binding_map.keys():
			self.root.ungrab_key(keycode, modifiers, self.root)

	def regrab(self):
		self.ungrab()
		self.grab()


	def _action_idle(self, action):
		gtk.gdk.threads_enter()
		action, args, kwargs = action
		gobject.idle_add(action, args, kwargs)
		gtk.gdk.threads_leave()
		return False

	def run(self):
		self.running = True
		wait_for_release = False
		while self.running:
			event = self.display.next_event()
			if event.type == X.KeyPress and not wait_for_release:
				keycode = event.detail
				modifiers = event.state & self.known_modifiers_mask
				try:
					action = self._binding_map[(keycode, modifiers)]
				except KeyError:
					# This key binding isn't handled by Snappy.
					self.display.allow_events(X.ReplayKeyboard, event.time)
				else:
					# Get the action ready for when the key combo is released
					wait_for_release = True
					self.display.allow_events(X.AsyncKeyboard, event.time)
					self._upcoming_action = (keycode, modifiers, action)

			elif event.type == X.KeyRelease and wait_for_release and event.detail == self._upcoming_action[0]:
				# The user has released the key combo; run the queued action
				wait_for_release = False
				action = self._upcoming_action[2]
				del self._upcoming_action
				gobject.idle_add(self._action_idle, action)
				self.display.allow_events(X.AsyncKeyboard, event.time)

			else:
				self.display.allow_events(X.ReplayKeyboard, event.time)

	def stop(self):
		self.running = False
		self.ungrab()
		self.display.close()
Example #11
0
class GlobalKeyBinding(gobject.GObject, threading.Thread):
    __gsignals__ = {"activate": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())}

    def __init__(self, key):
        gobject.GObject.__init__(self)
        threading.Thread.__init__(self)
        self.setDaemon(True)

        self.key = key

        self.keymap = gtk.gdk.keymap_get_default()
        self.display = Display()
        self.screen = self.display.screen()
        self.root = self.screen.root
        self.e = True
        self.map_modifiers()

    def map_modifiers(self):
        gdk_modifiers = (
            gtk.gdk.CONTROL_MASK,
            gtk.gdk.SHIFT_MASK,
            gtk.gdk.MOD1_MASK,
            gtk.gdk.MOD2_MASK,
            gtk.gdk.MOD3_MASK,
            gtk.gdk.MOD4_MASK,
            gtk.gdk.MOD5_MASK,
            gtk.gdk.SUPER_MASK,
            gtk.gdk.HYPER_MASK,
            gtk.gdk.LOCK_MASK,
        )
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            # Do you know how to handle unknown "Mod*" keys?
            # They are usually Locks and something like that
            if "Mod" not in gtk.accelerator_name(0, modifier):
                self.known_modifiers_mask |= modifier

    def on_key_changed(self, *args):
        self.regrab()

    def regrab(self):
        self.ungrab()
        self.grab()

    def grab(self):

        accelerator = self.key
        keyval, modifiers = gtk.accelerator_parse(accelerator)
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            print "Unable to bind the selected key"
            return
        self.keycode = self.keymap.get_entries_for_keyval(keyval)[0][0]
        self.modifiers = int(modifiers)
        return self.root.grab_key(self.keycode, X.AnyModifier, True, X.GrabModeAsync, X.GrabModeSync)

    def ungrab(self):
        if self.keycode:
            self.root.ungrab_key(self.keycode, X.AnyModifier, self.root)

    def idle(self):
        # Clipboard requests will hang without locking the GDK thread
        gtk.gdk.threads_enter()
        # Workarround to only send signal every 2 times needed by tilo
        if self.e == True:
            self.emit("activate")
            self.e = False
        elif self.e == False:
            self.e = True
        gtk.gdk.threads_leave()
        return False

    def run(self):
        self.running = True
        wait_for_release = False
        while self.running:
            event = self.display.next_event()
            if event.detail == self.keycode and event.type == X.KeyPress and not wait_for_release:
                modifiers = event.state & self.known_modifiers_mask
                if modifiers == self.modifiers:
                    wait_for_release = True
                    self.display.allow_events(X.AsyncKeyboard, event.time)
                else:
                    self.display.allow_events(X.ReplayKeyboard, event.time)
            elif event.detail == self.keycode and wait_for_release:
                if event.type == X.KeyRelease:
                    wait_for_release = False
                    gobject.idle_add(self.idle)
                self.display.allow_events(X.AsyncKeyboard, event.time)
            else:
                self.display.allow_events(X.ReplayKeyboard, event.time)

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()
Example #12
0
class HotKeyListener(gobject.GObject, threading.Thread):
    __gsignals__ = {
            'key-press': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                          (gobject.TYPE_STRING,))
            }

    def __init__(self, keybinds):
        gobject.GObject.__init__(self)
        threading.Thread.__init__(self)
        self.display = Display()
        self.screen = self.display.screen()
        self.root = self.screen.root
        self._mod_mask = get_known_modifiers()
        self._keys = {}
        # Parse and load the keybinds:
        for act, key in keybinds.iteritems():
            km = parse_key(key)
            if km is not None:
                self._keys[km] = act

    def _grab(self):
        for keycode, _ in self._keys.keys():
            self.root.grab_key(keycode, X.AnyModifier, True,
                               X.GrabModeAsync,
                               X.GrabModeSync)

    def _ungrab(self):
        for keycode, _ in self._keys.keys():
            self.root.ungrab_key(keycode, X.AnyModifier, self.root)

    def _emit(self, key):
        gtk.gdk.threads_enter()
        self.emit('key-press', key)
        gtk.gdk.threads_leave()

    def _key_pressed_action(self, keycode, modifiers):
        modifiers &= self._mod_mask
        for km,act in self._keys.iteritems():
            if keycode == km[0] and modifiers == km[1]:
                return act

    def run(self):
        self._running = True
        self._grab()
        while self._running is True:
            # Wait for new events
            select.select([self.display], [], [], 1)
            # Pump events
            while self.display.pending_events() > 0:
                event = self.display.next_event()
                if event.type == X.KeyPress:
                    act = self._key_pressed_action(event.detail, event.state)
                    if act is not None:
                        gobject.idle_add(self._emit, act)
                        self.display.allow_events(X.AsyncKeyboard, event.time)
                    else:
                        self.display.allow_events(X.ReplayKeyboard, event.time)
        self.display.close()

    def stop(self):
        self._ungrab()
        self._running = False
Example #13
0
class PointerMonitor(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
    }

    def __init__(self):
        GObject.GObject.__init__(self)
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.display = Display()
        self.root = self.display.screen().root
        self.windows = []

    # Receives GDK windows
    def addWindowToMonitor(self, window):
        self.windows.append(window)

    def grabPointer(self):
        self.root.grab_button(X.AnyButton, X.AnyModifier, True,
                              X.ButtonPressMask, X.GrabModeSync,
                              X.GrabModeAsync, 0, 0)
        self.display.flush()

    def ungrabPointer(self):
        self.root.ungrab_button(X.AnyButton, X.AnyModifier)
        self.display.flush()

    def idle(self):
        self.emit("activate")
        return False

    def activate(self):
        GLib.idle_add(self.run)

    def run(self):
        self.running = True
        while self.running:
            event = self.display.next_event()
            try:
                if event.type == X.ButtonPress:
                    # Check if pointer is inside monitored windows
                    for w in self.windows:
                        if (Gtk.MAJOR_VERSION, Gtk.MINOR_VERSION) >= (3, 20):
                            pdevice = Gdk.Display.get_default(
                            ).get_default_seat().get_pointer()
                        else:
                            pdevice = Gdk.Display.get_default(
                            ).get_device_manager().get_client_pointer()
                        p = self.get_window().get_device_position(pdevice)
                        g = self.get_size()
                        if p.x >= 0 and p.y >= 0 and p.x <= g.width and p.y <= g.height:
                            break
                    else:
                        # Is outside, so activate
                        GLib.idle_add(self.idle)
                    self.display.allow_events(X.ReplayPointer, event.time)
                else:
                    self.display.allow_events(X.ReplayPointer, X.CurrentTime)
            except Exception as e:
                print "Unexpected error: " + str(e)

    def stop(self):
        self.running = False
        self.root.ungrab_button(X.AnyButton, X.AnyModifier)
        self.display.close()
Example #14
0
# open connection to the x-server
display = Display()

# select root window
root = display.screen().root

# change root window attributes so that it gets notified when key press or key release events occur.
root.change_attributes(event_mask=X.KeyPressMask | X.KeyReleaseMask)

# terminate the program after 10 seconds to prevent freezing. This is useful if you want to modify
# this example without the risk of freezing your whole system permanently.
signal.signal(signal.SIGALRM, lambda a, b: sys.exit(1))
signal.alarm(10)

# grab the 'x' key (key code 53)
root.grab_key(53, 0, True, X.GrabModeSync, X.GrabModeSync)

while 1:

    # get the next event from the input queue. If the queue is empty, this call blocks until
    # there's an event
    event = display.next_event()

    # handle event
    print("pressed" if event.type == 2 else "released")

    # tell the x server that we 'consumed' the event. This call is required because we won't get
    # other events otherwise
    display.allow_events(X.AsyncKeyboard, X.CurrentTime)

Example #15
0
class GlobalKeyBinding (gobject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        }

    def __init__ (self, dir, key):
        gobject.GObject.__init__ (self)
        threading.Thread.__init__ (self)
        self.setDaemon (True)

        self.gconf_key = dir+"/"+key

        self.gconf = gconf.client_get_default ()
        self.gconf.add_dir (dir, gconf.CLIENT_PRELOAD_NONE)
        self.gconf.notify_add (self.gconf_key, self.on_key_changed)

        self.keymap = gtk.gdk.keymap_get_default ()
        self.display = Display ()
        self.screen = self.display.screen ()
        self.root = self.screen.root

        self.map_modifiers ()

    def map_modifiers (self):
        gdk_modifiers = (gtk.gdk.CONTROL_MASK, gtk.gdk.SHIFT_MASK, gtk.gdk.MOD1_MASK,
                         gtk.gdk.MOD2_MASK, gtk.gdk.MOD3_MASK, gtk.gdk.MOD4_MASK, gtk.gdk.MOD5_MASK,
                         gtk.gdk.SUPER_MASK, gtk.gdk.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            # Do you know how to handle unknown "Mod*" keys?
            # They are usually Locks and something like that
            if "Mod" not in gtk.accelerator_name (0, modifier):
                self.known_modifiers_mask |= modifier

    def on_key_changed (self, *args):
        self.regrab ()

    def regrab (self):
        self.ungrab ()
        self.grab ()

    def grab (self):
        accelerator = self.gconf.get_string (self.gconf_key)
        keyval, modifiers = gtk.accelerator_parse (accelerator)
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return
        self.keycode = self.keymap.get_entries_for_keyval(keyval)[0][0]
        self.modifiers = int (modifiers)
        return self.root.grab_key (self.keycode, X.AnyModifier, True, X.GrabModeAsync, X.GrabModeSync)

    def ungrab (self):
        if self.keycode:
            self.root.ungrab_key (self.keycode, X.AnyModifier, self.root)

    def idle (self):
        # Clipboard requests will hang without locking the GDK thread
        gtk.gdk.threads_enter ()
        self.emit ("activate")
        gtk.gdk.threads_leave ()
        return False

    def run (self):
        self.running = True
        wait_for_release = False
        while self.running:
            try:
              event = self.display.next_event ()
              if event.detail == self.keycode and event.type == X.KeyPress and not wait_for_release:
                  modifiers = event.state & self.known_modifiers_mask
                  if modifiers == self.modifiers:
                      wait_for_release = True
                      self.display.allow_events (X.AsyncKeyboard, event.time)
                  else:
                      self.display.allow_events (X.ReplayKeyboard, event.time)
              elif event.detail == self.keycode and wait_for_release:
                  if event.type == X.KeyRelease:
                      wait_for_release = False
                      gobject.idle_add (self.idle)
                  self.display.allow_events (X.AsyncKeyboard, event.time)
              else:
                  self.display.allow_events (X.ReplayKeyboard, event.time)
            except Exception, e:
              print e
class GlobalKeyBinding (gobject.GObject, threading.Thread):
    """
    This is both a GObject and a Thread.
    GObject: it emits the 'active' signal when the key binding is activated
    Thread: runs an X loop for catching X events after the key has been grabbed
    """

    __gsignals__ = {
        'activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
        }

    def __init__ (self, application, key):
        gobject.GObject.__init__ (self)
        threading.Thread.__init__ (self)
        self.setDaemon (True)

        self.application = application
        self.gconf_key = key

        absolute_key = self.application.config.dir+"/"+self.gconf_key
        self.application.config.client.notify_add (absolute_key,
                                                   self.on_key_changed)
        self.keymap = gtk.gdk.keymap_get_default ()
        self.display = Display ()
        self.screen = self.display.screen ()
        self.root = self.screen.root

        self.modifiers = 0
        self.keycode = 0
        self.unknown_combos = []

        self.map_modifiers ()

        self.running = False

    def map_modifiers (self):
        """
        Use only known GTK+ modifiers to avoid catching Lock
        or something like that
        """
        gdk_modifiers = (gtk.gdk.CONTROL_MASK, gtk.gdk.SHIFT_MASK,
                         gtk.gdk.MOD1_MASK,
                         gtk.gdk.MOD2_MASK, gtk.gdk.MOD3_MASK,
                         gtk.gdk.MOD4_MASK, gtk.gdk.MOD5_MASK,
                         gtk.gdk.SUPER_MASK, gtk.gdk.HYPER_MASK)
        unknown = []
        for modifier in gdk_modifiers:
            # Do you know how to handle unknown "Mod*" keys?
            # They are usually Locks and something like that
            if "Mod" in gtk.accelerator_name (0, modifier):
                unknown.append ([modifier])
        combos = self.generate_combos (unknown, unknown, len(unknown))
        self.unknown_combos = self.flatten_combos (combos)

    @staticmethod
    def generate_combos (elems, combos, level):
        if level == 1:
            return combos
        res = []
        for el in elems:
            for c in combos:
                res.append (el+c)
        return GlobalKeyBinding.generate_combos (elems, res, level-1)

    @staticmethod
    def flatten_combos (combos):
        ored = map (lambda l: reduce (lambda x, y: x | y, l), combos)
        ored.append (0)
        return set (ored)

    def on_key_changed (self, *args):
        """
        Called from GConf when the key binding changes its value.
        Will regrab the key.
        """
        self.regrab ()

    def regrab (self):
        """
        Ungrab the grab the key
        """
        self.ungrab ()
        self.grab ()

    def grab (self):
        """
        Grab the key for the X display.
        This means we will listen only to X events having our key
        as keycode.
        Instead of grabbing all the possible key combo (including Locks)
        we listen to the keycode with any modifier then filter manually
        the events in the loop.
        The key is grabbed in Sync mode.
        """
        accelerator = self.application.config.get (self.gconf_key)
        keyval, modifiers = gtk.accelerator_parse (accelerator)
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return
        self.keycode = self.keymap.get_entries_for_keyval(keyval)[0][0]
        self.modifiers = int (modifiers)
        for combo in self.unknown_combos:
            self.root.grab_key (self.keycode, self.modifiers | combo, True,
                                X.GrabModeAsync, X.GrabModeSync)

    def ungrab (self):
        """
        Ungrab the key binding
        """
        if self.keycode:
            for combo in self.unknown_combos:
                self.root.ungrab_key (self.keycode, self.modifiers | combo, self.root)
        
    def idle (self):
        """
        Internally called to emit the 'activate' event.
        This method will be run as idle for the gobject mainloop
        """
        # Clipboard requests will hang without locking the GDK thread
        gtk.gdk.threads_enter ()
        self.emit ("activate")
        gtk.gdk.threads_leave ()
        return False

    def run (self):
        """
        We grab in Sync mode because with Async with loose the
        release event someway.
        The loop will run until self.running is True.
        """
        self.running = True
        while self.running:
            event = self.display.next_event ()
            self.display.allow_events (X.AsyncKeyboard, event.time)
            if event.type == X.KeyRelease:
                gobject.idle_add (self.idle)

    def stop (self):
        """
        Stop the loop, ungrab the key and close the display
        """
        self.running = False
        self.ungrab ()
        self.display.close ()
Example #17
0
class GlobalKeyBinding(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
    }

    def __init__(self):
        try:
            GObject.GObject.__init__(self)
            threading.Thread.__init__(self)
            self.setDaemon(True)

            self.keymap = Gdk.Keymap().get_default()
            self.display = Display()
            self.screen = self.display.screen()
            self.window = self.screen.root
            self.showscreen = Wnck.Screen.get_default()
            self.ignored_masks = self.get_mask_combinations(X.LockMask
                                                            | X.Mod2Mask
                                                            | X.Mod5Mask)
            self.map_modifiers()
            self.raw_keyval = None
            self.keytext = ""
        except Exception as cause:
            print(("init keybinding error: \n", str(cause)))
            self.display = None
            return None

    def is_hotkey(self, key, modifier):
        keymatch = False
        modmatch = False
        modifier = modifier & ~Gdk.ModifierType.SUPER_MASK
        modint = int(modifier)
        if self.get_keycode(key) == self.keycode or self.get_keycode(
                key) == 134:
            keymatch = True
        for ignored_mask in self.ignored_masks:
            if self.modifiers | ignored_mask == modint | ignored_mask:
                modmatch = True
                break
        return keymatch and modmatch

    def map_modifiers(self):
        gdk_modifiers = (Gdk.ModifierType.CONTROL_MASK,
                         Gdk.ModifierType.SHIFT_MASK,
                         Gdk.ModifierType.MOD1_MASK,
                         Gdk.ModifierType.MOD2_MASK,
                         Gdk.ModifierType.MOD3_MASK,
                         Gdk.ModifierType.MOD4_MASK,
                         Gdk.ModifierType.MOD5_MASK,
                         Gdk.ModifierType.SUPER_MASK,
                         Gdk.ModifierType.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            if "Mod" not in Gtk.accelerator_name(
                    0, modifier) or "Mod4" in Gtk.accelerator_name(
                        0, modifier):
                self.known_modifiers_mask |= modifier

    def get_keycode(self, keyval):
        return self.keymap.get_entries_for_keyval(keyval).keys[0].keycode

    def grab(self, key):
        if self.display == None:
            return False
        accelerator = key
        accelerator = accelerator.replace("<Super>", "<Mod4>")
        keyval, modifiers = Gtk.accelerator_parse(accelerator)
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return False

        self.keytext = key
        self.keycode = self.get_keycode(keyval)
        self.modifiers = int(modifiers)

        catch = error.CatchError(error.BadAccess)
        for ignored_mask in self.ignored_masks:
            mod = modifiers | ignored_mask
            result = self.window.grab_key(self.keycode,
                                          mod,
                                          True,
                                          X.GrabModeAsync,
                                          X.GrabModeSync,
                                          onerror=catch)
            result = self.window.grab_key(134,
                                          mod,
                                          True,
                                          X.GrabModeAsync,
                                          X.GrabModeSync,
                                          onerror=catch)
        self.display.flush()
        # sync has been blocking. Don't know why.
        #self.display.sync()
        if catch.get_error():
            return False
        return True

    def ungrab(self):
        if self.display == None:
            return
        if self.keycode:
            self.window.ungrab_key(self.keycode, X.AnyModifier, self.window)
            self.window.ungrab_key(134, X.AnyModifier, self.window)

    def rebind(self, key):
        self.ungrab()
        if key != "":
            self.grab(key)
        else:
            self.keytext = ""

    def set_focus_window(self, window=None):
        if self.display == None:
            return
        self.ungrab()
        if window is None:
            self.window = self.screen.root
        else:
            self.window = self.display.create_resource_object(
                "window", window.get_xid())
        self.grab(self.keytext)

    def get_mask_combinations(self, mask):
        return [x for x in range(mask + 1) if not (x & ~mask)]

    def idle(self):
        self.emit("activate")
        return False

    def activate(self):
        GLib.idle_add(self.run)

    def run(self):
        if self.display == None:
            return
        self.running = True
        wait_for_release = False
        showdesktop = True
        while self.running:
            event = self.display.next_event()
            try:
                self.current_event_time = event.time
                if (event.detail == self.keycode and event.type == X.KeyPress
                        and not wait_for_release) or (
                            event.detail == 134 and event.type == X.KeyPress
                            and not wait_for_release):
                    modifiers = event.state & self.known_modifiers_mask
                    if modifiers == self.modifiers:
                        wait_for_release = True
                        self.display.allow_events(X.SyncKeyboard, event.time)
                    else:
                        self.display.allow_events(X.ReplayKeyboard, event.time)
                elif (event.detail == self.keycode
                      and wait_for_release) or (event.detail == 134
                                                and wait_for_release):
                    if event.type == X.KeyRelease:
                        wait_for_release = False
                        GLib.idle_add(self.idle)
                    self.display.allow_events(X.SyncKeyboard, event.time)
                elif event.detail == 40 and event.type == X.KeyPress:  #super+d
                    self.display.allow_events(X.SyncKeyboard, event.time)
                elif event.detail == 40 and event.type == X.KeyRelease:  #super+d
                    if showdesktop:
                        self.showscreen.toggle_showing_desktop(True)
                        showdesktop = False
                    else:
                        self.showscreen.toggle_showing_desktop(False)
                        showdesktop = True
                    self.display.allow_events(X.ReplayKeyboard, event.time)
                elif event.detail == 33 and event.type == X.KeyPress:  #super+p
                    self.display.allow_events(X.SyncKeyboard, event.time)
                elif event.detail == 33 and event.type == X.KeyRelease:  #super+p
                    self.display.allow_events(X.ReplayKeyboard, event.time)
                elif event.detail == 26 and event.type == X.KeyPress:  #super+e
                    self.display.allow_events(X.SyncKeyboard, event.time)
                elif event.detail == 26 and event.type == X.KeyRelease:  #super+e
                    os.system("peony &")
                    self.display.allow_events(X.ReplayKeyboard, event.time)
                else:
                    self.display.allow_events(X.ReplayKeyboard, event.time)
            except AttributeError:
                continue

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()
class GlobalKeyBinding(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SIGNAL_RUN_LAST, None, ()),
    }

    def __init__(self):
        GObject.GObject.__init__(self)
        threading.Thread.__init__(self)
        self.setDaemon(True)

        self.keymap = Gdk.Keymap.get_default()
        self.display = Display()
        self.screen = self.display.screen()
        self.root = self.screen.root
        self.map_modifiers()

    def map_modifiers(self):
        gdk_modifiers = (Gdk.ModifierType.CONTROL_MASK,
                         Gdk.ModifierType.SHIFT_MASK,
                         Gdk.ModifierType.MOD1_MASK,
                         Gdk.ModifierType.MOD2_MASK,
                         Gdk.ModifierType.MOD3_MASK,
                         Gdk.ModifierType.MOD4_MASK,
                         Gdk.ModifierType.MOD5_MASK,
                         Gdk.ModifierType.SUPER_MASK,
                         Gdk.ModifierType.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            # Do you know how to handle unknown "Mod*" keys?
            # They are usually Locks and something like that
            if "Mod" not in Gtk.accelerator_name(0, modifier):
                self.known_modifiers_mask |= modifier

    def grab(self):
        Gdk.threads_enter()
        accelerator = ConfigManager.get_conf('global-key')
        Gdk.threads_leave()
        keyval, modifiers = Gtk.accelerator_parse(accelerator)
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return

        self.keycode = self.keymap.get_entries_for_keyval(keyval)[1][0].keycode
        self.modifiers = int(modifiers)

        catch = error.CatchError(error.BadAccess)
        self.root.grab_key(self.keycode,
                           X.AnyModifier,
                           True,
                           X.GrabModeAsync,
                           X.GrabModeSync,
                           onerror=catch)
        self.display.sync()
        if catch.get_error():
            return False
        return True

    def ungrab(self):
        if self.keycode:
            self.root.ungrab_key(self.keycode, X.AnyModifier, self.root)

    def idle(self):
        Gdk.threads_enter()
        self.emit("activate")
        Gdk.threads_leave()
        return False

    def run(self):
        self.running = True
        wait_for_release = False
        while self.running:
            event = self.display.next_event()
            self.current_event_time = event.time
            if event.detail == self.keycode and event.type == X.KeyPress and not wait_for_release:
                modifiers = event.state & self.known_modifiers_mask
                if modifiers == self.modifiers:
                    wait_for_release = True
                    self.display.allow_events(X.AsyncKeyboard, event.time)
                else:
                    self.display.allow_events(X.ReplayKeyboard, event.time)
            elif event.detail == self.keycode and wait_for_release:
                if event.type == X.KeyRelease:
                    wait_for_release = False
                    GObject.idle_add(self.idle)
                self.display.allow_events(X.AsyncKeyboard, event.time)
            else:
                self.display.allow_events(X.ReplayKeyboard, event.time)

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()
Example #19
0
class GlobalKeyBinding(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
        }

    def __init__(self):
        GObject.GObject.__init__(self)
        threading.Thread.__init__(self)
        self.setDaemon(True)

        self.keymap = capi.get_widget (gdk.gdk_keymap_get_default())
        self.display = Display()
        self.screen = self.display.screen()
        self.root = self.screen.root
        self.ignored_masks = self.get_mask_combinations(X.LockMask | X.Mod2Mask | X.Mod5Mask)
        self.map_modifiers()

    def map_modifiers(self):
        gdk_modifiers =(Gdk.ModifierType.CONTROL_MASK, Gdk.ModifierType.SHIFT_MASK, Gdk.ModifierType.MOD1_MASK,
                         Gdk.ModifierType.MOD2_MASK, Gdk.ModifierType.MOD3_MASK, Gdk.ModifierType.MOD4_MASK, Gdk.ModifierType.MOD5_MASK,
                         Gdk.ModifierType.SUPER_MASK, Gdk.ModifierType.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            if "Mod" not in Gtk.accelerator_name(0, modifier):
                self.known_modifiers_mask |= modifier

    def grab(self, key):
        Gdk.threads_enter()
        accelerator = key
        Gdk.threads_leave()
        keyval, modifiers = Gtk.accelerator_parse(accelerator)
        print keyval, modifiers
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return False
        count = c_int()
        keys = KeymapKey * 10
        gdk.gdk_keymap_get_entries_for_keyval(hash(self.keymap), keyval, byref(keys), byref(count))
        self.keycode =  keys[0].keycode
        self.modifiers = int(modifiers)

        catch = error.CatchError(error.BadAccess)
        for ignored_mask in self.ignored_masks:
            mod = modifiers | ignored_mask
            result = self.root.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeSync, onerror=catch)
        self.display.sync()
        if catch.get_error():
            return False
        return True

    def ungrab(self, key):
        if self.keycode:
            self.root.ungrab_key(self.keycode, X.AnyModifier, self.root)

    def get_mask_combinations(self, mask):
        return [x for x in xrange(mask+1) if not (x & ~mask)]

    def idle(self):
        # Gdk.threads_enter()
        self.emit("activate")
        # Gdk.threads_leave()
        return False

    def run(self):
        self.running = True
        wait_for_release = False
        while self.running:
            event = self.display.next_event()
            self.current_event_time = event.time
            if event.detail == self.keycode and event.type == X.KeyPress and not wait_for_release:
                modifiers = event.state & self.known_modifiers_mask
                if modifiers == self.modifiers:
                    wait_for_release = True
                    self.display.allow_events(X.AsyncKeyboard, event.time)
                else:
                    self.display.allow_events(X.ReplayKeyboard, event.time)
            elif event.detail == self.keycode and wait_for_release:
                if event.type == X.KeyRelease:
                    wait_for_release = False
                    GLib.idle_add(self.idle)
                self.display.allow_events(X.AsyncKeyboard, event.time)
            else:
                self.display.allow_events(X.ReplayKeyboard, event.time)

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()
Example #20
0
class mwsd:
    def __init__(self, args):

        self.verbose = args.verbose
        self.ip = "localhost"
        self.port = args.port
        self.ignore = args.ignore

        self.disp = Display()
        self.screen = self.disp.screen()
        self.root = self.screen.root

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.setup_socket()

        self.ids = []
        self.windows = []

        self.status = False
        self.running = True

        self.lock = threading.Lock()

# Communication to daemon

    def setup_socket(self):
        #        self.socket.setblocking(False)
        self.socket.bind((self.ip, self.port))
        self.socket.listen(1)

        # Running the server in a other thread
        self.running = True
        self.thread = threading.Thread(target=self.server_listen)
        self.thread.daemon = True
        self.thread.start()

    def server_listen(self):
        while self.running is True:

            connection, client_address = self.socket.accept()

            try:
                msg = ""
                while True:
                    data = connection.recv(16)

                    if data:
                        msg += data.decode()
                    else:
                        break

                if msg != "":
                    msg_list = msg.split()

                    if self.verbose is True:
                        print(msg)

                    if msg_list[0] == "add":
                        for id in msg_list[1:]:
                            self.add(int(id))
                        connection.sendall("done".encode())
                    elif msg_list[0] == "rm":
                        for id in msg_list[1:]:
                            self.rm(int(id))
                        connection.sendall("done".encode())
                    elif msg_list[0] == "clear":
                        self.clear()
                    elif msg_list[0] == "active":
                        self.active()
                    elif msg_list[0] == "deactive":
                        self.deactive()
                    elif msg_list[0] == "toggle":
                        if self.status is True:
                            self.active()
                        else:
                            self.deactive()
                    elif msg_list[0] == "stop":
                        self.terminate()
                    else:
                        print("Unknown command")
                        connection.sendall("UnknownCommand".encode())

            finally:
                connection.close()

# Actions

    def add(self, id: int):
        self.lock.acquire(blocking=True)
        self.ids.append(id)
        self.windows.append(self.disp.create_resource_object('window', id))
        self.grab(self.windows[-1])
        self.lock.release()

    def rm(self, id: int):
        self.lock.acquire(blocking=True)

        index = self.ids.index(id)
        self.ids.remove(id)
        self.windows.remove(self.windows[index])

        self.lock.release()

    def clear(self):
        self.lock.acquire(blocking=True)

        self.windows.clear()
        self.ids.clear()

        self.lock.release()

    def active(self):
        self.status = True

    def deactive(self):
        self.status = False

    def terminate(self):
        self.running = False

# Daemon main function

    def listen(self):
        while self.running:
            # X11
            if len(self.windows) != 0 and len(self.ids) != 0:
                evt = self.disp.next_event()
                if evt.type in [X.KeyPress]:
                    keycode = evt.detail
                    if self.verbose is True:
                        print("Keycode:", keycode)

                    self.disp.allow_events(X.ReplayKeyboard, X.CurrentTime)
                    if self.status is True:
                        for window in self.windows:
                            self.press(window, keycode, evt.state)
                    else:
                        index = self.ids.index(evt.window.id)
                        self.press(self.windows[index], keycode, evt.state)

                if evt.type == X.DestroyNotify:
                    try:
                        self.rm(evt.window.id)
                    except ValueError:
                        pass

# X11

    def event(self, name, window, detail, state):
        return name(time=X.CurrentTime,
                    root=self.root,
                    window=window,
                    same_screen=0,
                    child=Xlib.X.NONE,
                    root_x=0,
                    root_y=0,
                    event_x=0,
                    event_y=0,
                    state=state,
                    detail=detail)

    def press(self, window, keycode, mask=X.NONE):
        window.send_event(self.event(event.KeyPress, window, keycode, mask),
                          propagate=True)
        window.send_event(self.event(event.KeyRelease, window, keycode, mask),
                          propagate=True)
        self.disp.flush()
        self.disp.sync()

    def grab(self, window):
        window.grab_key(X.AnyKey, X.AnyModifier, True, X.GrabModeAsync,
                        X.GrabModeAsync)

        # Ungrab window manager shortcuts (Super + ...)
        for key in self.ignore:
            window.ungrab_key(key, X.AnyModifier, True)

        window.change_attributes(event_mask=X.KeyReleaseMask | X.KeyPressMask
                                 | X.StructureNotifyMask)

    def ungrab(self, window):
        window.ungrab_key(X.AnyKey, X.AnyModifier, True)


# Cleanup

    def cleanup(self):
        self.running = False
Example #21
0
class GlobalKeyBinding(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
    }

    def __init__(self):
        GObject.GObject.__init__(self)
        threading.Thread.__init__(self)
        self.setDaemon(True)

        self.keymap = capi.get_widget(gdk.gdk_keymap_get_default())
        self.display = Display()
        self.screen = self.display.screen()
        self.window = self.screen.root
        self.ignored_masks = self.get_mask_combinations(X.LockMask | X.Mod2Mask
                                                        | X.Mod5Mask)
        self.map_modifiers()
        self.raw_keyval = None
        self.keytext = ""

    def is_hotkey(self, key, modifier):
        keymatch = False
        modmatch = False
        modifier = modifier & ~Gdk.ModifierType.SUPER_MASK
        modint = int(modifier)
        if self.get_keycode(key) == self.keycode:
            keymatch = True
        for ignored_mask in self.ignored_masks:
            if self.modifiers | ignored_mask == modint | ignored_mask:
                modmatch = True
                break
        return keymatch and modmatch

    def map_modifiers(self):
        gdk_modifiers = (Gdk.ModifierType.CONTROL_MASK,
                         Gdk.ModifierType.SHIFT_MASK,
                         Gdk.ModifierType.MOD1_MASK,
                         Gdk.ModifierType.MOD2_MASK,
                         Gdk.ModifierType.MOD3_MASK,
                         Gdk.ModifierType.MOD4_MASK,
                         Gdk.ModifierType.MOD5_MASK,
                         Gdk.ModifierType.SUPER_MASK,
                         Gdk.ModifierType.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            if "Mod" not in Gtk.accelerator_name(
                    0, modifier) or "Mod4" in Gtk.accelerator_name(
                        0, modifier):
                self.known_modifiers_mask |= modifier

    def get_keycode(self, keyval):
        count = c_int()
        array = (KeymapKey * 10)()
        keys = cast(array, POINTER(KeymapKey))
        gdk.gdk_keymap_get_entries_for_keyval(hash(self.keymap), keyval,
                                              byref(keys), byref(count))
        return keys[0].keycode

    def grab(self, key):
        accelerator = key
        accelerator = accelerator.replace("<Super>", "<Mod4>")
        keyval, modifiers = Gtk.accelerator_parse(accelerator)
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return False

        self.keytext = key
        self.keycode = self.get_keycode(keyval)
        self.modifiers = int(modifiers)

        catch = error.CatchError(error.BadAccess)
        for ignored_mask in self.ignored_masks:
            mod = modifiers | ignored_mask
            result = self.window.grab_key(self.keycode,
                                          mod,
                                          True,
                                          X.GrabModeAsync,
                                          X.GrabModeSync,
                                          onerror=catch)
        self.display.flush()
        # sync has been blocking. Don't know why.
        #self.display.sync()
        if catch.get_error():
            return False
        return True

    def ungrab(self):
        if self.keycode:
            self.window.ungrab_key(self.keycode, X.AnyModifier, self.window)

    def rebind(self, key):
        self.ungrab()
        if key != "":
            self.grab(key)
        else:
            self.keytext = ""

    def set_focus_window(self, window=None):
        self.ungrab()
        if window is None:
            self.window = self.screen.root
        else:
            self.window = self.display.create_resource_object(
                "window", gdk.gdk_x11_drawable_get_xid(hash(window)))
        self.grab(self.keytext)

    def get_mask_combinations(self, mask):
        return [x for x in xrange(mask + 1) if not (x & ~mask)]

    def idle(self):
        self.emit("activate")
        return False

    def activate(self):
        GLib.idle_add(self.run)

    def run(self):
        self.running = True
        wait_for_release = False
        while self.running:
            event = self.display.next_event()
            try:
                self.current_event_time = event.time
                if event.detail == self.keycode and event.type == X.KeyPress and not wait_for_release:
                    modifiers = event.state & self.known_modifiers_mask
                    if modifiers == self.modifiers:
                        wait_for_release = True
                        self.display.allow_events(X.AsyncKeyboard, event.time)
                    else:
                        self.display.allow_events(X.ReplayKeyboard, event.time)
                elif event.detail == self.keycode and wait_for_release:
                    if event.type == X.KeyRelease:
                        wait_for_release = False
                        GLib.idle_add(self.idle)
                    self.display.allow_events(X.AsyncKeyboard, event.time)
                else:
                    self.display.allow_events(X.ReplayKeyboard, event.time)
            except AttributeError:
                continue

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()
Example #22
0
class Manager():
    def __init__(self, inkscape_id):
        self.id = inkscape_id
        self.disp = Display()
        self.screen = self.disp.screen()
        self.root = self.screen.root

        self.inkscape = self.disp.create_resource_object('window', inkscape_id)
        self.mode = normal_mode

    def event(self, name, detail, state):
        return name(time=X.CurrentTime,
                    root=self.root,
                    window=self.inkscape,
                    same_screen=0,
                    child=Xlib.X.NONE,
                    root_x=0,
                    root_y=0,
                    event_x=0,
                    event_y=0,
                    state=state,
                    detail=detail)

    def string_to_keycode(self, key):
        keysym = XK.string_to_keysym(key)
        keycode = self.disp.keysym_to_keycode(keysym)
        return keycode

    def press(self, key, mask=X.NONE):
        keycode = self.string_to_keycode(key)
        self.inkscape.send_event(self.event(event.KeyPress, keycode, mask),
                                 propagate=True)
        self.inkscape.send_event(self.event(event.KeyRelease, keycode, mask),
                                 propagate=True)
        self.disp.flush()
        self.disp.sync()

    def grab(self):
        self.inkscape.grab_key(X.AnyKey, X.AnyModifier, True, X.GrabModeAsync,
                               X.GrabModeAsync)

        # Ungrab window manager shortcuts (Super + ...)
        self.inkscape.ungrab_key(self.string_to_keycode('Super'),
                                 X.AnyModifier, True)
        self.inkscape.ungrab_key(self.string_to_keycode('Alt_L'),
                                 X.AnyModifier, True)
        self.inkscape.ungrab_key(self.string_to_keycode('Shift_R'),
                                 X.AnyModifier, True)
        self.inkscape.change_attributes(event_mask=X.KeyReleaseMask
                                        | X.KeyPressMask
                                        | X.StructureNotifyMask)

    def ungrab(self):
        self.inkscape.ungrab_key(X.AnyKey, X.AnyModifier, True)

    def listen(self):
        self.grab()
        while True:
            evt = self.disp.next_event()
            if evt.type in [X.KeyPress, X.KeyRelease]:
                keycode = evt.detail
                keysym = self.disp.keycode_to_keysym(keycode, 0)
                char = XK.keysym_to_string(keysym)
                self.disp.allow_events(X.ReplayKeyboard, X.CurrentTime)

                self.mode(self, evt, char)

            if evt.type == X.DestroyNotify:
                if evt.window.id == self.id:
                    self.ungrab()
                    return
Example #23
0
class PointerMonitor(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
    }

    def __init__(self):
        GObject.GObject.__init__ (self)
        threading.Thread.__init__ (self)
        self.setDaemon (True)
        self.display = Display()
        self.root = self.display.screen().root
        self.windows = []

    # Receives GDK windows
    def addWindowToMonitor(self, window):
        self.windows.append(window)

    def grabPointer(self):
        self.root.grab_button(X.AnyButton, X.AnyModifier, True, X.ButtonPressMask, X.GrabModeSync, X.GrabModeAsync, 0, 0)
        self.display.flush()

    def ungrabPointer(self):
        self.root.ungrab_button(X.AnyButton, X.AnyModifier)
        self.display.flush()

    def idle(self):
        self.emit("activate")
        return False

    def activate(self):
        GLib.idle_add(self.run)

    def run(self):
        self.running = True
        while self.running:
            event = self.display.next_event()
            try:
                if event.type == X.ButtonPress:
                    # Check if pointer is inside monitored windows
                    for w in self.windows:
                        if Gtk.check_version (3, 20, 0) is None:
                            pdevice = Gdk.Display.get_default().get_default_seat().get_pointer()
                        else:
                            pdevice = Gdk.Display.get_default().get_device_manager().get_client_pointer()
                        p = self.get_window().get_device_position(pdevice)
                        g = self.get_size()

                        if p.x >= 0 and p.y >= 0 and p.x <= g.width and p.y <= g.height:
                            break
                    else:
                        # Is outside, so activate
                        GLib.idle_add(self.idle)
                    self.display.allow_events(X.ReplayPointer, event.time)
                else:
                    self.display.allow_events(X.ReplayPointer, X.CurrentTime)
            except Exception as e:
                print "Unexpected error: " + str(e)

    def stop(self):
        self.running = False
        self.root.ungrab_button(X.AnyButton, X.AnyModifier)
        self.display.close()
Example #24
0
class GlobalKeyBinding(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
    }

    def __init__(self):
        GObject.GObject.__init__ (self)
        threading.Thread.__init__ (self)
        self.setDaemon (True)

        self.keymap = Gdk.Keymap().get_default()
        self.display = Display()
        self.screen = self.display.screen()
        self.window = self.screen.root
        self.ignored_masks = self.get_mask_combinations(X.LockMask | X.Mod2Mask | X.Mod5Mask)
        self.map_modifiers()
        self.raw_keyval = None
        self.keytext = ""

    def map_modifiers(self):
        gdk_modifiers =(Gdk.ModifierType.CONTROL_MASK, Gdk.ModifierType.SHIFT_MASK, Gdk.ModifierType.MOD1_MASK,
                        Gdk.ModifierType.MOD2_MASK, Gdk.ModifierType.MOD3_MASK, Gdk.ModifierType.MOD4_MASK, Gdk.ModifierType.MOD5_MASK,
                        Gdk.ModifierType.SUPER_MASK, Gdk.ModifierType.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            if "Mod" not in Gtk.accelerator_name(0, modifier) or "Mod4" in Gtk.accelerator_name(0, modifier):
                self.known_modifiers_mask |= modifier

    def grab(self, key):
        accelerator = key
        accelerator = accelerator.replace("<Super>", "<Mod4>")
        keyval, modifiers = Gtk.accelerator_parse(accelerator)
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return False

        self.keytext = key
        try:
            self.keycode = self.keymap.get_entries_for_keyval(keyval).keys[0].keycode
        except:
            # In Betsy, the get_entries_for_keyval() returns an unamed tuple...
            self.keycode = self.keymap.get_entries_for_keyval(keyval)[1][0].keycode
        self.modifiers = int(modifiers)

        catch = error.CatchError(error.BadAccess)
        for ignored_mask in self.ignored_masks:
            mod = modifiers | ignored_mask
            result = self.window.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeAsync, onerror=catch)
        self.display.flush()
        # sync has been blocking. Don't know why.
        #self.display.sync()
        if catch.get_error():
            return False
        return True

    def ungrab(self):
        if self.keycode:
            self.window.ungrab_key(self.keycode, X.AnyModifier, self.window)

    def rebind(self, key):
        self.ungrab()
        if key != "":
            self.grab(key)
        else:
            self.keytext = ""

    def set_focus_window(self, window = None):
        self.ungrab()
        if window is None:
            self.window = self.screen.root
        else:
            self.window = self.display.create_resource_object("window", window.get_xid())
        self.grab(self.keytext)

    def get_mask_combinations(self, mask):
        return [x for x in xrange(mask+1) if not (x & ~mask)]

    def idle(self):
        self.emit("activate")
        return False

    def activate(self):
        GLib.idle_add(self.run)

    def run(self):
        self.running = True
        wait_for_release = False
        while self.running:
            event = self.display.next_event()
            try:
                self.current_event_time = event.time
                if event.detail == self.keycode and event.type == X.KeyPress and not wait_for_release:
                    modifiers = event.state & self.known_modifiers_mask
                    if modifiers == self.modifiers:
                        wait_for_release = True
                        self.display.allow_events(X.AsyncKeyboard, event.time)
                    else:
                        self.display.allow_events(X.ReplayKeyboard, event.time)
                elif event.detail == self.keycode and wait_for_release:
                    if event.type == X.KeyRelease:
                        wait_for_release = False
                        GLib.idle_add(self.idle)
                    self.display.allow_events(X.AsyncKeyboard, event.time)
                else:
                    self.display.send_event(self.window, event, X.KeyPressMask | X.KeyReleaseMask, True)
                    self.display.allow_events(X.ReplayKeyboard, event.time)
                    wait_for_release = False
            except AttributeError:
                continue

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()
class GlobalKeyBinding(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate':(GObject.SIGNAL_RUN_LAST, None,()),
        }

    def __init__(self):
        GObject.GObject.__init__(self)
        threading.Thread.__init__(self)
        self.setDaemon(True)
        
        self.keymap = Gdk.Keymap.get_default()
        self.display = Display()
        self.screen = self.display.screen()
        self.root = self.screen.root
        self.map_modifiers()

    def map_modifiers(self):
        gdk_modifiers =(Gdk.ModifierType.CONTROL_MASK, Gdk.ModifierType.SHIFT_MASK, Gdk.ModifierType.MOD1_MASK,
                         Gdk.ModifierType.MOD2_MASK, Gdk.ModifierType.MOD3_MASK, Gdk.ModifierType.MOD4_MASK, Gdk.ModifierType.MOD5_MASK,
                         Gdk.ModifierType.SUPER_MASK, Gdk.ModifierType.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            # Do you know how to handle unknown "Mod*" keys?
            # They are usually Locks and something like that
            if "Mod" not in Gtk.accelerator_name(0, modifier):
                self.known_modifiers_mask |= modifier

    def grab(self):
        Gdk.threads_enter()
        accelerator = ConfigManager.get_conf('global-key')
        Gdk.threads_leave()
        keyval, modifiers = Gtk.accelerator_parse(accelerator)
        if not accelerator or(not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return

        self.keycode= self.keymap.get_entries_for_keyval(keyval)[1][0].keycode
        self.modifiers = int(modifiers)

        catch = error.CatchError(error.BadAccess)
        self.root.grab_key(self.keycode, X.AnyModifier, True, X.GrabModeAsync, X.GrabModeSync,onerror=catch)
        self.display.sync()
        if catch.get_error():
            return False
        return True
        
    def ungrab(self):
        if self.keycode:
            self.root.ungrab_key(self.keycode, X.AnyModifier, self.root)
        
    def idle(self):
        Gdk.threads_enter()
        self.emit("activate")
        Gdk.threads_leave()
        return False

    def run(self):
        self.running = True
        wait_for_release = False
        while self.running:
            event = self.display.next_event()
            self.current_event_time = event.time
            if event.detail == self.keycode and event.type == X.KeyPress and not wait_for_release:
                modifiers = event.state & self.known_modifiers_mask
                if modifiers == self.modifiers:
                    wait_for_release = True
                    self.display.allow_events(X.AsyncKeyboard, event.time)
                else:
                    self.display.allow_events(X.ReplayKeyboard, event.time)
            elif event.detail == self.keycode and wait_for_release:
                if event.type == X.KeyRelease:
                    wait_for_release = False
                    GObject.idle_add(self.idle)
                self.display.allow_events(X.AsyncKeyboard, event.time)
            else:
                self.display.allow_events(X.ReplayKeyboard, event.time)

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()
Example #26
0
class GlobalKeyBinding(GObject.GObject, threading.Thread):
    __gsignals__ = {
        'activate': (GObject.SignalFlags.RUN_LAST, None, ()),
    }

    def __init__(self):
        GObject.GObject.__init__(self)
        threading.Thread.__init__(self)
        self.setDaemon(True)

        self.keymap = Gdk.Keymap().get_default()
        self.display = Display()
        self.screen = self.display.screen()
        self.window = self.screen.root
        self.ignored_masks = self.get_mask_combinations(X.LockMask | X.Mod2Mask
                                                        | X.Mod5Mask)
        self.map_modifiers()
        self.raw_keyval = None
        self.keytext = ""

    def map_modifiers(self):
        gdk_modifiers = (Gdk.ModifierType.CONTROL_MASK,
                         Gdk.ModifierType.SHIFT_MASK,
                         Gdk.ModifierType.MOD1_MASK,
                         Gdk.ModifierType.MOD2_MASK,
                         Gdk.ModifierType.MOD3_MASK,
                         Gdk.ModifierType.MOD4_MASK,
                         Gdk.ModifierType.MOD5_MASK,
                         Gdk.ModifierType.SUPER_MASK,
                         Gdk.ModifierType.HYPER_MASK)
        self.known_modifiers_mask = 0
        for modifier in gdk_modifiers:
            if "Mod" not in Gtk.accelerator_name(
                    0, modifier) or "Mod4" in Gtk.accelerator_name(
                        0, modifier):
                self.known_modifiers_mask |= modifier

    def grab(self, key):
        accelerator = key
        accelerator = accelerator.replace("<Super>", "<Mod4>")
        keyval, modifiers = Gtk.accelerator_parse(accelerator)
        if not accelerator or (not keyval and not modifiers):
            self.keycode = None
            self.modifiers = None
            return False

        self.keytext = key
        try:
            self.keycode = self.keymap.get_entries_for_keyval(
                keyval).keys[0].keycode
        except AttributeError:
            # In older Gtk3 the get_entries_for_keyval() returns an unnamed tuple...
            self.keycode = self.keymap.get_entries_for_keyval(
                keyval)[1][0].keycode
        self.modifiers = int(modifiers)

        # Request to receive key press/release reports from other windows that may not be using modifiers
        catch = error.CatchError(error.BadWindow)
        if self.modifiers:
            self.window.change_attributes(onerror=catch,
                                          event_mask=X.KeyPressMask
                                          | X.KeyReleaseMask)
        else:
            self.window.change_attributes(onerror=catch,
                                          event_mask=X.NoEventMask)
        if catch.get_error():
            return False

        catch = error.CatchError(error.BadAccess)
        for ignored_mask in self.ignored_masks:
            mod = modifiers | ignored_mask
            result = self.window.grab_key(self.keycode,
                                          mod,
                                          True,
                                          X.GrabModeAsync,
                                          X.GrabModeAsync,
                                          onerror=catch)
        self.display.flush()
        if catch.get_error():
            return False

        catch = error.CatchError(error.BadCursor)
        if not self.modifiers:
            # We grab Super+click so that we can forward it to the window manager and allow Super+click bindings (window move, resize, etc.)
            self.window.grab_button(X.AnyButton, X.Mod4Mask, True,
                                    X.ButtonPressMask, X.GrabModeSync,
                                    X.GrabModeAsync, X.NONE, X.NONE)
        self.display.flush()
        if catch.get_error():
            return False

        return True

    def ungrab(self):
        if self.keycode:
            self.window.ungrab_key(self.keycode, X.AnyModifier, self.window)

    def rebind(self, key):
        self.ungrab()
        if key != "":
            self.grab(key)
        else:
            self.keytext = ""

    def set_focus_window(self, window=None):
        self.ungrab()
        if window is None:
            self.window = self.screen.root
        else:
            self.window = self.display.create_resource_object(
                "window", window.get_xid())
        self.grab(self.keytext)

    def get_mask_combinations(self, mask):
        return [x for x in range(mask + 1) if not (x & ~mask)]

    def idle(self):
        self.emit("activate")
        return False

    def activate(self):
        GLib.idle_add(self.run)

    # Get which window manager we're currently using (Marco, Compiz, Metacity, etc...)
    def get_wm(self):
        name = ''
        wm_check = self.display.get_atom('_NET_SUPPORTING_WM_CHECK')
        win_id = self.window.get_full_property(wm_check, X.AnyPropertyType)
        if win_id:
            w = self.display.create_resource_object("window", win_id.value[0])
            wm_name = self.display.get_atom('_NET_WM_NAME')
            prop = w.get_full_property(wm_name, X.AnyPropertyType)
            if prop:
                name = prop.value
        return name.lower()

    def run(self):
        self.running = True
        wait_for_release = False
        while self.running:
            event = self.display.next_event()

            if self.modifiers:
                # Use simpler logic when using traditional combined keybindings
                modifiers = event.state & self.known_modifiers_mask
                if event.type == X.KeyPress and event.detail == self.keycode and modifiers == self.modifiers:
                    GLib.idle_add(self.idle)

            else:
                try:
                    # KeyPress
                    if event.type == X.KeyPress and event.detail == self.keycode and not wait_for_release:
                        modifiers = event.state & self.known_modifiers_mask
                        if modifiers == self.modifiers:
                            wait_for_release = True

                    # KeyRelease
                    elif event.type == X.KeyRelease and event.detail == self.keycode and wait_for_release:
                        GLib.idle_add(self.idle)
                        wait_for_release = False

                    # Modifiers are often used with mouse events - don't let the system swallow those
                    elif event.type == X.ButtonPress:
                        self.display.allow_events(X.ReplayPointer,
                                                  X.CurrentTime)
                        # Compiz would rather not have the event sent to it and just read it from the replayed queue
                        wm = self.get_wm()
                        if wm != "compiz":
                            self.display.ungrab_keyboard(X.CurrentTime)
                            self.display.ungrab_pointer(X.CurrentTime)
                            query_pointer = self.window.query_pointer()
                            self.display.send_event(query_pointer.child, event,
                                                    X.ButtonPressMask, True)
                        wait_for_release = False

                    # If the user presses another key in between the KeyPress and the KeyRelease, they
                    # meant to use a different shortcut
                    else:
                        self.display.ungrab_keyboard(X.CurrentTime)
                        # Send the event up in case another window is listening to it
                        self.display.send_event(
                            event.window, event,
                            X.KeyPressMask | X.KeyReleaseMask, True)
                        wait_for_release = False
                except AttributeError:
                    continue

    def stop(self):
        self.running = False
        self.ungrab()
        self.display.close()