You are not logged in.

#1 2026-03-19 18:30:35

Kepis
Member
Registered: 2021-12-15
Posts: 105

[Solved]: xkb shortcut layout - shortcuts working on non-US layouts

Hi, I'm on sway, but xkb is used there as well. I am looking for a way to make shortcut modifiers (Super/Ctrl/Alt) emmit US / standard keyboard letters while allowing me to still use a different layout for writing.

Ideally I'd be able to switch layouts and be able to reuse the extra level defined for the shortcuts. However, it seems that either emmited shortcuts print the level1 symbol, or the emmited symbol consumes the modifier that was mapped to that level - i.e. when defining a custom modifier type either I can map the modifier to a higher level, or preserve it, never both.

My idea for a workaround was to map None to level5 instead, but then it is not layout-agnostic, because I'd have to redefine every layout to have the US key on level1 and the original layout level1 value I'd have to map manually to level5 for every symbol. That is, unless there is a way to reference a different level of the same symbol from previous definition (like the passthrough key any does leave there the previously defined key on the same level).

An alternative that I thought could work, but don't know how to do/test, is to define an action on the modifier keys to change the layout for the time of being pushed down, or maybe just change the group to Group2 (I still don't understand if there is a difference between groups and layouts or not) while keeping the modifier active (once again, not sure if that is possible or how to do that - SetMods seems promising, but discards all other modifiers).

Exemplary goal behaviour for the three different cases of layout keys (differin where the US equivalent is defined - level 3 vs level 2 vs level 1):

Note: AGr = RAlt / AltGr, G+S = AltGr+Shift
      None |  S  | AGr | G+S | Anything with Ctrl or LAlt as US default
TLDE |  ;  |  °  |  `  |  ~  |  ` 
AE01 |  +  |  1  |  !  |  ~  |  1
AD01 |  q  |  Q  |  \  |     |  q

To make the different positions of the US default work is no problem - I could just ignore those and define the US unmodified default as level5, or define different xkb_types for each of the three cases. The problem is, that modifier keys always get consumed when they're used to change the level. And the approach of remapping None to a different level forces me to manually define every layout because I need to map tose special keys to the level5 where None would be pointing to. (there are some extra caveats with the Shift behaviour, but that is not that important)

Last edited by Kepis (2026-03-19 23:24:21)

Offline

#2 2026-03-19 21:10:02

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,775

Re: [Solved]: xkb shortcut layout - shortcuts working on non-US layouts

tl;dr you want ctrl+a => ctrl+a but a => α and your idea is to turn ctrl into a combined lv5 shift + ctrl?
lv5:caps_switch      Caps Lock chooses 5th level
and then ctrl+capsl+a for ctrl+a isn't an option?

That's not gonna work - the lv5 shifts simply change the meaning of the key.
You'll need sth. like https://github.com/rvaiya/keyd which can map specific key combos to other key combos

Offline

#3 2026-03-19 22:30:09

Kepis
Member
Registered: 2021-12-15
Posts: 105

Re: [Solved]: xkb shortcut layout - shortcuts working on non-US layouts

well practically, yes - if I want to try writing a different alphabet I want my shortcuts to work. Since the charset will be different, I need a way to make the modifier keys spit out a different key than the one deault (level1)  to the layout and take the key I want it to use from some other posiition.

I think have found an annoying, but theoretically possible workaround. The documentation states that I can set both a modifier and a group at the same time, yet there is no way to actually do that in the syntax - putting a comma between the actions makes them get registered for different levels, and anything else is considered an error - I tried all of this, none compiled:

    key <LCTL> {actions = [ {[SetMods(modifiers=Control),SetGroup(group=+1)]} ]};
    key <LCTL> {actions = [ [SetMods(modifiers=Control),SetGroup(group=+1)] ]};
    key <LCTL> {actions = [ {SetMods(modifiers=Control),SetGroup(group=+1)} ]};
    key <LCTL> {actions = [ SetMods(modifiers=Control)+SetGroup(group=+1) ]};

So the solution I see possible, is to map all the modifiers to set mods with an extra modifier, that I then consume in a types definition and that extra modifier gets converted to the level5. This even lets me keep all the layouts in tact. Only major disadvantage is, that I have to redefine all keys I ever want to use with any modifiers to consume my modifier correctly, because otherwise they will emmit that modifier as well and every application will think that there is an extra modifier and therefore not match any keybind.

My types:

default partial xkb_types "default" {
	virtual_modifiers Alt, LevelThree, LevelFive;

    type "L5" {
		modifiers = Shift + LevelThree + Control + Alt + Super + LevelFive;
		map[None] = Level1;		map[Shift] = Level2;		map[LevelThree] = Level3;     map[LevelThree+Shift] = Level4;

        map[LevelFive+Super] = Level5; preserve[LevelFive+Super] = Super;
        
        map[LevelFive+Alt] = Level5; preserve[LevelFive+Alt] = Alt;
        map[LevelFive+Super+Alt] = Level5; preserve[LevelFive+Super+Alt] = Super+Alt;
...

		preserve[Shift+LevelThree] = Shift;

		level_name[Level1] = "Base";
		level_name[Level2] = "Shift";
		level_name[Level3] = "AltGr";
		level_name[Level4] = "Shift AltGr";
		level_name[Level5] = "Shortcut";
        
        // preserve[Shift] = Shift;
    };
};

===

Edit:

I've just noticed it actually does work as it should - this version did work:

    key <LCTL> {actions = [ {SetMods(modifiers=Control),SetGroup(group=+1)} ]};

Unfortunately when I specified the group before without the '+' it didn't work as an absolute index, it just shifted the indexing by 1 or sth (I had to use '2' to get to the first layout that I have set to US). However, it does mean I can do it without adding definitions practically anywhere - I just make all modifiers go to the default layout, nice!

Last edited by Kepis (2026-03-19 22:47:42)

Offline

#4 2026-03-19 22:57:42

Kepis
Member
Registered: 2021-12-15
Posts: 105

Re: [Solved]: xkb shortcut layout - shortcuts working on non-US layouts

With being able to set both the modifier as well as the group, I can relatively easily adjust it to any layout, only changing the relative index of the group to jump to.

One last thing that bugs me, is that I seem to be unable to have more than 4 layouts - I can specify more in sway, but I can cycle through only the four. Do you know if that is normal, or should I be maybe looking for some bug in my config? I'm using

		swaymsg input type:keyboard xkb_switch_layout next

which should work, but even when I dump out the config, it also completely omits the 5th layout.

Offline

#5 2026-03-19 23:23:25

Kepis
Member
Registered: 2021-12-15
Posts: 105

Re: [Solved]: xkb shortcut layout - shortcuts working on non-US layouts

Last issue that this configuration creates, is that because LAlt is a modifier that now jumps to a different group on-press I now always switch from the US layout to any other as opposed to going to the next because in the moment of activating the binding I am in the US layout. I've partially resolved it by putting a 0.2s sleep before calling the command to change layouts and invoking it on key release instead of press, but it is still not quite ideal.

From the perspective of how pleasant it is to switch between keyboards, the approach of creating a virtual modifier that gets sacrificed later in the keybind processing would be nicer. However, this approach is so much simpler and cleaner I think it is worth it.

Last edited by Kepis (2026-03-19 23:24:58)

Offline

Board footer

Powered by FluxBB