3

I am using pykeylogger and want to extend it a little bit by adding information about current keyboard layout selected (right now you know from log what buttons are pressed assuming US qwerty).

For windows system it is looks like:

def get_locale(self):
        if os.name == 'nt':
            w = user32.GetForegroundWindow() 
            tid = user32.GetWindowThreadProcessId(w, 0) 
            return hex(user32.GetKeyboardLayout(tid))

to get hex code of layout (like 0x409409) that is fine for me as I basically want to distinguish one layout from another.

I would appreciate if you give me a solution for posix (for example ubuntu) system.

2
  • Try /etc/default/keyboard/ Commented Sep 23, 2013 at 9:04
  • @DanielB do you mean that I can read from /etc/default/keyboard and thus get layout for current application in focus? For me sudo cat /etc/default/keyboard command returns same content for any current layout Commented Sep 23, 2013 at 10:35

2 Answers 2

2

setxkbmap -print

xkb_keymap {
xkb_keycodes  { include "evdev+aliases(qwerty)" };
xkb_types     { include "complete"  };
xkb_compat    { include "complete"  };
xkb_symbols   { include "pc+gb+gr(simple):2+inet(evdev)+terminate(ctrl_alt_bksp)"   };
xkb_geometry  { include "pc(pc105)" };
};

xkb_keycodes { include "evdev+aliases(qwerty)" };

xkb_symbols { include "pc+gb+ gr (simple):2+inet(evdev)+terminate(ctrl_alt_bksp)" };

Sign up to request clarification or add additional context in comments.

3 Comments

yes setxkbmap -print gives me the list of installed layouts but how can I detect which one is active right now?
if you want to know whats actice right now you can use xkb-switch. link. example: xkb-switch --> gr(simple), xkb-switch --> gb
well its not in python but you can make a small script that wgets it untars it cd in it and build it. then you can popen call it. not sure if thats the best solution but it will work.
2

I have found following that works for me:

  1. compiled xkblayout-state and moved executable to directory in PATH
  2. rewrote get_locale as
import os
if os.name == 'posix':    
    from subprocess import check_output
elif os.name == 'nt':
    import win32api, win32con, win32process
    from ctypes import windll
    user32 = windll.user32

def get_locale(self):
    if os.name == 'nt':
        w = user32.GetForegroundWindow() 
        tid = user32.GetWindowThreadProcessId(w, 0) 
        return hex(user32.GetKeyboardLayout(tid))
    elif os.name == 'posix':
        return check_output(["xkblayout-state", "print", "%s"])

and now get_locale returns nice letter code of current locale (i.e. 'us' for qwerty) in Ubuntu.

Yes, output is different in each OS and I will definitely rewrite this function in the future. But for now I have achieved my goal to be able to detect keyboard layout at windows and unix machines.

Another option is to use xset utility like xset -q | grep -A 0 'LED' | cut -c59-67 (see this question for details) but I think that it's little bit fishy especially if you have more than two layouts (like I do) - scroll LED is on for all except default layout.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.