class XTestSendContext(object): """ This class manages a connection to the X-Server and allows to send key events. """ def __init__(self): # open a connection to the x server self.display = Display() # get the root window of the default screen self.root = self.display.screen().root def send_key_event(self, key_code, key_down): """ Sends a key event to the focused window using python-xlibs fake_input method. :param key_code: Integer code of the key event that should be sent :param key_down: True = key press event, False = key release event """ # select the right event type depending on key_down event_type = X.KeyPress if key_down else X.KeyRelease # fake keyboard event fake_input(self.display, event_type, key_code) # sync connection to ensure that the input is actually sent to the x server self.display.sync() def close(self): """ Closes the connection to the x server """ self.display.close()
class HotkeyThread(qtcore.QThread): hotkeySignal = qtcore.pyqtSignal() def __init__(self, mod = 'MOD_SHIFT', key = 'VK_SPACE'): qtcore.QThread.__init__(self) keysym = string_to_keysym('space') self.modifiers = X.ShiftMask | X.ControlMask self.disp = Display() self.key = self.disp.keysym_to_keycode(keysym) self.root = self.disp.screen().root self.root.change_attributes(event_mask=X.KeyPressMask) self.root.grab_key(self.key, self.modifiers, 0, False, X.GrabModeAsync, X.GrabModeAsync) self.root.grab_key(self.key, self.modifiers | X.LockMask, 0, False, X.GrabModeAsync, X.GrabModeAsync) self.root.grab_key(self.key, self.modifiers | X.Mod2Mask, 0, False, X.GrabModeAsync, X.GrabModeAsync) self.root.grab_key(self.key, self.modifiers | X.LockMask | X.Mod2Mask, 0, False, X.GrabModeAsync, X.GrabModeAsync) self.root.grab_key(self.key, self.modifiers | X.Mod3Mask | X.LockMask, 0, False, X.GrabModeAsync, X.GrabModeAsync) self.root.grab_key(self.key, self.modifiers | X.Mod3Mask | X.Mod2Mask, 0, False, X.GrabModeAsync, X.GrabModeAsync) self.root.grab_key(self.key, self.modifiers | X.Mod3Mask | X.LockMask | X.Mod2Mask, 0, False, X.GrabModeAsync, X.GrabModeAsync) def dispatch_hotkey(self, msg): if msg.type == X.KeyPress: self.hotkeySignal.emit() def __del__(self): self.terminate() def run(self): while True: event = self.root.display.next_event() self.dispatch_hotkey(event) print('finished loop')
def start(self): self._p = Popen([ 'google-chrome', '--user-data-dir=%s' % os.path.join(os.path.dirname(__file__), self.user_dir), '--app=%s' % url, '--name=cafesys-kiosk', ]) pid = self._p.pid window = None while not window: window = _find_chrome_window() while True: display = Display() focus = display.get_input_focus().focus focus.send_event(event.KeyPress( detail=32, #95 time=X.CurrentTime, root=display, window=focus, child=X.NONE, state=0, same_screen=1, root_x=1, root_y=1, event_x=1, event_y=1, )) print 'event sent'
class KeyboardWatcher(Process): def __init__(self,name,queue): self._name = name self._queue = queue self._display = Display() def handle_event(self,reply): """ This function is called when a xlib event is fired """ data = reply.data while len(data): event, data = rq.EventField(None).parse_binary_value(data, self._display.display, None, None) if event.type == X.KeyPress and event.sequence_number == 0: key = event.detail self._queue.put([self._name,key]) def run(self): root = self._display.screen().root ctx = self._display.record_create_context( 0, [record.AllClients], [{ 'core_requests': (0, 0), 'core_replies': (0, 0), 'ext_requests': (0, 0, 0, 0), 'ext_replies': (0, 0, 0, 0), 'delivered_events': (0, 0), 'device_events': (X.KeyReleaseMask), 'errors': (0, 0), 'client_started': False, 'client_died': False, }]) self._display.record_enable_context(ctx, self.handle_event)
def click(self, button=BUTTON_LEFT): display = XlibDisplay() for event, button in \ [(X.ButtonPress, button), (X.ButtonRelease, button)]: LOGGER.debug('%s %s', event, button) xtest.fake_input(display, event, button) display.sync()
def _init_xlib(self): """Setup python-xlib components in the PyGTK event loop""" disp = Display() self.xroot = disp.screen().root # We want to receive KeyPress events self.xroot.change_attributes(event_mask = X.KeyPressMask) self._key_n_mask = {} for key in self._keys: if len(key.split('-')) > 1: more_mask = key.split('-')[0:-1] real_key = key.split('-')[-1] else: more_mask = [] real_key = key try: modmask = reduce(operator.ior, [getattr(X, "%sMask" % x) for x in (self._modkeys + more_mask)]) except Exception, err: logging.error("Error while resolving modifier key mask: %s", err) logging.error("Not binding keys for safety reasons. (eg. What if Ctrl+C got bound?)") modmask = 0 else: keycode = disp.keysym_to_keycode(string_to_keysym(real_key)) self._key_n_mask[(keycode, modmask)] = self._keys[key] #Ignore all combinations of Mod2 (NumLock) and Lock (CapsLock) for ignored in [0, X.Mod2Mask, X.LockMask, X.Mod2Mask | X.LockMask]: self.xroot.grab_key(keycode, modmask | ignored, 1, X.GrabModeAsync, X.GrabModeAsync)
def __init__(self, display=None): self.display = Display(display) self.display2 = Display(display) self.ctx = self.display2.record_create_context( 0, [record.AllClients], [{ 'core_requests': (0, 0), 'core_replies': (0, 0), 'ext_requests': (0, 0, 0, 0), 'ext_replies': (0, 0, 0, 0), 'delivered_events': (0, 0), 'device_events': (X.KeyPress, X.KeyRelease), 'errors': (0, 0), 'client_started': False, 'client_died': False, }]) self.lock_meaning = None #Get these dictionaries for converting keysyms and strings self.keysym_to_string, self.string_to_keysym = self.get_translation_dicts() #Identify and register special groups of keys self.modifier_keycodes = {} self.all_mod_keycodes = [] self.keypad_keycodes = [] #self.configure_keys() #Direct access to the display's keycode-to-keysym array #print('Keycode to Keysym map') #for i in range(len(self.display._keymap_codes)): # print('{0}: {1}'.format(i, self.display._keymap_codes[i])) PyKeyboardEventMeta.__init__(self)
class QuickTileApp(object): keybinds_failed = False def __init__(self, wm, keys=None, modkeys=None, movemodkeys=None): """@todo: document these arguments""" self.wm = wm self._keys = keys or {} self._modkeys = modkeys or 0 self._movemodkeys = movemodkeys or 0 self._movemodmask = 0 def _init_dbus(self): """Setup dbus-python components in the PyGTK event loop""" class QuickTile(dbus.service.Object): def __init__(self): dbus.service.Object.__init__(self, sessBus, '/com/ssokolow/QuickTile') @dbus.service.method(dbus_interface='com.ssokolow.QuickTile', in_signature='s', out_signature='b') def doCommand(self, command): return wm.doCommand(command) def doMoveCommand(self, command): return wm.doMoveCommand(command) self.dbusName = dbus.service.BusName("com.ssokolow.QuickTile", sessBus) self.dbusObj = QuickTile() def _init_xlib(self): """Setup python-xlib components in the PyGTK event loop""" self.xdisp = Display() self.xroot = self.xdisp.screen().root # We want to receive KeyPress events self.xroot.change_attributes(event_mask=X.KeyPressMask) # unrecognized shortkeys now will be looked up in a hardcoded dict # and replaced by valid names like ',' -> 'comma' # while generating the self.keys dict self.keys = dict() for key in self._keys: transKey = key if key in KEYLOOKUP: transKey = KEYLOOKUP[key] code = self.xdisp.keysym_to_keycode(string_to_keysym(transKey)) self.keys[code] = self._keys[key] # Resolve strings to X11 mask constants for the modifier mask try: modmask = reduce(operator.ior, [getattr(X, "%sMask" % x) for x in self._modkeys]) self._movemodmask = reduce(operator.ior, [getattr(X, "%sMask" % x) for x in self._movemodkeys]) except Exception, err: logging.error("Error while resolving modifier key mask: %s", err) logging.error("Not binding keys for safety reasons. " "(eg. What if Ctrl+C got bound?)") modmask = 0 movemodmask = 0 else:
def control(self): """Control an X11 keyboard. Press Ctrl-C to stop.""" # current display root = Display().screen().root # we tell the X server we want to catch keyPress event root.change_attributes(event_mask = X.KeyPressMask) # Inform X11 of which keys we'll be trapping keys = self.keys for keycode in keys: root.grab_key(keycode, X.AnyModifier, 1, X.GrabModeAsync, X.GrabModeAsync) # Endless loop which listens for events next_event = root.display.next_event KeyPress = X.KeyPress try: while 1: event = next_event() if event.type == KeyPress: # For KeyPress events, event.detail is the keycode keys[event.detail]() except KeyboardInterrupt: pass
def __init__(self, wid): """Constructor for OpenGLRenderingArea""" xlib = cdll.LoadLibrary('libX11.so') xlib.XOpenDisplay.argtypes = [c_char_p] xlib.XOpenDisplay.restype = POINTER(struct__XDisplay) self.xdisplay = xlib.XOpenDisplay((ctypes.c_char * 1)(*[0])) display = Display() attrs = [ GLX.GLX_RGBA, True, GLX.GLX_RED_SIZE, 1, GLX.GLX_GREEN_SIZE, 1, GLX.GLX_BLUE_SIZE, 1, GLX.GLX_DOUBLEBUFFER, 0, 0, 0 ] width = 200 height = 200 cattrs = (c_int * len(attrs))(*attrs) xvinfo = GLX.glXChooseVisual(self.xdisplay, display.get_default_screen(), cattrs) configs = GLX.glXChooseFBConfig(self.xdisplay, 0, None, byref(c_int())) self.context = GLX.glXCreateContext(self.xdisplay, xvinfo, None, True) self.x_window_id = GdkX11.X11Window.get_xid(wid) if not GLX.glXMakeCurrent(self.xdisplay, self.x_window_id, self.context): print("failed") GL.glViewport(0, 0, width, height) # todo self.app = None GL.glClearColor(0.24, 0.24, 0.24, 0.0) self.profiler_window = None
def main(): z = Zoomer() # setup xlib disp = Display() root = disp.screen().root # grab a buttons with a modifier for mask in masks: for button in buttons: root.grab_button(button, X.Mod1Mask | mask, root, False, X.GrabModeAsync, X.GrabModeAsync, X.NONE, X.NONE) while 1: try: event = root.display.next_event() if event.detail == X.Button4: z.zoomIn() elif event.detail == X.Button5: z.zoomOut() except AttributeError: pass except ConnectionClosedError: sys.exit()
def run(self): self.disable_keyboard_interrupt() display = Display() while True: try: time.sleep(self._interval) window = display.get_input_focus().focus if window.get_wm_class() is None and window.get_wm_name() is None: window = window.query_tree().parent if window: pid_value = window.get_full_property(display.intern_atom('_NET_WM_PID'),0) if pid_value: try: pid = int(pid_value.value[0]) process = psutil.Process(pid) name,exe,title = process.name,process.exe,window.get_wm_name() value = {'exe':exe,'title':title.decode('latin-1'),'time':time.time()-self._last_time} self.send_event(value) self._last_time = time.time() except: pass except AttributeError: pass
def main(): parser = argparse.ArgumentParser() parser.add_argument("-t", "--timeout", help="specify a timeout interval between 1 and infinity", type=int, required=True) args = parser.parse_args() display = Display() if not display.has_extension('XFIXES'): if display.query_extension('XFIXES') is None: print('XFIXES extension not supported', file=sys.stderr) return 1 xfixes_version = display.xfixes_query_version() print('Found XFIXES version %s.%s' % ( xfixes_version.major_version, xfixes_version.minor_version, ), file=sys.stderr) screen = display.screen() mouse = Mouse(display, screen, args.timeout) mouse.start() run_sensor(mouse)
def run(self): if sys.platform=="win32": import win32con import ctypes k,mods=self.readShortcut_Win() if not ctypes.windll.user32.RegisterHotKey(None,0,mods,k): self.error.emit() return False msg = ctypes.wintypes.MSG () while ctypes.windll.user32.GetMessageA (ctypes.byref (msg), None, 0, 0) != 0: if msg.message == win32con.WM_HOTKEY: self.show.emit() elif sys.platform.startswith("linux"): from Xlib.display import Display from Xlib import X,error __BAD_ACCESS = error.CatchError(error.BadAccess) disp = Display() root = disp.screen().root root.change_attributes(event_mask = X.KeyPressMask) k,mods=self.readShortcut_Linux(disp) root.grab_key(k, mods, 1,X.GrabModeAsync, X.GrabModeAsync,onerror=__BAD_ACCESS) disp.sync() if __BAD_ACCESS.get_error(): self.error.emit() return False while True: event=root.display.next_event() if event.type==X.KeyPress: if event.detail==k: self.show.emit()
def main(): disp = Display() while 1: keymap = disp.query_keymap() if keymap not in ignorelist: KeyPress().start() time.sleep(0.08)
def main(): disp = Display() lastlastkeymap = [] lastkeymap = [] stopCommand = 0 makeBeep = 1 lowerQ = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] upperQ = [0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] while 1: time.sleep(0.06) # This is the lowest value that ensures Xlib won't recognize a single keypress twice keymap = disp.query_keymap() if keymap == lowerQ and keymap == lastkeymap: stopCommand += 1 if stopCommand == 2: stopCommand = 0 makeBeep = 1 - makeBeep else: stopCommand = 0 if keymap not in ignorelist and keymap != lastkeymap: lastkeymap = keymap if makeBeep == 1: os.system("beep -l 20")
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)
def sleep_screen(): print('') display = Display(':0') root = display.screen().root root.grab_pointer(True, X.ButtonPressMask | X.ButtonReleaseMask | X.PointerMotionMask, X.GrabModeAsync, X.GrabModeAsync, 0, 0, X.CurrentTime) root.grab_keyboard(True, X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime) subprocess.call('xset dpms force off'.split()) p = subprocess.Popen('gnome-screensaver-command -i'.split()) while True: # print display.next_event() p.terminate() break subprocess.call('amixer set Master mute'.split()) print('\nHave a nice rest! Signing out until dawn ({}).'.format( dt.datetime.now())) subprocess.call( 'gsettings set org.gnome.desktop.session idle-delay 3600'.split()) print('\\' * 36 + '|' * 8 + '/' * 36) print('\\' * 38 + '|' * 4 + '/' * 38) print('\\' * 40 + '/' * 40)
def mouse_move(x, y): from Xlib.display import Display from Xlib import X from Xlib.ext.xtest import fake_input d = Display() fake_input(d, X.MotionNotify, x=x, y=y) d.flush()
class KeyboardAndMouseWatcher(BaseWatcher): def __init__(self,name,queue): super(KeyboardAndMouseWatcher,self).__init__(name,queue) self._queue = queue self._mouse_last_x = None self._mouse_last_y = None self._display = Display() def add_to_datapoint(self,x,y): if y[0] == 'keys_pressed': x[y[0]][y[1]]+=y[2] else: x[y[0]]+=y[1] return x def init_datapoint(self): return {'buttons_pressed': 0,'keys_pressed' :defaultdict(lambda :0),'mouse_moved':0} def handle_event(self,reply): """ This function is called when a xlib event is fired """ data = reply.data while len(data): event, data = rq.EventField(None).parse_binary_value(data, self._display.display, None, None) if event.type == X.MotionNotify: if self._mouse_last_x != None: mouse_distance=math.sqrt((event.root_x-self._mouse_last_x)**2+(event.root_y-self._mouse_last_y)**2) self.send_event(('mouse_moved',mouse_distance)) self._mouse_last_x,self._mouse_last_y = event.root_x,event.root_y if event.type == X.ButtonPress: self.send_event(('buttons_pressed',1)) if event.type == X.KeyPress: key = event.detail self.send_event(('keys_pressed',key,1)) def run(self): self.disable_keyboard_interrupt() root = self._display.screen().root ctx = self._display.record_create_context( 0, [record.AllClients], [{ 'core_requests': (0, 0), 'core_replies': (0, 0), 'ext_requests': (0, 0, 0, 0), 'ext_replies': (0, 0, 0, 0), 'delivered_events': (0, 0), 'device_events': (X.KeyReleaseMask, X.PointerMotionMask), 'errors': (0, 0), 'client_started': False, 'client_died': False, }]) self._display.record_enable_context(ctx, self.handle_event)
def main(): disp = Display() # connect to display while 1: #event loop keymap = disp.query_keymap() if keymap not in ignorelist: os.popen("curl http://localhost:4567/key") time.sleep(0.1)
def stop(self): # hack for unreleased context # https://github.com/SavinaRoja/PyUserInput/issues/48 from Xlib.display import Display display = Display() display.record_disable_context(self.ctx) display.close() return super().stop()
def girale(mov): up=4 #4 scrolls up down=5 #5 scrolls down d = Display() m = up if mov==1 else down fake_input(d,X.ButtonPress,m) d.sync() fake_input(d,X.ButtonRelease,m) d.sync()
def mouse_click(button=1): from Xlib import X from Xlib.display import Display from Xlib.ext.xtest import fake_input d = Display() fake_input(d, X.ButtonPress, button) d.sync() fake_input(d, X.ButtonRelease, button) d.sync()
class PyMouse(PyMouseMeta): def __init__(self, display=':0'): PyMouseMeta.__init__(self) self.display = Display(display) self.display2 = Display(display) def press(self, x, y, button = 1): self.move(x, y) fake_input(self.display, X.ButtonPress, [None, 1, 3, 2, 4, 5][button]) self.display.sync() def release(self, x, y, button = 1): self.move(x, y) fake_input(self.display, X.ButtonRelease, [None, 1, 3, 2, 4, 5][button]) self.display.sync() def move(self, x, y): fake_input(self.display, X.MotionNotify, x=x, y=y) self.display.sync() def position(self): coord = self.display.screen().root.query_pointer()._data return coord["root_x"], coord["root_y"] def screen_size(self): width = self.display.screen().width_in_pixels height = self.display.screen().height_in_pixels return width, height
def main(argv): display = Display() if not display.has_extension('XFIXES'): if display.query_extension('XFIXES') is None: print('XFIXES extension not supported', file=sys.stderr) return 1 xfixes_version = display.xfixes_query_version() print('Found XFIXES version %s.%s' % ( xfixes_version.major_version, xfixes_version.minor_version, ), file=sys.stderr) screen = display.screen() print('Hiding cursor ...', file=sys.stderr) screen.root.xfixes_hide_cursor() display.sync() time.sleep(5) print('Showing cursor ...', file=sys.stderr) screen.root.xfixes_hide_cursor() display.sync()
class x11_Mouse: def __init__(self): self.display = Display() def press(self, x, y, button=1): self.move(x, y) fake_input(self.display, X.ButtonPress, button_ids[button]) self.display.sync() def release(self, x, y, button=1): self.move(x, y) fake_input(self.display, X.ButtonRelease, button_ids[button]) self.display.sync() def move(self, x, y): # if (x, y) != self.position( ): fake_input(self.display, X.MotionNotify, x=x, y=y) self.display.sync() def position(self): pos = self.display.screen().root.query_pointer()._data return pos["root_x"], pos["root_y"] def screen_size(self): width = self.display.screen().width_in_pixels height = self.display.screen().height_in_pixels return width, heightwe
def __send_key(self, x_event, key_code): key = key_code.X11 if key is None: print("key not defined on X11!") pass d = Display() x11key = d.keysym_to_keycode(XK.string_to_keysym(key)) fake_input(d, x_event, x11key) d.sync()
class PyMouse(PyMouseMeta): def __init__(self, display=None): PyMouseMeta.__init__(self) self.display = Display(display) def press(self, x=None, y=None, button=1): self.move(x, y) fake_input(self.display, X.ButtonPress, button_ids[button]) self.display.sync() def release(self, x=None, y=None, button=1): self.move(x, y) fake_input(self.display, X.ButtonRelease, button_ids[button]) self.display.sync() def scroll(self, vertical=None, horizontal=None, depth=None): # Xlib supports only vertical and horizontal scrolling if depth is not None: raise ScrollSupportError( "PyMouse cannot support depth-scrolling \ in X11. This feature is only available on Mac." ) # Execute vertical then horizontal scrolling events if vertical is not None: vertical = int(vertical) if vertical == 0: # Do nothing with 0 distance pass elif vertical > 0: # Scroll up if positive self.click(*self.position(), button=4, n=vertical) else: # Scroll down if negative self.click(*self.position(), button=5, n=abs(vertical)) if horizontal is not None: horizontal = int(horizontal) if horizontal == 0: # Do nothing with 0 distance pass elif horizontal > 0: # Scroll right if positive self.click(*self.position(), button=7, n=horizontal) else: # Scroll left if negative self.click(*self.position(), button=6, n=abs(horizontal)) def move(self, x, y): if (x, y) != self.position() and (x, y) != (None, None): fake_input(self.display, X.MotionNotify, x=x, y=y) self.display.sync() def drag(self, x, y): self.move(x, y) def position(self): coord = self.display.screen().root.query_pointer()._data return coord["root_x"], coord["root_y"] def screen_size(self): width = self.display.screen().width_in_pixels height = self.display.screen().height_in_pixels return width, height
def _unregister_shortcut(self, native_key, native_mods, window_id): display = Display() window = display.screen().root self._error = False window.ungrab_key(native_key, native_mods, self._on_error) display.sync() try: del self.shortcuts[(native_key, native_mods)] except KeyError: pass return not self._error
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:", e) def stop(self): self.running = False self.root.ungrab_button(X.AnyButton, X.AnyModifier) self.display.close()
integers, but not keysyms. """ if key not in keyboardMapping or keyboardMapping[key] is None: return if type(key) == int: keycode = key else: keycode = keyboardMapping[key] fake_input(_display, X.KeyRelease, keycode) _display.sync() # Taken from PyKeyboard's ctor function. _display = Display(os.environ['DISPLAY']) """ Information for keyboardMapping derived from PyKeyboard's special_key_assignment() function. The *KB dictionaries in pyautogui map a string that can be passed to keyDown(), keyUp(), or press() into the code used for the OS-specific keyboard function. They should always be lowercase, and the same keys should be used across all OSes.""" keyboardMapping = dict([(key, None) for key in pyautogui.KEY_NAMES]) keyboardMapping.update({ 'backspace': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('BackSpace')), '\b': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('BackSpace')), 'tab': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Tab')), 'enter':
from .special_keys import CONTROL as _CONTROL _log = getLogger(__name__) del getLogger # many of the rule features require X11 so turn rule processing off if X11 is not available try: import Xlib from Xlib import X from Xlib.display import Display from Xlib.ext import record from Xlib.protocol import rq from Xlib import XK as _XK _XK.load_keysym_group('xf86') XK_KEYS = vars(_XK) disp_prog = Display() x11 = True except Exception: _log.warn('X11 not available - rules will not be activated', exc_info=_sys.exc_info()) XK_KEYS = {} x11 = False if x11: # determine name of active process NET_ACTIVE_WINDOW = disp_prog.intern_atom('_NET_ACTIVE_WINDOW') NET_WM_PID = disp_prog.intern_atom('_NET_WM_PID') WM_CLASS = disp_prog.intern_atom('WM_CLASS') root2 = disp_prog.screen().root root2.change_attributes(event_mask=Xlib.X.PropertyChangeMask) active_process_name = None
class BreakScreen(object): """ The fullscreen window which prevents users from using the computer. This class reads the break_screen.glade and build the user interface. """ def __init__(self, context, on_skip, on_postpone, style_sheet_path): self.context = context self.count_labels = [] self.display = Display() self.enable_postpone = False self.enable_shortcut = False self.is_pretified = False self.keycode_shortcut_postpone = 65 self.keycode_shortcut_skip = 9 self.on_postpone = on_postpone self.on_skip = on_skip self.shortcut_disable_time = 2 self.strict_break = False self.windows = [] # Initialize the theme css_provider = Gtk.CssProvider() css_provider.load_from_path(style_sheet_path) Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) def initialize(self, config): """ Initialize the internal properties from configuration """ logging.info("Initialize the break screen") self.enable_postpone = config.get('allow_postpone', False) self.keycode_shortcut_postpone = config.get('shortcut_postpone', 65) self.keycode_shortcut_skip = config.get('shortcut_skip', 9) self.shortcut_disable_time = config.get('shortcut_disable_time', 2) self.strict_break = config.get('strict_break', False) def skip_break(self): """ Skip the break from the break screen """ logging.info("User skipped the break") # Must call on_skip before close to lock screen before closing the break screen self.on_skip() self.close() def postpone_break(self): """ Postpone the break from the break screen """ logging.info("User postponed the break") self.on_postpone() self.close() def on_window_delete(self, *args): """ Window close event handler. """ logging.info("Closing the break screen") self.__release_keyboard() self.close() def on_skip_clicked(self, button): """ Skip button press event handler. """ self.skip_break() def on_postpone_clicked(self, button): """ Postpone button press event handler. """ self.postpone_break() def show_count_down(self, countdown, seconds): """ Show/update the count down on all screens. """ self.enable_shortcut = not self.strict_break and self.shortcut_disable_time <= seconds mins, secs = divmod(countdown, 60) timeformat = '{:02d}:{:02d}'.format(mins, secs) GLib.idle_add(lambda: self.__update_count_down(timeformat)) def show_message(self, break_obj, widget): """ Show the break screen with the given message on all displays. """ message = break_obj.name image_path = break_obj.image self.enable_shortcut = not self.strict_break and self.shortcut_disable_time <= 0 GLib.idle_add( lambda: self.__show_break_screen(message, image_path, widget)) def close(self): """ Hide the break screen from active window and destroy all other windows """ logging.info("Close the break screen(s)") self.__release_keyboard() # Destroy other windows if exists GLib.idle_add(lambda: self.__destroy_all_screens()) def __show_break_screen(self, message, image_path, widget): """ Show an empty break screen on all screens. """ # Lock the keyboard thread = threading.Thread(target=self.__lock_keyboard) thread.start() logging.info("Show break screens in all displays") screen = Gtk.Window().get_screen() no_of_monitors = screen.get_n_monitors() for monitor in range(no_of_monitors): monitor_gemoetry = screen.get_monitor_geometry(monitor) x = monitor_gemoetry.x y = monitor_gemoetry.y builder = Gtk.Builder() builder.add_from_file(BREAK_SCREEN_GLADE) builder.connect_signals(self) window = builder.get_object("window_main") lbl_message = builder.get_object("lbl_message") lbl_count = builder.get_object("lbl_count") lbl_widget = builder.get_object("lbl_widget") img_break = builder.get_object("img_break") box_buttons = builder.get_object("box_buttons") # Add the buttons if not self.strict_break: # Add postpone button if self.enable_postpone: btn_postpone = Gtk.Button(_('Postpone')) btn_postpone.get_style_context().add_class('btn_postpone') btn_postpone.connect('clicked', self.on_postpone_clicked) btn_postpone.set_visible(True) box_buttons.pack_start(btn_postpone, True, True, 0) # Add the skip button btn_skip = Gtk.Button(_('Skip')) btn_skip.get_style_context().add_class('btn_skip') btn_skip.connect('clicked', self.on_skip_clicked) btn_skip.set_visible(True) box_buttons.pack_start(btn_skip, True, True, 0) # Set values if image_path: img_break.set_from_file(image_path) lbl_message.set_label(message) lbl_widget.set_markup(widget) self.windows.append(window) self.count_labels.append(lbl_count) # Set visual to apply css theme. It should be called before show method. window.set_visual(window.get_screen().get_rgba_visual()) if self.context['desktop'] == 'kde': # Fix flickering screen in KDE by setting opacity to 1 window.set_opacity(0.9) # In Unity, move the window before present if self.context['desktop'] == 'unity': window.move(x, y) window.stick() window.set_keep_above(True) window.present() # In other desktop environments, move the window after present if self.context['desktop'] != 'unity': window.move(x, y) window.fullscreen() def __update_count_down(self, count): """ Update the countdown on all break screens. """ for label in self.count_labels: label.set_text(count) def __lock_keyboard(self): """ Lock the keyboard to prevent the user from using keyboard shortcuts """ logging.info("Lock the keyboard") self.lock_keyboard = True # Grab the keyboard root = self.display.screen().root root.change_attributes(event_mask=X.KeyPressMask | X.KeyReleaseMask) root.grab_keyboard(True, X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime) # Consume keyboard events while self.lock_keyboard: if self.display.pending_events() > 0: # Avoid waiting for next event by checking pending events event = self.display.next_event() if self.enable_shortcut and event.type == X.KeyPress: if event.detail == self.keycode_shortcut_skip: self.skip_break() break elif self.enable_postpone and event.detail == self.keycode_shortcut_postpone: self.postpone_break() break else: # Reduce the CPU usage by sleeping for a second time.sleep(1) def __release_keyboard(self): """ Release the locked keyboard. """ logging.info("Unlock the keyboard") self.lock_keyboard = False self.display.ungrab_keyboard(X.CurrentTime) self.display.flush() def __destroy_all_screens(self): """ Close all the break screens. """ for win in self.windows: win.destroy() del self.windows[:] del self.count_labels[:]
def __init__(self, display=None): PyKeyboardMeta.__init__(self) self.display = Display(display) self.display2 = Display(display) self.special_key_assignment()
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()
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from Xlib.display import Display from Xlib import X from time import sleep display = Display(':0') root = display.screen().root root.change_attributes(event_mask=X.SubstructureNotifyMask) class EventWaiter(object): def waitMapNotify(self): while True: ev = display.next_event() if ev.type == X.MapNotify: sleep(1) return ev waiter = EventWaiter()
class PyKeyboard(PyKeyboardMeta): """ The PyKeyboard implementation for X11 systems (mostly linux). This allows one to simulate keyboard input. """ def __init__(self, display=None): PyKeyboardMeta.__init__(self) self.display = Display(display) self.display2 = Display(display) self.special_key_assignment() def press_key(self, character=''): """ Press a given character key. Also works with character keycodes as integers, but not keysyms. """ try: # Detect uppercase or shifted character shifted = self.is_char_shifted(character) except AttributeError: # Handle the case of integer keycode argument fake_input(self.display, X.KeyPress, character) self.display.sync() else: if shifted: fake_input(self.display, X.KeyPress, self.shift_key) char_val = self.lookup_character_value(character) fake_input(self.display, X.KeyPress, char_val) self.display.sync() def release_key(self, character=''): """ Release a given character key. Also works with character keycodes as integers, but not keysyms. """ try: # Detect uppercase or shifted character shifted = self.is_char_shifted(character) except AttributeError: # Handle the case of integer keycode argument fake_input(self.display, X.KeyRelease, character) self.display.sync() else: if shifted: fake_input(self.display, X.KeyRelease, self.shift_key) char_val = self.lookup_character_value(character) fake_input(self.display, X.KeyRelease, char_val) self.display.sync() def special_key_assignment(self): """ Determines the keycodes for common special keys on the keyboard. These are integer values and can be passed to the other key methods. Generally speaking, these are non-printable codes. """ #This set of keys compiled using the X11 keysymdef.h file as reference #They comprise a relatively universal set of keys, though there may be #exceptions which may come up for other OSes and vendors. Countless #special cases exist which are not handled here, but may be extended. #TTY Function Keys self.backspace_key = self.lookup_character_value('BackSpace') self.tab_key = self.lookup_character_value('Tab') self.linefeed_key = self.lookup_character_value('Linefeed') self.clear_key = self.lookup_character_value('Clear') self.return_key = self.lookup_character_value('Return') self.enter_key = self.return_key # Because many keyboards call it "Enter" self.pause_key = self.lookup_character_value('Pause') self.scroll_lock_key = self.lookup_character_value('Scroll_Lock') self.sys_req_key = self.lookup_character_value('Sys_Req') self.escape_key = self.lookup_character_value('Escape') self.delete_key = self.lookup_character_value('Delete') #Modifier Keys self.shift_l_key = self.lookup_character_value('Shift_L') self.shift_r_key = self.lookup_character_value('Shift_R') self.shift_key = self.shift_l_key # Default Shift is left Shift self.alt_l_key = self.lookup_character_value('Alt_L') self.alt_r_key = self.lookup_character_value('Alt_R') self.alt_key = self.alt_l_key # Default Alt is left Alt self.control_l_key = self.lookup_character_value('Control_L') self.control_r_key = self.lookup_character_value('Control_R') self.control_key = self.control_l_key # Default Ctrl is left Ctrl self.caps_lock_key = self.lookup_character_value('Caps_Lock') self.capital_key = self.caps_lock_key # Some may know it as Capital self.shift_lock_key = self.lookup_character_value('Shift_Lock') self.meta_l_key = self.lookup_character_value('Meta_L') self.meta_r_key = self.lookup_character_value('Meta_R') self.super_l_key = self.lookup_character_value('Super_L') self.windows_l_key = self.super_l_key # Cross-support; also it's printed there self.super_r_key = self.lookup_character_value('Super_R') self.windows_r_key = self.super_r_key # Cross-support; also it's printed there self.hyper_l_key = self.lookup_character_value('Hyper_L') self.hyper_r_key = self.lookup_character_value('Hyper_R') #Cursor Control and Motion self.home_key = self.lookup_character_value('Home') self.up_key = self.lookup_character_value('Up') self.down_key = self.lookup_character_value('Down') self.left_key = self.lookup_character_value('Left') self.right_key = self.lookup_character_value('Right') self.end_key = self.lookup_character_value('End') self.begin_key = self.lookup_character_value('Begin') self.page_up_key = self.lookup_character_value('Page_Up') self.page_down_key = self.lookup_character_value('Page_Down') self.prior_key = self.lookup_character_value('Prior') self.next_key = self.lookup_character_value('Next') #Misc Functions self.select_key = self.lookup_character_value('Select') self.print_key = self.lookup_character_value('Print') self.print_screen_key = self.print_key # Seems to be the same thing self.snapshot_key = self.print_key # Another name for printscreen self.execute_key = self.lookup_character_value('Execute') self.insert_key = self.lookup_character_value('Insert') self.undo_key = self.lookup_character_value('Undo') self.redo_key = self.lookup_character_value('Redo') self.menu_key = self.lookup_character_value('Menu') self.apps_key = self.menu_key # Windows... self.find_key = self.lookup_character_value('Find') self.cancel_key = self.lookup_character_value('Cancel') self.help_key = self.lookup_character_value('Help') self.break_key = self.lookup_character_value('Break') self.mode_switch_key = self.lookup_character_value('Mode_switch') self.script_switch_key = self.lookup_character_value('script_switch') self.num_lock_key = self.lookup_character_value('Num_Lock') #Keypad Keys: Dictionary structure keypad = [ 'Space', 'Tab', 'Enter', 'F1', 'F2', 'F3', 'F4', 'Home', 'Left', 'Up', 'Right', 'Down', 'Prior', 'Page_Up', 'Next', 'Page_Down', 'End', 'Begin', 'Insert', 'Delete', 'Equal', 'Multiply', 'Add', 'Separator', 'Subtract', 'Decimal', 'Divide', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] self.keypad_keys = { k: self.lookup_character_value('KP_' + str(k)) for k in keypad } self.numpad_keys = self.keypad_keys #Function Keys/ Auxilliary Keys #FKeys self.function_keys = [None] + [ self.lookup_character_value('F' + str(i)) for i in xrange(1, 36) ] #LKeys self.l_keys = [None] + [ self.lookup_character_value('L' + str(i)) for i in xrange(1, 11) ] #RKeys self.r_keys = [None] + [ self.lookup_character_value('R' + str(i)) for i in xrange(1, 16) ] #Unsupported keys from windows self.kana_key = None self.hangeul_key = None # old name - should be here for compatibility self.hangul_key = None self.junjua_key = None self.final_key = None self.hanja_key = None self.kanji_key = None self.convert_key = None self.nonconvert_key = None self.accept_key = None self.modechange_key = None self.sleep_key = None def lookup_character_value(self, character): """ Looks up the keysym for the character then returns the keycode mapping for that keysym. """ ch_keysym = string_to_keysym(character) if ch_keysym == 0: ch_keysym = string_to_keysym(special_X_keysyms[character]) return self.display.keysym_to_keycode(ch_keysym)
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_L'), X.AnyModifier, True) self.inkscape.ungrab_key(self.string_to_keycode('Shift_L'), 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): print('keycode of Super_L:', self.string_to_keycode('Super_L')) print('keycode of Shift_L:', self.string_to_keycode('Shift_L')) self.grab() while True: evt = self.disp.next_event() if evt.type in [X.KeyPress, X.KeyRelease]: keycode = evt.detail print('keycode', keycode) 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
class PyKeyboardEvent(PyKeyboardEventMeta): """ The PyKeyboardEvent implementation for X11 systems (mostly linux). This allows one to listen for keyboard input. """ def __init__(self, display=None): PyKeyboardEventMeta.__init__(self) self.display = Display(display) self.display2 = Display(display) self.ctx = self.display2.record_create_context( 0, [record.AllClients ], [{ 'core_requests': (0, 0), 'core_replies': (0, 0), 'ext_requests': (0, 0, 0, 0), 'ext_replies': (0, 0, 0, 0), 'delivered_events': (0, 0), 'device_events': (X.KeyPress, X.KeyRelease), 'errors': (0, 0), 'client_started': False, 'client_died': False, }]) self.shift_state = 0 # 0 is off, 1 is on self.alt_state = 0 # 0 is off, 2 is on self.mod_keycodes = self.get_mod_keycodes() def run(self): """Begin listening for keyboard input events.""" self.state = True if self.capture: self.display2.screen().root.grab_keyboard( True, X.KeyPressMask | X.KeyReleaseMask, X.GrabModeAsync, X.GrabModeAsync, 0, 0, X.CurrentTime) self.display2.record_enable_context(self.ctx, self.handler) self.display2.record_free_context(self.ctx) def stop(self): """Stop listening for keyboard input events.""" self.state = False self.display.record_disable_context(self.ctx) self.display.ungrab_keyboard(X.CurrentTime) self.display.flush() self.display2.record_disable_context(self.ctx) self.display2.ungrab_keyboard(X.CurrentTime) self.display2.flush() def handler(self, reply): """Upper level handler of keyboard events.""" data = reply.data while len(data): event, data = rq.EventField(None).parse_binary_value( data, self.display.display, None, None) if event.type == X.KeyPress: if self.escape_code(event): # Quit if this returns True self.stop() else: self._key_press(event.detail) elif event.type == X.KeyRelease: self._key_release(event.detail) else: print('WTF: {0}'.format(event.type)) def _key_press(self, keycode): """A key has been pressed, do stuff.""" #Alter modification states if keycode in self.mod_keycodes[ 'Shift'] or keycode in self.mod_keycodes['Lock']: self.toggle_shift_state() elif keycode in self.mod_keycodes['Alt']: self.toggle_alt_state() else: self.key_press(keycode) def _key_release(self, keycode): """A key has been released, do stuff.""" #Alter modification states if keycode in self.mod_keycodes['Shift']: self.toggle_shift_state() elif keycode in self.mod_keycodes['Alt']: self.toggle_alt_state() else: self.key_release(keycode) def escape_code(self, event): if event.detail == self.lookup_character_value('Escape'): return True return False def lookup_char_from_keycode(self, keycode): keysym = self.display.keycode_to_keysym( keycode, self.shift_state + self.alt_state) if keysym: char = self.display.lookup_string(keysym) return char else: return None def get_mod_keycodes(self): """ Detects keycodes for modifiers and parses them into a dictionary for easy access. """ modifier_mapping = self.display.get_modifier_mapping() modifier_dict = {} nti = [('Shift', X.ShiftMapIndex), ('Control', X.ControlMapIndex), ('Mod1', X.Mod1MapIndex), ('Alt', X.Mod1MapIndex), ('Mod2', X.Mod2MapIndex), ('Mod3', X.Mod3MapIndex), ('Mod4', X.Mod4MapIndex), ('Mod5', X.Mod5MapIndex), ('Lock', X.LockMapIndex)] for n, i in nti: modifier_dict[n] = list(modifier_mapping[i]) return modifier_dict def lookup_character_value(self, character): """ Looks up the keysym for the character then returns the keycode mapping for that keysym. """ ch_keysym = string_to_keysym(character) if ch_keysym == 0: ch_keysym = string_to_keysym(special_X_keysyms[character]) return self.display.keysym_to_keycode(ch_keysym) def toggle_shift_state(self): '''Does toggling for the shift state.''' if self.shift_state == 0: self.shift_state = 1 elif self.shift_state == 1: self.shift_state = 0 else: return False return True def toggle_alt_state(self): '''Does toggling for the alt state.''' if self.alt_state == 0: self.alt_state = 2 elif self.alt_state == 2: self.alt_state = 0 else: return False return True
class Listener: def __init__(self): self.disp = None self.keys_down = set() def keycode_to_key(self, keycode, state): i = 0 #if state & X.ShiftMask: #i += 1 #if state & X.Mod1Mask: #i += 2 return self.disp.keycode_to_keysym(keycode, i) def key_to_string(self, key): keys = [] for name in dir(XK): if name.startswith("XK_") and getattr(XK, name) == key: keys.append( name.lstrip("XK_").replace("_L", "").replace("_R", "")) if keys: return " or ".join(keys) return "[%d]" % key def keycode_to_string(self, keycode, state): return self.key_to_string(self.keycode_to_key(keycode, state)) def mouse_to_string(self, code): if code == X.Button1: return "Button1" elif code == X.Button2: return "Button2" elif code == X.Button3: return "Button3" elif code == X.Button4: return "Button4" elif code == X.Button5: return "Button5" else: return "{%d}" % code def down(self, key): self.keys_down.add(key) self.print_keys() def up(self, key): if key in self.keys_down: self.keys_down.remove(key) self.print_keys() def print_keys(self): keys = str(list(self.keys_down)) #print(keys) self.EventL() def event_handler(self, reply): data = reply.data while data: event, data = rq.EventField(None).parse_binary_value( data, self.disp.display, None, None) if event.type == X.KeyPress: self.down(self.keycode_to_string(event.detail, event.state)) elif event.type == X.KeyRelease: self.up(self.keycode_to_string(event.detail, event.state)) elif event.type == X.ButtonPress: self.down(self.mouse_to_string(event.detail)) elif event.type == X.ButtonRelease: self.up(self.mouse_to_string(event.detail)) def run(self): self.disp = Display() XK.load_keysym_group('xf86') root = self.disp.screen().root ctx = self.disp.record_create_context( 0, [record.AllClients ], [{ 'core_requests': (0, 0), 'core_replies': (0, 0), 'ext_requests': (0, 0, 0, 0), 'ext_replies': (0, 0, 0, 0), 'delivered_events': (0, 0), 'device_events': (X.KeyReleaseMask, X.ButtonReleaseMask), 'errors': (0, 0), 'client_started': False, 'client_died': False, }]) self.disp.record_enable_context( ctx, lambda reply: self.event_handler(reply)) self.disp.record_free_context(ctx) while True: event = root.display.next_event() def EventL(self): keys = str(list(self.keys_down)) #print(keys) if keys == "['Shift']" or keys == "['Button2']": Suspend1() if pause == 0: if keys == "['Button1']": mouselu("")
pass elif event.type == X.KeyRelease: keycode = event.detail keysym = disp.keycode_to_keysym(keycode, 0) if hex(keysym) == MediaKey.media_next.value: print("next") elif hex(keysym) == MediaKey.media_previous.value: print("previous") elif hex(keysym) == MediaKey.media_stop.value: print("stop") elif hex(keysym) == MediaKey.media_play_pause.value: print("play_or_pause") # get current display disp = Display() root = disp.screen().root # Monitor keypress and button press ctx = disp.record_create_context( 0, [record.AllClients ], [{ 'core_requests': (0, 0), 'core_replies': (0, 0), 'ext_requests': (0, 0, 0, 0), 'ext_replies': (0, 0, 0, 0), 'delivered_events': (0, 0), 'device_events': (X.KeyReleaseMask, X.ButtonReleaseMask), 'errors': (0, 0), 'client_started': False, 'client_died': False,
class GlobalKey(threading.Thread): ''' Class to handle global key. ''' def __init__(self): ''' Initialize GlobalKey class. ''' super(GlobalKey, self).__init__() self.daemon = True self.display = Display() self.root = self.display.screen().root self._binding_map = {} self.stop = False 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 bind(self, binding_string, action): ''' Binding keymap with given action. @param binding_string: Keymap string, return by function `get_keyevent_name` of module dtk.ui.keymap. @param action: Callback. ''' # Get keybinding's keyval and modifiers. return keyval, modifiers = parse_keyevent_name(binding_string) # Get key code. keycode = gtk.gdk.keymap_get_default().get_entries_for_keyval( keyval)[0][0] # Binding key. self._binding_map[(keycode, modifiers)] = action # Make keybinding can response even user enable Num-Lock key. num_lock_modifiers = modifiers | gdk.MOD2_MASK self._binding_map[(keycode, num_lock_modifiers)] = action # Restart grab keybinding. self.regrab() def unbind(self, binding_string): ''' Unbind keymap. @param binding_string: Keymap string that return by function `get_keyevent_name` of module dtk.ui.keymap. ''' # Get keybinding. keyval, modifiers = parse_keyevent_name(binding_string) # Get key code. keycode = gtk.gdk.keymap_get_default().get_entries_for_keyval( keyval)[0][0] # Get modifiers with Num-Lock mask. num_lock_modifiers = modifiers | gdk.MOD2_MASK # Remove keybinding from binding map. regrab_flag = False if self._binding_map.has_key((keycode, modifiers)): del self._binding_map[(keycode, modifiers)] regrab_flag = True # Try remove key binding (with Num-Lock mask) from binding map. if self._binding_map.has_key((keycode, num_lock_modifiers)): del self._binding_map[(keycode, num_lock_modifiers)] regrab_flag = True if regrab_flag: self.regrab() def grab(self): ''' Grab key. ''' for (keycode, modifiers) in self._binding_map.keys(): try: self.root.grab_key(keycode, int(modifiers), True, X.GrabModeAsync, X.GrabModeSync) except Exception, e: print "function grab got error: %s" % (e) traceback.print_exc(file=sys.stdout)
else: win32api.mouse_event( event | win32defines.MOUSEEVENTF_ABSOLUTE, coords[0], coords[1], dw_data) time.sleep(Timings.after_clickinput_wait) if ('control' in keyboard_keys) and key_up: keyboard.VirtualKeyAction(keyboard.VK_CONTROL, down=False).run() if ('shift' in keyboard_keys) and key_up: keyboard.VirtualKeyAction(keyboard.VK_SHIFT, down=False).run() if ('alt' in keyboard_keys) and key_up: keyboard.VirtualKeyAction(keyboard.VK_MENU, down=False).run() else: _display = Display() def _perform_click_input(button='left', coords=(0, 0), button_down=True, button_up=True, double=False, wheel_dist=0, pressed="", key_down=True, key_up=True): """Perform a click action using Python-xlib""" #Move mouse x = int(coords[0]) y = int(coords[1]) fake_input(_display, X.MotionNotify, x=x, y=y)
def __hooked_class_init(cls): cls._display = Display() cls._root_window = cls._display.screen().root
# Python 2/3 compatibility. from __future__ import print_function import sys import os # Change path so we find Xlib from pprint import pprint from Xlib.display import Display from Xlib.ext.nvcontrol import Gpu, Cooler sys.path.append(os.path.join(os.path.dirname(__file__), '..')) if __name__ == '__main__': display = Display() # Check for extension if not display.has_extension('NV-CONTROL'): sys.stderr.write( '{}: server does not have the NV-CONTROL extension\n'.format( sys.argv[0])) ext = display.query_extension('NV-CONTROL') print(ext) sys.stderr.write("\n".join(display.list_extensions())) if ext is None: sys.exit(1) gpu = Gpu(0) fan = Cooler(0) perf_level = 3