Check if a key is pressed with python (daemon in background)

I created a python script in which the event should be executed every time I press Super (or WinKey) on my keyboard.

How to achieve this if the python process is not "focused" - since it is running in the background, waiting for a key to be pressed to execute the event?

I saw a lot of messages on the Internet that showed how to read the input, but they have everything necessary for the process to "focus", and no one showed me how to capture Super (or WinKey) using a python script.

I am running Ubuntu 9.10.

+4
source share
4 answers

This allows me to get the state of the modifiers on my * nix system.

#!/usr/bin/env python # -*- coding: utf-8 -*- """OSD Neo2 ======== On screen display for learning the keyboard layout Neo2 Copyright (c) 2009 Martin Zuther (http://www.mzuther.de/) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Thank you for using free software! """ # Here follows a plea in German to keep the comments in English so # that you may understand them, dear visitor ... # # Meine Kommentare in den Quellcodes sind absichtlich auf Englisch # gehalten, damit Leute, die im Internet nach Lösungen suchen, den # Code nachvollziehen können. Daher bitte ich darum, zusätzliche # Kommentare ebenfalls auf Englisch zu schreiben. Vielen Dank! import ctypes import ctypes.util import gettext import os import types # initialise localisation settings module_path = os.path.dirname(os.path.realpath(__file__)) gettext.bindtextdomain('OSDneo2', os.path.join(module_path, 'po/')) gettext.textdomain('OSDneo2') _ = gettext.lgettext class SimpleXkbWrapper: """ Far from complete wrapper for the "X Keyboard Extension" (well, to be honest, it just wraps what I need using Python "ctypes" library <g>). """ # set this to true to get lots of debugging information (and # considerably slow things down) DEBUG_XKB = False # "C defines" from file /usr/include/X11/extensions/XKB.h (Ubuntu 9.04): # $XFree86: xc/include/extensions/XKB.h,v 1.5tsi Exp $ # # XkbUseCoreKbd is used to specify the core keyboard without having to # look up its X input extension identifier. XkbUseCoreKbd = 0x0100 # "C defines" from file /usr/include/X11/XKBlib.h (Ubuntu 9.04): # $XFree86: xc/lib/X11/XKBlib.h,v 3.5 2003/04/17 02:06:31 dawes Exp $ # # # XkbOpenDisplay error codes XkbOD_Success = 0 XkbOD_BadLibraryVersion = 1 XkbOD_ConnectionRefused = 2 XkbOD_NonXkbServer = 3 XkbOD_BadServerVersion = 4 # "C typedef" from file /usr/include/X11/extensions/XKBstr.h (Ubuntu 9.04): # $Xorg: XKBstr.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $ # # Common data structures and access macros # # typedef struct _XkbStateRec { # unsigned char group; # unsigned char locked_group; # unsigned short base_group; # unsigned short latched_group; # unsigned char mods; # unsigned char base_mods; # unsigned char latched_mods; # unsigned char locked_mods; # unsigned char compat_state; # unsigned char grab_mods; # unsigned char compat_grab_mods; # unsigned char lookup_mods; # unsigned char compat_lookup_mods; # unsigned short ptr_buttons; # } XkbStateRec,*XkbStatePtr; class XkbStateRec(ctypes.Structure): _fields_ = [ ('group', ctypes.c_ubyte), \ ('locked_group', ctypes.c_ubyte), \ ('base_group', ctypes.c_ushort), \ ('latched_group', ctypes.c_ushort), \ ('mods', ctypes.c_ubyte), \ ('base_mods', ctypes.c_ubyte), \ ('latched_mods', ctypes.c_ubyte), \ ('locked_mods', ctypes.c_ubyte), \ ('compat_state', ctypes.c_ubyte), \ ('grab_mods', ctypes.c_ubyte), \ ('compat_grab_mods', ctypes.c_ubyte), \ ('lookup_mods', ctypes.c_ubyte), \ ('compat_lookup_mods', ctypes.c_ubyte), \ ('ptr_buttons', ctypes.c_ushort) \ ] # "C defines" from file /usr/include/X11/Xh (Ubuntu 9.04): # $XFree86: xc/include/Xh,v 1.6 2003/07/09 15:27:28 tsi Exp $ # # Key masks. Used as modifiers to GrabButton and GrabKey, results of # QueryPointer, state in various key-, mouse-, and button-related # events. ShiftMask = 1 LockMask = 2 ControlMask = 4 Mod1Mask = 8 Mod2Mask = 16 Mod3Mask = 32 Mod4Mask = 64 Mod5Mask = 128 def __init__(self): # dynamically link to "X Keyboard Extension" library library_xf86misc = ctypes.CDLL(ctypes.util.find_library('Xxf86misc')) # print debugging information if requested if self.DEBUG_XKB: print print ' %s' % library_xf86misc # define "ctypes" prototype for the function # # Display *XkbOpenDisplay(display_name, event_rtrn, error_rtrn, # major_in_out, minor_in_out, reason_rtrn) # # char * display_name; # int * event_rtrn; # int * error_rtrn; # int * major_in_out; # int * minor_in_out; # int * reason_rtrn; paramflags_xkbopendisplay = \ (1, 'display_name'), \ (2, 'event_rtrn'), \ (2, 'error_rtrn'), \ (3, 'major_in_out'), \ (3, 'minor_in_out'), \ (2, 'reason_rtrn') prototype_xkbopendisplay = ctypes.CFUNCTYPE( \ ctypes.c_uint, \ ctypes.c_char_p, \ ctypes.POINTER(ctypes.c_int), \ ctypes.POINTER(ctypes.c_int), \ ctypes.POINTER(ctypes.c_int), \ ctypes.POINTER(ctypes.c_int), \ ctypes.POINTER(ctypes.c_int) \ ) # set-up function (low-level) self.__XkbOpenDisplay__ = prototype_xkbopendisplay( \ ('XkbOpenDisplay', library_xf86misc), \ paramflags_xkbopendisplay \ ) # define error handler def errcheck_xkbopendisplay(result, func, args): # print debugging information if requested if self.DEBUG_XKB: print print ' [XkbOpenDisplay]' print ' Display: %#010x' % result print ' display_name: %s' % args[0].value print ' event_rtrn: %d' % args[1].value print ' error_rtrn: %d' % args[2].value print ' major_in_out: %d' % args[3].value print ' minor_in_out: %d' % args[4].value print ' reason_rt: %d' % args[5].value # function didn't return display handle, so let see why # not if result == 0: # values were taken from file /usr/include/X11/XKBlib.h (Ubuntu 9.04): # $XFree86: xc/lib/X11/XKBlib.h,v 3.5 2003/04/17 02:06:31 dawes Exp $ # error_id = args[5].value if error_id == self.XkbOD_Success: error_name = 'XkbOD_Success' elif error_id == self.XkbOD_BadLibraryVersion: error_name = 'XkbOD_BadLibraryVersion' elif error_id == self.XkbOD_ConnectionRefused: error_name = 'XkbOD_ConnectionRefused' elif error_id == self.XkbOD_NonXkbServer: error_name = 'XkbOD_NonXkbServer' elif error_id == self.XkbOD_BadServerVersion: error_name = 'XkbOD_BadServerVersion' else: error_name = _('undefined') error_message = \ _('"XkbOpenDisplay" reported an error (%(error_name)s).') % \ {'error_name': error_name} raise OSError(error_message) # return display handle and all function arguments return (ctypes.c_uint(result), args) # connect error handler to function self.__XkbOpenDisplay__.errcheck = errcheck_xkbopendisplay # define "ctypes" prototype for the function # # Bool XkbGetState(display, device_spec, state_return) # # Display * display; # unsigned int device_spec; # XkbStatePtr state_return; paramflags_xkbgetstate = \ (1, 'display'), \ (1, 'device_spec'), \ (3, 'state_return') prototype_xkbgetstate = ctypes.CFUNCTYPE( \ ctypes.c_int, # Python 2.5 doesn't yet know c_bool \ ctypes.c_uint, \ ctypes.c_uint, \ ctypes.POINTER(self.XkbStateRec) \ ) # set-up function (low-level) self.__XkbGetState__ = prototype_xkbgetstate( \ ('XkbGetState', library_xf86misc), \ paramflags_xkbgetstate \ ) # define error handler def errcheck_xkbgetstate(result, func, args): # print debugging information if requested if self.DEBUG_XKB: print print ' [XkbGetState]' print ' Status: %s' % result print ' display: %#010x' % args[0].value print ' device_spec: %d\n' % args[1].value print ' state_return.group: %d' % \ args[2].group print ' state_return.locked_group: %d' % \ args[2].locked_group print ' state_return.base_group: %d' % \ args[2].base_group print ' state_return.latched_group: %d' % \ args[2].latched_group print ' state_return.mods: %d' % \ args[2].mods print ' state_return.base_mods: %d' % \ args[2].base_mods print ' state_return.latched_mods: %d' % \ args[2].latched_mods print ' state_return.locked_mods: %d' % \ args[2].locked_mods print ' state_return.compat_state: %d' % \ args[2].compat_state print ' state_return.grab_mods: %d' % \ args[2].grab_mods print ' state_return.compat_grab_mods: %d' % \ args[2].compat_grab_mods print ' state_return.lookup_mods: %d' % \ args[2].lookup_mods print ' state_return.compat_lookup_mods: %d' % \ args[2].compat_lookup_mods print ' state_return.ptr_buttons: %d\n' % \ args[2].ptr_buttons print ' Mask mods base_mods latched_mods locked_mods compat_state' print ' --------------------------------------------------------------------------' print ' ShiftMask %-5s %-5s %-5s %-5s %-5s' % \ ((args[2].mods & self.ShiftMask) != 0, \ (args[2].base_mods & self.ShiftMask) != 0, \ (args[2].latched_mods & self.ShiftMask) != 0, \ (args[2].locked_mods & self.ShiftMask) != 0, \ (args[2].compat_state & self.ShiftMask) != 0) print ' LockMask %-5s %-5s %-5s %-5s %-5s' % \ ((args[2].mods & self.LockMask) != 0, \ (args[2].base_mods & self.LockMask) != 0, \ (args[2].latched_mods & self.LockMask) != 0, \ (args[2].locked_mods & self.LockMask) != 0, \ (args[2].compat_state & self.LockMask) != 0) print ' ControlMask %-5s %-5s %-5s %-5s %-5s' % \ ((args[2].mods & self.ControlMask) != 0, \ (args[2].base_mods & self.ControlMask) != 0, \ (args[2].latched_mods & self.ControlMask) != 0, \ (args[2].locked_mods & self.ControlMask) != 0, \ (args[2].compat_state & self.ControlMask) != 0) print ' Mod1Mask %-5s %-5s %-5s %-5s %-5s' % \ ((args[2].mods & self.Mod1Mask) != 0, \ (args[2].base_mods & self.Mod1Mask) != 0, \ (args[2].latched_mods & self.Mod1Mask) != 0, \ (args[2].locked_mods & self.Mod1Mask) != 0, \ (args[2].compat_state & self.Mod1Mask) != 0) print ' Mod2Mask %-5s %-5s %-5s %-5s %-5s' % \ ((args[2].mods & self.Mod2Mask) != 0, \ (args[2].base_mods & self.Mod2Mask) != 0, \ (args[2].latched_mods & self.Mod2Mask) != 0, \ (args[2].locked_mods & self.Mod2Mask) != 0, \ (args[2].compat_state & self.Mod2Mask) != 0) print ' Mod3Mask %-5s %-5s %-5s %-5s %-5s' % \ ((args[2].mods & self.Mod3Mask) != 0, \ (args[2].base_mods & self.Mod3Mask) != 0, \ (args[2].latched_mods & self.Mod3Mask) != 0, \ (args[2].locked_mods & self.Mod3Mask) != 0, \ (args[2].compat_state & self.Mod3Mask) != 0) print ' Mod4Mask %-5s %-5s %-5s %-5s %-5s' % \ ((args[2].mods & self.Mod4Mask) != 0, \ (args[2].base_mods & self.Mod4Mask) != 0, \ (args[2].latched_mods & self.Mod4Mask) != 0, \ (args[2].locked_mods & self.Mod4Mask) != 0, \ (args[2].compat_state & self.Mod4Mask) != 0) print ' Mod5Mask %-5s %-5s %-5s %-5s %-5s' % \ ((args[2].mods & self.Mod5Mask) != 0, \ (args[2].base_mods & self.Mod5Mask) != 0, \ (args[2].latched_mods & self.Mod5Mask) != 0, \ (args[2].locked_mods & self.Mod5Mask) != 0, \ (args[2].compat_state & self.Mod5Mask) != 0) # return function return value and all function arguments return (result, args) # connect error handler to function self.__XkbGetState__.errcheck = errcheck_xkbgetstate # define high-level version of "XkbOpenDisplay" def XkbOpenDisplay(self, display_name, major_in_out, minor_in_out): # if we don't do type checking, nobody ever will assert (type(display_name) == types.NoneType) or \ (type(display_name) == types.StringType) assert type(major_in_out) == types.IntType assert type(minor_in_out) == types.IntType # convert function arguments to "ctypes", ... __display_name__ = ctypes.c_char_p(display_name) __major_in_out__ = ctypes.c_int(major_in_out) __minor_in_out__ = ctypes.c_int(minor_in_out) # ... call low-level function ... ret = self.__XkbOpenDisplay__(__display_name__, __major_in_out__, \ __minor_in_out__) # ... and return converted return value and function arguments return {'display_handle': ret[0].value, \ 'server_major_version': ret[1][3].value, \ 'server_minor_version': ret[1][4].value} # define high-level version of "XkbGetState" def XkbGetState(self, display_handle, device_spec): # if we don't do type checking, nobody ever will assert type(display_handle) == types.LongType assert type(device_spec) == types.IntType # convert function arguments to "ctypes", ... __display_handle__ = ctypes.c_uint(display_handle) __device_spec__ = ctypes.c_uint(device_spec) __xkbstaterec__ = self.XkbStateRec() # ... call low-level function ... ret = self.__XkbGetState__(__display_handle__, __device_spec__, \ __xkbstaterec__) # ... and return converted function argument xkbstaterec = ret[1][2] return xkbstaterec # extract modifier status using bitmasks def ExtractLocks(self, xkbstaterec): return {'group': xkbstaterec.group, \ 'shift': \ (xkbstaterec.base_mods & self.ShiftMask) != 0, \ 'shift_lock': \ (xkbstaterec.locked_mods & self.ShiftMask) != 0, \ 'lock': \ (xkbstaterec.base_mods & self.LockMask) != 0, \ 'lock_lock': \ (xkbstaterec.locked_mods & self.LockMask) != 0, \ 'control': \ (xkbstaterec.base_mods & self.ControlMask) != 0, \ 'control_lock': \ (xkbstaterec.locked_mods & self.ControlMask) != 0, \ 'mod1': \ (xkbstaterec.base_mods & self.Mod1Mask) != 0, \ 'mod1_lock': \ (xkbstaterec.locked_mods & self.Mod1Mask) != 0, \ 'mod2': \ (xkbstaterec.base_mods & self.Mod2Mask) != 0, \ 'mod2_lock': \ (xkbstaterec.locked_mods & self.Mod2Mask) != 0, \ 'mod3': \ (xkbstaterec.base_mods & self.Mod3Mask) != 0, \ 'mod3_lock': \ (xkbstaterec.locked_mods & self.Mod3Mask) != 0, \ 'mod4': \ (xkbstaterec.base_mods & self.Mod4Mask) != 0, \ 'mod4_lock': \ (xkbstaterec.locked_mods & self.Mod4Mask) != 0, \ 'mod5': \ (xkbstaterec.base_mods & self.Mod5Mask) != 0, \ 'mod5_lock': \ (xkbstaterec.locked_mods & self.Mod5Mask) != 0} 

