swaywm / sway

i3-compatible Wayland compositor
https://swaywm.org
MIT License
14.48k stars 1.11k forks source link

Bindings to keysyms are layout-dependent #8275

Open chebykinn opened 1 month ago

chebykinn commented 1 month ago

Hi, I've been using Sway on and off for a while already, but I wanted to understand the reason for making bindings layout-dependent.

Let's say for example a user sets a key binding to open an application menu the same way they did it in i3:

bindsym $mod+d exec rofi -show run

This will only work with English keyboard layout. If they have a setup with multiple layouts like with an additional Cyrillic layout the menu wouldn't be called unless they switch back to English. To avoid this it is suggested to use bindsym --to-code in the man page, but it's not straightforward for the people who come from i3 and I've found multiple related issues here before posting this.

So roughly I have these questions:

chebykinn commented 1 month ago

Or maybe this is an incorrect behavior on the i3 side, since they have bindsym and bindcode, the latter is supposed to work independently from the layout, but then I just don't understand the reason for having bindsym.

emersion commented 1 month ago

A keysym (key symbol) doesn't identify a physical key. It identifies the result of translation a key according to a keyboard layout. A keycode identifies a physical key.

One could write a full config with keycodes rather than keysyms, but that's not what bindsym does. But that isn't very user-friendly, e.g. KEY_A is the position of the A key on a US keyboard (second row first key after Tab), and e.g. on a French keyboard it's the Q key.

chebykinn commented 1 month ago

Right, but from my everyday experience on i3 bindsym somehow maps to physical keys, why does it work differently?

I understand now the use case for binding to letters, French layout is a good example, do I understand that you have it as the only layout?

emersion commented 1 month ago

I don't remember what i3 does but probably it does --to-code by default or something. We chose to not do that in Sway because it went against the principle of keysyms.

Some people have French as the only layout, some people have both French and English (personally I only have English).

chebykinn commented 1 month ago

Got it, thanks! But what is the difference between bindsym --to-code vs bindcode?

emersion commented 1 month ago

bindsym --to-code takes keysyms as input and converts them into keycodes according to the default layout. bindcode takes keycodes as input.

bindsym accepts symbol names e.g. "a", but for bindcode you'd need to look up the KEY_* constant in /usr/include/linux/input-event-codes.h and put the number in the config file.

chebykinn commented 1 month ago

I understand now, thanks. I still think that for i3 compatibility it would've been best to keep the same behavior, but I get why you didn't do that. I'll leave this thread open for a while in case someone else would be interested.