-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement layout-independent keysym bindings #3058
Conversation
Please review the style guide: https://github.com/swaywm/sway/blob/master/CONTRIBUTING.md#style-reference |
I'm not sure this is a good idea. If you have a keyboard with multiple keys producing the same keysym, it'll only work with one of them. |
I would say that in one layout keyboards should only produce one unique keysym per key most of the time. From what I see, even numpad keys (digits, enter, insert, etc) produce keysyms which are different from the other keys' keysyms. In the rare case when the same keysym is producible from different keys, we could just skip the conversion. In other words, we will only convert keysyms which can be replaced with a single keycode. This should still fix bindings with Latin characters, since it is hard to imagine a keyboard with several keys to type in the same letter in one layout, and keysyms which cannot be safely replaced won't be affected. |
Maybe this should be optional, let (If you use two layouts with different positions for the latin letters (e.g. |
This is exactly what I experience from time to time (except that in my case almost all shortcuts just stop working). People do not normally think about the current layout all the time, so this inconsistency is annoying.
Making the bindsym conversion optional would mean that there are cases when people use some shortcuts in one keyboard layout and do not use in another. I cannot say for everyone, but to me it seems weird. In my opinion, it is convenient to use keysyms in the config file, but they should not be interpreted literally. Instead, bindings should be bound to proper hardware keys and just work consistently in any layout. This is not exactly what this pull request does, though. This change fixes the problem, but does not eliminate layout-dependent keysym comparisons altogether. I do not think I can do this until there is an agreement to drop support for layout-dependent keysym bindings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commit probably better to just merge with the prev. one, and then force-push the changes.
Hmm this is odd as the |
4598cf6
to
3a2c920
Compare
Squashed the style fixes and rebased the changes. |
Let's say keycodes Shift+1 gives the keysym 1 in one of my layouts (e.g. fr), and that just pressing the keycode 1 gives the keysym 1 in the other (e.g. en). What happens with this patch applied? |
It depends on how you have configured your layouts. The layout which comes first is used to resolve the bindsyms. For
For
|
Any updates on this? This is currently one of the biggest pain points with sway for me. |
I'm really not a fan of converting keysyms into keycodes. This makes bindings depend on the first layout, and breaks other layouts (set via |
Investigating what i3 does would be interesting. |
The issue with keysyms is that they depend on the current layout and this is a pain. The simplest way to fix that is to use only one layout for bindings, which sounds like a reasonable requirement. As for IPC, there are options:
This approach is actually inspired by what i3 does. You can take a look at |
i3 has another feature: keybindings can be restricted to a single layout with the |
@emersion, could you please make your point clearer:
|
@kupospelov, thanks for bumping this, and sorry for not clearly replying. I'll try to fully understand the issue, because I'm missing some pieces of the problem and haven't spent enough time thinking about it.
Excuse me, but an you please re-explain why it's an issue with Russian layouts? I only know the French issue: with the current design, if you bind
I should really read i3's code to understand in detail what they do. The thing that makes me skeptical about this feature is that as a user, I really don't expect I think it would make sense to have an option for this. It would be nice when implementing this to try to keep the code as simple and straightforward as possible (disclaimer: I haven't looked at the code yet).
Yes, I think we need to re-translate from keysyms each time the layout is changed via the |
Because pressing |
This could work like variables, you add an option to Example of implementation: This: Would get read as: |
To better demonstrate the issue, here's an example Russian keyboard: It's expected to be used with the US layout interchangeably (so you toggle between the two). When you switch the Russian layout on, keys don't really move around (it's not like 1 becomes shift+something or anything like that) so it's expected that US bindings continue to work the same regardless of the currently active layout. For the keys that do move (some punctuation) I would say it's still expected that they work as in the US layout rather than as in the Russian layout. |
Folks in this thread were quite eloquent at describing issues, it is hard to add anything else. Generally speaking, the main issue is that there is no I am also pretty sure that the same issue exists for a number of other layouts (Ukrainian and Greek for example, should be more).
Please take a look when you have a chance. The most interesting file there is From what I see the meaning of
This sounds reasonable, but there is another expectation: any binding should consistently work. As a result, in case of two or more layouts, only keys producing the same keysyms in all of the layouts are actually usable, and the others are the source of pain and despair.
Please consider the current implementation a prototype. It has worked for me since October, but some pieces of code will need to be changed or added to support dynamic re-translation. It seems that the key decision that needs to be made is whether sway must be consistent with i3 in how bindings work. In terms of implementation, I tend to believe that approach used in i3 ("translate every keysym into keycodes and then only use keycodes") is simplest possible, just because there would basically be only one type of bindings instead of two and the code to process keysyms might be dropped. |
This works perfectly in i3 and doesn't work with sway, causing a lot of pain when using non-latin keymap. Does 1.0 release imply feature parity with i3? |
Tone down the entitlement. This project is run by volunteers who are just doing their best in their spare time. I suppose a verdict of some kind is necessary here. Unless @emersion disagrees, I think that this behavior (translating keysyms to keycodes) should only be done with a flag, e.g.
This shouldn't be too much of a pain to configure. |
Why not default? What would be downsides? FWIW, this is how keybindings work in pretty much any software. The example with Ctrl+q someone put above is a bright example. Not having it as default, I think, a unique "feature" to sway, any reason why? |
This was already explained earlier in the thread. |
|
Thanks @emersion! Please, could you run any Qt application, and tell whether the behavior is as you described when Ctrl+q is pressed (by default it should close the application). It would help us to figure out whether they do something different or not. |
I'm using Firefox right now. In the en layout I need to press Ctrl+Q to quit, but when I switch to the fr layout I need to press Ctrl+A (the physical A key is bound to the Q key in the layout). |
Which seems correct to me... no? |
12877ec
to
a034e53
Compare
I'll try having a look again soon. Can some other contributor look at the changes too? |
Could you please rebase again? (There is a conflict with the now-merged #3998, which introduced a Also, I have read through the changeset a few times and have no immediate complaints; testing layout switching with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your patience. This version looks much better than the previous one.
Here are a few comments, only about style. The logic looks good to me. After these minor fixes and a rebase, I'll be okay to merge this.
sway/commands/bind.c
Outdated
|
||
switch (binding->type) { | ||
// a bindsym to translate | ||
case BINDING_KEYSYM: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style: case
should be on the same level as switch
(applies to the whole patch)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
sway/config.c
Outdated
@@ -921,3 +945,55 @@ void config_update_font_height(bool recalculate) { | |||
arrange_root(); | |||
} | |||
} | |||
|
|||
static void translate_bindings(list_t *bindings, list_t *bindsyms, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a little confusing, the only difference between translate_bindings
and translate_binding
is the final "s". Can we rename this one to translate_bindings_list
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to translate_binding_list
* `bindsym --to-code` enables keysym to keycode translation. * If there are no `xkb_layout` commands in the config file, the translation uses the XKB_DEFAULT_LAYOUT value. * It there is one or more `xkb_layout` command, the translation uses the first one. * If the translation is unsuccessful, a message is logged and the binding is stored as BINDING_KEYSYM. * The binding keysyms are stored and re-translated when a change in the input configuration may affect the translated bindings.
Do not store `xkb_keymap` since it can be retrieved from `xkb_state`.
Replace XKB_DEFAULT_LAYOUT with NULL as the default layout.
a034e53
to
7901420
Compare
Rebased. |
@emersion Can this be merged before 1.1 release? |
Oh, thanks for the heads-up. That would be nice indeed. Will have a look tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks! |
https://gist.github.com/eternal-sorrow/396d642a7c6be712157cc24376298faf simple patch so that this behaviour was default (without --to-code) |
DRYing things up without patching: bindsym --to-code {
$super+Return exec termite
$super+Shift+q kill
# ...
} |
@kupospelov Thank you, great work. Also helps when moving to optimized layouts, such as Dvorak. |
Fixes #2999.
The idea is to have an instance of default xkb_keymap and try to resolve bindsyms into bindcodes while binding.
If the conversion is successful, we just treat the binding as a bindcode. If the conversion has failed, we do not change the binding, so it will be processed as a normal bindsym.
In my configuration, all of the 80 bindsyms have been converted into bindcodes. I have tested the following and it worked in any keyboard layout:
I also checked a keysym with no simple keycode translation (the question mark, keysym
question
) and it worked as a keysym binding, however this kind of bindings still depends on the current keyboard layout.This makes shortcut behavior more consistent with that of i3 and other programs (e.g. terminal emulators).