You are not logged in.
I have a total of 4 keyboard layouts: us, ru, jp(hiragana), jp(katakana), that can be switched with Ctrl+Space hotkey:
setxkbmap -layout us,ru,jp_custom,jp_custom -variant workman,,hiragana,katakana -option grp:ctrl_space_toggle
Because of the JP layouts, switch from RU -> US requires pressing Ctrl+Space 3 times which can be really annoying sometimes, considering I rarely use JP layouts.
I wonder if I can set a distinct hotkeys for switching between RU, US and JP layouts accordingly, i.e. Ctrl+Space for US-RU and Alt+Shift for JP? Can it be achieved with XKB only?
Offline
Use "xdotool key ISO_First_Group" or "xdotool key ISO_Last_Group" to move to a defined point and then a sequence of "xdotool key ISO_Next_Group" or "xdotool key ISO_Prev_Group" to get to the desired position.
Online
Though `xev` recognizes ISO_Next_Group (and all other ISO_..._Group) press generated with `xdotool`, it's not changing the keyboard layout.
KeyPress event, serial 29, synthetic NO, window 0x3600001,
root 0x1db, subw 0x0, time 17571611, (443,920), root:(1727,928),
state 0x1, keycode 64 (keysym 0xfe08, ISO_Next_Group), same_screen YES,
XKeysymToKeycode returns keycode: 50
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 29, synthetic NO, window 0x3600001,
root 0x1db, subw 0x0, time 17571618, (443,920), root:(1727,928),
state 0x1, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 29, synthetic NO, window 0x3600001,
root 0x1db, subw 0x0, time 17571618, (443,920), root:(1727,928),
state 0x0, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
It appears that the ISO_Next_Group triggers Shift+Alt combination. Do I need to change the XKB configuration to make ISO_Next_Group work?
Offline
setxkbmap -print -query
Sanity check: this isn't a wayland session, is it?
Online
$ setxkbmap -print -query
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compat { include "complete" };
xkb_symbols { include "pc+us(workman)+ru:2+jp_custom(hiragana):3+jp_custom(katakana):4+inet(evdev)+group(ctrl_space_toggle):1+group(ctrl_space_toggle):2+group(ctrl_space_toggle):3+group(ctrl_space_toggle):4" };
xkb_geometry { include "pc(pc104)" };
};
rules: evdev
model: workman,,hiragana,katakana
layout: us,ru,jp_custom,jp_custom
variant: workman,,hiragana,katakana
options: grp:ctrl_space_toggle
Sanity check: this isn't a wayland session, is it?
No, it isn't
Offline
So next to the clearly wrong release event you're also not getting any "MappingNotify event"?
But ctrl+space principally works?? Does it generate the same kind of events?
Try https://wiki.archlinux.org/title/Xorg/K … tion_files instead of setxkbmap.
Online
With 00-keyboard.conf instead of setxkbmap I get these (xdotool key ISO_Next_Group):
MappingNotify event, serial 28, synthetic NO, window 0x0,
request MappingKeyboard, first_keycode 8, count 248
KeyPress event, serial 28, synthetic NO, window 0x3400001,
root 0x1db, subw 0x0, time 16166647, (-786,714), root:(498,722),
state 0x0, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 28, synthetic NO, window 0x3400001,
root 0x1db, subw 0x0, time 16166647, (-786,714), root:(498,722),
state 0x4, keycode 65 (keysym 0x20, space), same_screen YES,
XLookupString gives 1 bytes: (00) ""
XmbLookupString gives 1 bytes: (00) ""
XFilterEvent returns: False
KeyRelease event, serial 29, synthetic NO, window 0x3400001,
root 0x1db, subw 0x0, time 16166653, (-786,714), root:(498,722),
state 0x4, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 29, synthetic NO, window 0x3400001,
root 0x1db, subw 0x0, time 16166653, (-786,714), root:(498,722),
state 0x0, keycode 65 (keysym 0x20, space), same_screen YES,
XLookupString gives 1 bytes: (20) " "
XFilterEvent returns: False
I see that there are space keypresses instead of the ISO_Next_Group which appear when I press ctrl+space:
KeyPress event, serial 28, synthetic NO, window 0x3400001,
root 0x1db, subw 0x0, time 16227486, (-383,859), root:(901,867),
state 0x0, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 28, synthetic NO, window 0x3400001,
root 0x1db, subw 0x0, time 16227552, (-383,859), root:(901,867),
state 0x4, keycode 65 (keysym 0xfe08, ISO_Next_Group), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0x3400001,
root 0x1db, subw 0x0, time 16227640, (-383,859), root:(901,867),
state 0x2004, keycode 65 (keysym 0xfe08, ISO_Next_Group), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 28, synthetic NO, window 0x3400001,
root 0x1db, subw 0x0, time 16227687, (-383,859), root:(901,867),
state 0x2004, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
Offline
Grrr…
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/XKBlib.h>
int main(int argc, char **argv) {
if (argc != 2) {
printf("Usage: %s list|<match>\nMatch is lazy, the first layout beginning with the token is chosen\n", argv[0]);
return False;
}
Display* dpy = XOpenDisplay(NULL);
XkbDescRec* kbdDescPtr = XkbAllocKeyboard();
if (!kbdDescPtr) {
printf("Failed to get keyboard description.\n");
return False;
}
kbdDescPtr->dpy = dpy;
int deviceId = XkbUseCoreKbd;
/* if (deviceId != XkbUseCoreKbd) {
kbdDescPtr->device_spec = deviceId;
} */
XkbGetControls(dpy, XkbAllControlsMask, kbdDescPtr);
XkbGetNames(dpy, XkbSymbolsNameMask|XkbGroupNamesMask, kbdDescPtr);
Atom* groupSource = kbdDescPtr->names->groups;
int groupCount = 0;
if (kbdDescPtr->ctrls) {
groupCount = kbdDescPtr->ctrls->num_groups;
} else {
while (groupCount < XkbNumKbdGroups && groupSource[groupCount]) {
++groupCount;
}
}
Atom* tmpGroupSource = kbdDescPtr->names->groups;
Atom curGroupAtom;
char* groupName;
int printList = (strncmp(argv[1], "list", 4) == 0);
for (int i = 0; i < groupCount; i++) {
if ((curGroupAtom = tmpGroupSource[i]) != None) {
groupName = XGetAtomName(dpy, curGroupAtom);
if (!groupName) {
continue;
}
if (printList) {
printf("%s\n", groupName);
} else if (strncmp(argv[1], groupName, strlen(argv[1])) == 0) {
printf ("Setting %s\n", groupName);
// printf ("%d\n", i);
XkbLockGroup(dpy, deviceId, i);
XFree(groupName);
XCloseDisplay(dpy);
return True;
}
XFree(groupName);
}
}
XCloseDisplay(dpy);
return printList;
}
gcc -lX11 -o xkbgroup xkbgroup.c
Online