Comments (17)
xev uses the XLookupString()
function from Xlib. The keysym and string it displays are the one returned by XLookupString()
.
The behavior you describe is implemented in Xlib by a hidden library control called XkbLC_ControlFallback
(enabled by default).
xkbcommon implements this behavior, but not for keysyms, only the strings, i.e. xkb_state_key_get_one_sym
is not affected, xkb_state_key_get_utf8()
is affected. Adding it for strings was necessary for backward compatibility. No one asked for it to be added for keysyms as well.
I am inclined to not support this. In general, adding these special cases just makes it harder for an application to get things working in the hand, since it has to handle a bunch of obscure edge-cases. This solution is not general; for example, in the terminal example it might (arguably) fix the problem with Ctrl-a
but it won't fix it for Alt-a
. So I think the application can handle this on its own, if it wants to.
BTW, the switching-language-breaks-shortcuts problem is well known, and is handled by both big toolkits (GTK and Qt) at least. A terminal has its own input pipeline though.
from libxkbcommon.
Thanks for the answer, @kovidgoyal what do you think about this argument for implementing the fix in the kitty application itself?
from libxkbcommon.
This really doesn't seem like something that every application should have to workaround. And there really is no good way to workaround it. You want ctrl+X in the russian layout to generate Ctrl+. Somebody else might want it to generate Arabic Aleph. This kind of thing belongs in the layout definition,or if that is not possible, then via XCompose rules. Applications should not be second guessing what keys the OS wants them to generate, that way lies chaos. It means that it is not possible for users to configure their keyboards in one cetral place, instead they have to somehow get every different application to do what they want, that is insanity.
from libxkbcommon.
From the link that you provided:
# Ctrl+C in English layout
scancode: 0x25 release: 0 clean_sym: Control_L composed_sym: Control_L mods: numlock glfw_key: LEFT CONTROL
scancode: 0x36 release: 0 clean_sym: c composed_sym: c mods: ctrl+numlock glfw_key: C
scancode: 0x36 release: 1 clean_sym: c mods: ctrl+numlock glfw_key: C
scancode: 0x25 release: 1 clean_sym: Control_L mods: ctrl+numlock glfw_key: LEFT CONTROL
# Ctrl+C in Russian layout
scancode: 0x25 release: 0 clean_sym: Control_L composed_sym: Control_L mods: numlock glfw_key: LEFT CONTROL
scancode: 0x36 release: 0 clean_sym: Cyrillic_es composed_sym: Cyrillic_es mods: ctrl+numlock glfw_key: UNKNOWN
scancode: 0x36 release: 1 clean_sym: Cyrillic_es mods: ctrl+numlock glfw_key: UNKNOWN
scancode: 0x25 release: 1 clean_sym: Control_L mods: ctrl+numlock glfw_key: LEFT CONTROL
Shouldn't the application be using the key code scancode to test shortcuts, instead?
from libxkbcommon.
For me as a user this would be ideal, e.g. I already use such approach in my i3wm
key bindings and I'm happy that my shortcuts consistently work regardless of currently active layout (in other words, I configure Ctrl+36 instead of Ctrl+C). However @kovidgoyal said this would make it impossible to use compose keys to enter non-english text — I confess I still don't understand the reason 100%, so I'll let him describe the details if necessary.
from libxkbcommon.
For me as a user this would be ideal, e.g. I already use such approach in my i3wm key bindings and I'm happy that my shortcuts consistently work regardless of currently active layout (in other words, I configure Ctrl+36 instead of Ctrl+C)
Yes, that's what every other application does. GTK and SDL applications for example. Keysyms or the composed string shouldn't be used for testing shortcuts.
from libxkbcommon.
This really doesn't seem like something that every application should have to workaround.
Shortcuts are not a concept in XKB. Shortcuts are an application-level concept. Different applications want different things (for the same user). To use your example, Application A wants ctrl+X in the russian layout to generate Ctrl+. Application B might want it to generate Arabic Aleph
Yes, that's what every other application does. GTK and SDL applications for example.
I don't know about SDL, but GTK and Qt use keysyms.
Keysyms or the composed string shouldn't be used for testing shortcuts.
Using keycodes for shortcuts does not work well in general. For example, "Ctrl-S" is the universally accepted shortcut for "Save"; if you configure your qwerty keyboard with a dvorak layout, it should still be "Ctrl-S" (here I mean the key that generates "S" in the dvorak layout).
from libxkbcommon.
Indeed, it is to support people with layouts like dvorak that kitty uses keysyms not keycodes. To me it is logical that if you press the key X and get S output as text, you should be able to press the key Ctrl+X and get the shortcut Ctrl+S not Ctrl+X
As I said before, it is not possible for an application to figure out what the user wants. It is up to the user to configure their keyboard layout to generate the logical keypresses they intend, with and without modifiers. No other approach can possibly hope to be consistent or logical.
from libxkbcommon.
Using keycodes for shortcuts does not work well in general. For example, "Ctrl-S" is the universally accepted shortcut for "Save"; if you configure your qwerty keyboard with a dvorak layout, it should still be "Ctrl-S" (here I mean the key that generates "S" in the dvorak layout).
Sorry, I meant scancode there.
from libxkbcommon.
Scancodes are different according to kitty's debug mode:
# QWERTY, pressing "c" (bottom row, third key from the left)
scancode: 0x36 release: 0 clean_sym: c composed_sym: c text: c mods: numlock glfw_key: C
scancode: 0x36 release: 1 clean_sym: c mods: numlock glfw_key: C
# Dvorak, pressing "c" (top row, the key right under "8" and "9")
scancode: 0x1f release: 0 clean_sym: c composed_sym: c text: c mods: numlock glfw_key: C
scancode: 0x1f release: 1 clean_sym: c mods: numlock glfw_key: C
Maybe the solution is to make application support both bindings with keysym and scancode? That's what i3wm
does for example, it has commands bindsym and bindcode. In other words, if I could have configured Ctrl+40 to do what Ctrl+D does, I would be happy.
I also tried to make use of XCompose as suggested, it's very difficult to find how to properly configure it, but trial and error helped achieve the following ~/.XCompose
:
include "%L"
! Ctrl <Cyrillic_ve>: "\033D" d
! Ctrl <Cyrillic_es>: "\033C" c
It does send Ctrl+C and Ctrl+D to the application when active layout is Russian, but (1) I can't figure out how to make a binding for Ctrl+Shift+C, i.e. what escape code corresponds to Shift, and (2) this magic with escape code "\033" feels a bit specific to terminal apps only, isn't it?
from libxkbcommon.
I suspect I was wrong about xcompose, the fundamental problem is that xcompose is designed to output text, not key presses, so there is no way to represent a mapping from <modifier>+key -> modifier+another_key
in it (at least as far as I can tell from reading it's absolutely pathetic documentation). Which makes it useless for your purpose.
That means you have to rely on the XKB layout, and that is, as far as I can tell an undocumented rat's nest. I dont see in principle why XKB is not able to map modifier+key to modifier+another key but I cannot find out how to do it, without spending indecent amounts of time on it, at least. Maybe somebody with more experience with XKB can point you in the right direction.
As for binding via keycode instead of keysym -- it is an ugly hack to a problem that is correctly solved at the system level. And it means that in order to bind the shortcuts, users have to now figure out what the scancode for their keys is. That is really unacceptable. Not to mention fragile. As far as I know there is no guarantee that scancodes are portable across systems, so tomorrow if you change your computer/kernel version/graphics stack/keyboard model all your shortcuts will stop working, and I will have to deal with the bug reports.
from libxkbcommon.
This was solved on application level without introducing the initially suggested hack, the application now makes use of xkb fallback keyboard layout. Thank you for your input, closing the ticket.
from libxkbcommon.
That's not a bad way to do it.
Another way to do it is, instead of looking at a fallback keymap, look at a fallback "ascii layout" in the same keymap. By "ascii layout" I mean a layout which generates English-like Latin keysyms. I believe that for this purpose, modern desktop environments ensure that there is always at least one "ascii layout", i.e. they add a hidden one if not present.
from libxkbcommon.
How would I I do that? It's not clear to me form the libxkb API docs. And would doing it modify the xkb_state or xkb_compose_state?
from libxkbcommon.
You can use a "scratch" xkb_state
(like qt does), or you can query the keymap directly if you don't need some info like consumed modifiers. Here is some old code I dug up which shows the idea:
static xkb_keysym_t
get_ascii(struct xkb_state *state, xkb_keycode_t keycode)
{
struct xkb_keymap *keymap;
xkb_layout_index_t num_layouts;
xkb_layout_index_t layout;
xkb_level_index_t level;
const xkb_keysym_t *syms;
int num_syms;
keymap = xkb_state_get_keymap(state);
num_layouts = xkb_keymap_num_layouts_for_key(keymap, keycode);
for (layout = 0; layout < num_layouts; layout++) {
level = xkb_state_key_get_level(state, keycode, layout);
num_syms = xkb_keymap_key_get_syms_by_level(keymap, keycode,
layout, level, &syms);
if (num_syms != 1)
continue;
if (syms[0] > 0 && xkb_keysym_to_utf32(syms[0]) < 128)
return syms[0];
}
return XKB_KEY_NoSymbol;
}
from libxkbcommon.
Interesting, thanks. However, I'm not sure how reliable that would be. A lot of my users use alternative desktop environments, such as i3 or other window managers/lightweight desktops. If as you say, it is the responsibility of the desktop environment to ensure there is always an ascii layout, it might not be the case that all of them do that. On the other hand, I dont know how often the default keyboard layout would match the keyboard the user has connected either. I wish there was some "official" way to do this.
The advantage with using the default keyboard layout is that it can be easily configured by the user. Hidden layouts automagically inserted by desktop environments, not so much. Incidentally how would the desktop environment know what the physical layout of the keyboard is, to insert such an ascii layout?
from libxkbcommon.
I agree you can't be completely sure that an ascii layout is present. In my experience (which might be biased), most users do have one. And for terminal users, not having one would be very hard. But again, I agree.
Incidentally how would the desktop environment know what the physical layout of the keyboard is, to insert such an ascii layout?
I don't know how they do it, but I'm willing to bet what's added is always the simple us
layout.
from libxkbcommon.
Related Issues (20)
- Fatal error when $XDG_CONFIG_HOME/XCompose is a directory HOT 4
- question: how to map from xcb key press/release event state field to xkb_mod_mask_t HOT 2
- Support for pointer keys? HOT 8
- no usable option to activate horizontal number keys on Azerty keyboard HOT 2
- ! include line in rules file does not require a newline HOT 1
- LatchGroup action is not supported
- Types parser allows type definitions with garbage
- xkb_keysym_from_name returns upper case keysym for case-insensitive match in a few cases HOT 4
- Set Caps Lock to non-toggling without assigning it to Shift key, or make "last used layout" shortcut HOT 9
- Compose key does not always work HOT 11
- Documentation on how to create/install custom layouts needed HOT 16
- ABI break in 1.6.0 HOT 2
- 1.7.0: test suite fails in two units HOT 6
- Using my custom keyboard layouts doesn't work as expected when using `grp:alt_space_toggle` or `grp:win_space_toggle` HOT 4
- How to read used keysyms/keycodes for each modifier_map HOT 7
- meson.build script broke detection of --version-script support in GNU ld, as NetBSD uses HOT 3
- support multiple actions for a key per level HOT 2
- Please increment minor DSO version
- Feature Request: Add Halmak Keyboard Layout HOT 1
- rules: setxkbmap deals with empty component differently
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from libxkbcommon.