To call state in a dictionary from another file, just call from FILENAME import * and do the following:

 # simple demonstration of this wrapper xkb = SimpleXkbWrapper() # initialise wrapper for the X Keyboard Extension (v1.0) and # open connection to default X display display_name = None major_in_out = 1 minor_in_out = 0 try: ret = xkb.XkbOpenDisplay(display_name, major_in_out, minor_in_out) except OSError, error: print print ' Error: %s' % error print exit(1) # ... get modifier state of core keyboard ... display_handle = ret['display_handle'] device_spec = xkb.XkbUseCoreKbd xkbstaterec = xkb.XkbGetState(display_handle, device_spec) # ... and extract and the information we need print xkb.ExtractLocks(xkbstaterec) 

Welcomes the creator, whose code can be found here , and Jason Oriendorfl to draw my attention to this.

+5
source

My previous answer seemed to be completely wrong, sorry. I think the correct approach would be to read from / dev / input / event 1 (?)

This short test showed scancodes for me, even if the terminal had no focus:

 from struct import unpack port = open("/dev/input/event1","rb") while 1: a,b,c,d = unpack("4B",port.read(4)) print a,b,c,d 

I don't know if / dev / input / event 1 is always a keyboard or how to determine which one, but at least it worked for me

+2
source

If you need to work on Linux, I think you need to track X events somehow.

You can see all the events if you run the "xev" command - so I'm sure X provides an interface for all events. A quick googling search finds the Python X library , which probably gives you the material you need.

You can download it here .

0
source

You can use PyUserInput for this purpose, it is a cross-platform solution compatible in your case with X11.

Super example:

 from pykeyboard import PyKeyboardEvent class MonitorSuper(PyKeyboardEvent): def tap(self, keycode, character, press): '''Monitor Super key.''' if character == 'Super_L': if press: print('Super pressed') else: print('Super released') mon = MonitorSuper() mon.run() 
0
source

All Articles