How do I get current keyboard layout?
Solution 1
Maybe this is version dependent, but on my machine that uses setxkbmap
1.3.0 the following command works:
setxkbmap -query | grep layout
Note that depending on your need it may be useless to know only the layout : for instance the Dvorak variant of the US layout is quite different than the default QWERTY. The -query
option of setxkbmap
gives both the layout and the variant, as different fields :
$ setxkbmap -query
rules: evdev
model: default
layout: fr
variant: bepo
options: grp:alt_shift_toggle
Solution 2
Yes THERE IS a command line tool that does what you want! I just discovered it 10min ago :)
Look at here: https://github.com/nonpop/xkblayout-state
xkblayout-state print "%s"
does exactly what you want (it doesn't output an end of line, so add ; echo
if you need).
run the tool without parameters for the help.
Solution 3
There is xkb-switch which is described thus:
xkb-switch is a C++ program that allows to query and change the XKB layout state.
https://github.com/ierton/xkb-switch
Or, following nozimica's suggestion, you could use:
setxkbmap -print | awk -F"+" '/xkb_symbols/ {print $2}'
From this thread on the Arch Linux boards: https://bbs.archlinux.org/viewtopic.php?pid=539406
Solution 4
Use this to get the code for the current layout:
$(xset -q|grep LED| awk '{ print $10 }')
This might needs to be converted to a form you want, like:
case "$(xset -q|grep LED| awk '{ print $10 }')" in
"00000002") KBD="English" ;;
"00001002") KBD="Thai" ;;
*) KBD="unknown" ;;
esac
Solution 5
The answers so far did not work for me. I use setkbmap
with two layouts english and czech so any -print
or -query
will always return the two. Grepping the LED status for xset -q
does not work either since that one shows the status of all keyboard leds.
The best so far was to quickly write this small utility: https://gist.github.com/fikovnik/ef428e82a26774280c4fdf8f96ce8eeb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/XKBlib.h>
#include <X11/extensions/XKBrules.h>
int main(int argc, char **argv) {
Display *dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
XkbStateRec state;
XkbGetState(dpy, XkbUseCoreKbd, &state);
XkbDescPtr desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
char *group = XGetAtomName(dpy, desc->names->groups[state.group]);
printf("Full name: %s\n", group);
XkbRF_VarDefsRec vd;
XkbRF_GetNamesProp(dpy, NULL, &vd);
char *tok = strtok(vd.layout, ",");
for (int i = 0; i < state.group; i++) {
tok = strtok(NULL, ",");
if (tok == NULL) {
return 1;
}
}
printf("Layout name: %s\n", tok);
return 0;
}
and compile using
gcc -I/usr/include getxkblayout.c -lX11 -lxkbfile
Related videos on Youtube
Andrew
Updated on September 18, 2022Comments
-
Andrew over 1 year
I'm wondering if there is any command line tool that returns the current keyboard layout.
I have
XkbLayout
set tous, ru
.Update:
setxkbmap
returns layout settings, not selected layout. E.g.:$ setxkbmap -print | grep xkb_symbols xkb_symbols { include "pc+us+ru:2+inet(evdev)+capslock(grouplock)+terminate(ctrl_alt_bksp)" };
It will return the same result no matter what the current layout is.
-
neydroydrec over 12 yearsI am not really good at D-Bus, but it should be easy to track the current keyboard layout using it I think. Although it may not be able to do so if there is no active switch.
-
-
Andrew about 13 yearsit returns overall keyboard settings, not current layout (us or ru)
-
stefan about 13 yearsExecute it well, as @jasonwryan states if you analyze carefully that line, into it resides your layout. In my case it is
latam
. -
Andrew about 13 yearsjasonwryan version just output a part of string after '+',
xkb_symbols
value doesn't depend on selected layout, I always get 'us' -
Andrew about 13 yearsThanks,
xkb-switch
works fine, but I hope that there was more portable solution -
neydroydrec over 12 years@Andrew: yes it's kind of odd there is no simple way to get the current layout.
-
l0b0 over 12 yearsI get
00000002
even though my layout is "USA Dvorak international". Language is not enough... -
sastanin over 11 yearsIt doesn't help if there are three or more layouts. The second and the third layouts give the same value
00001004
on my machine. -
sastanin over 11 yearsIt prints only the first layout in the list, not the current one.
-
MusiGenesis about 11 years
-query
was added in setxkbmap 1.2.0 -
xlembouras almost 10 yearsI like this one, I think you can narrow it down to 8 chars.
c59-66
. -
terdon over 8 yearsYour
setxkbmap
doesn't show the currently active layout when more than one layout is defined. -
erik about 8 yearsYou get the current layouts and variants and many additional info with
setxkbmap -print -verbose 10
-
erik about 8 yearsTo set it, for example both layouts cz and us, the latter with variant dvorak (for a 104 key keyboard), use
setxkbmap -model pc104 -layout cz,us -variant ,dvorak
-
andras.tim almost 8 yearsHow can I detect my keymap, when I use language toggle by setxkbmap?
$ setxkbmap -v
>>Trying to build keymap using the following components: | keycodes: evdev+aliases(qwerty) | types: complete | compat: complete+ledscroll(group_lock) | symbols: pc+us+hu:2+inet(evdev)+group(alt_shift_toggle)+compose(rwin)+terminate(ctrl_alt_bksp) | geometry: pc(pc105)
in this case I got everytime "us" -
fikovnik over 6 yearsThis will not work reliably - you need to use a mask since the LED indicates the status of the keyboard led buttons as well.
-
nephewtom over 4 yearsIn which package is
XKBrules.h
contained?x11proto-dev
does not contain it. -
fikovnik over 4 years@nephewtom libxkbfile
-
xeruf almost 4 yearsdoesn't let you know the active one for multiple layouts, which is what the OP asked. Bummer this got to the top.
-
xeruf almost 4 yearsdoesn't show the currently active layout when more than one layout is defined, only shows the first
-
invot over 3 yearsAt my side
setxkbmap -query | awk '/layout/ {print $2}'
givesus,de,us
. It does not return the current keyboard layout but gives the available keyboard layouts. And aftersetxkbmap us
theWin+SPC
no more toggles to German, so this approach has bad sideffects. -
invot over 3 yearsI'd wish there would be some generic solution which "just works"(tm) on any X11 desktop you can imagine, like KDE, GNOME and, say, WubbaLubbaDubDub.
-
ali b over 3 years@Tino It print those languages because either you (with command
setxkbmap -layout us,de
) or the system at the startup set it like so. you can put the commandsetxkbmap <default language>
in the startup scripts like.xinitrc
or.xprofile
to fix it. Afterwards when you query for current keyboard layout, it'll show you one layout.Win+SPC
does not work becauseSPC
in German is different character from that in Eng. So when you switch German the combination won't work.So in this way, the best solution is to use a hotkey with non-printable characters likeAlt-Esc
orAlt-shift
etc. -
Flow over 3 yearsThis is one of the reasons I don't recommend using
xmodmap
, usesetxkbmap
andxkbcomp
instead.