Sway: xmodmap with inputs

Created on 12 Jun 2019  Â·  16Comments  Â·  Source: swaywm/sway

  • Sway Version: sway version 1.1-rc1-38-g3f77591b (Jun 11 2019, branch 'master')

I was using a script in i3 to set my us key layout to use German "umlaut" (ä, ö, ü and ß).

setxkbmap -layout us -variant altgr-intl -option caps:none
xmodmap -e 'keycode  66 = Mode_switch'
xmodmap -e 'keycode  26 = e E EuroSign cent'
xmodmap -e 'keycode  30 = u U udiaeresis Udiaeresis'
xmodmap -e 'keycode  32 = o O odiaeresis Odiaeresis'
xmodmap -e 'keycode  38 = a A adiaeresis Adiaeresis'
xmodmap -e 'keycode  39 = s S ssharp'

Is it possible to do this with inputs?

Most helpful comment

You'll have to use a custom layout.

Save the following to $HOME/.xkb/symbols/us-german-umlaut

default partial alphanumeric_keys
xkb_symbols "basic" {
    include "us(altgr-intl)"
    include "level3(caps_switch)"
    name[Group1] = "English (US, international with German umlaut)";
    key <AD03> { [ e, E, EuroSign, cent ] };
    key <AD07> { [ u, U, udiaeresis, Udiaeresis ] };
    key <AD09> { [ o, O, odiaeresis, Odiaeresis ] };
    key <AC01> { [ a, A, adiaeresis, Adiaeresis ] };
    key <AC02> { [ s, S, ssharp ] };
};

Then in your sway config, you can use input <identifier> xkb_layout us-german-umlaut. You can use swaymsg -t get_inputs to find the identifier for the keyboard. Alternatively, using * (wildcard for all devices) or type:keyboard (wildcard for all keyboards) in place of the identifier would also work

All 16 comments

You'll have to use a custom layout.

Save the following to $HOME/.xkb/symbols/us-german-umlaut

default partial alphanumeric_keys
xkb_symbols "basic" {
    include "us(altgr-intl)"
    include "level3(caps_switch)"
    name[Group1] = "English (US, international with German umlaut)";
    key <AD03> { [ e, E, EuroSign, cent ] };
    key <AD07> { [ u, U, udiaeresis, Udiaeresis ] };
    key <AD09> { [ o, O, odiaeresis, Odiaeresis ] };
    key <AC01> { [ a, A, adiaeresis, Adiaeresis ] };
    key <AC02> { [ s, S, ssharp ] };
};

Then in your sway config, you can use input <identifier> xkb_layout us-german-umlaut. You can use swaymsg -t get_inputs to find the identifier for the keyboard. Alternatively, using * (wildcard for all devices) or type:keyboard (wildcard for all keyboards) in place of the identifier would also work

Thank you SO much! Works as expected

@RedSoxFan Have a similar issue but it's not clear how to convert a set of xmodmap commands to a layout file. Could you provide some brief guidance or link to a guide on how to create these layout files?

edit: I was able to solve my issue (making the "PrtSc" key map to Win) by using:

input * xkb_options altwin:prtsc_win

In general you want to stay away from writing custom xkb files unless absolutely necessary. Take a look at /usr/share/X11/xkb/rules/evdev.lst to see if the customization you want exists as a xkb variant or option. More information here https://www.x.org/releases/current/doc/xorg-docs/input/XKB-Config.html

Could you provide some brief guidance or link to a guide on how to create these layout files?

Maybe put a link to some documentation on this in wiki and/or FAQ

 key <AD03> { [ e, E, EuroSign, cent ] };
 key <AD07> { [ u, U, udiaeresis, Udiaeresis ] };

@RedSoxFan Could you let me know how to remap the 'r' key to get the ₹ (Indian Rupee) symbol in a similar fashion? Or point me to the right resource? Thanks.

@paramjit1
You can find the appropriate symbols here (or locally in /usr/share/X11/keysymdef.h) - just drop the XK_ prefix.

As for the key portion, the graphic at https://www.charvolant.org/doug/xkb/html/img3.png appears to be a good resource for that.

@RedSoxFan I tried to implement what you have suggested in order to remap AltGr+- to give me an em dash (on a swiss german keyboard layout).

In my sway config I have this relevant snippet:

input type:keyboard {
        xkb_layout ch
        xkb_options ch_emdash
}

And this is my xkb file under .xkb/symbols/ch_emdash:

default partial alphanumeric_keys
xkb_symbols "basic" {
    name[Group1] = "German (CH, international with German umlaut)";
    key <AB11> { [ minus, underscore, emdash ] };
};

This doesn't seem to be doing anything. AltGr+- still gives me a dot underneath the next character (ụ) or a dot under the previous character if I press it twice (̣). If I press AlrGr+- and the - I get an em dash, sadly one with a dot underneath it (⨪), as I would do anyway. Any idea what I can do?

including the rest of the example code:

    include "us(altgr-intl)"
    include "level3(caps_switch)"

also does nothing.

It worked with:

input type:keyboard {
        xkb_layout ch_emdash
}

in the sway config, and with:

default partial alphanumeric_keys
xkb_symbols "basic" {
        include "ch"
        name[Group1] = "German (CH, international with German umlaut)";
        key <AB10> { [ minus, underscore, endash, emdash ] };
};

in ~/.xkb/symbols/ch_emdash.

I am trying to recreate a mapping (that was previously done through xmodmap), which assigns the extra function keys that I have programmed onto my keyboard to Hungarian accents. The shift level works on every key, but the regular level only works on two of them (19 and 24). I have found that those are the ones that already have some XF86 mappings in the default symbols layouts. Can I somehow override those? I even tried replace key but that doesn't seem to do anything useful, and I couldn't really find any documentation on it.

default partial alphanumeric_keys
xkb_symbols "basic" {

  include "us(basic)"

  name[Group1]= "English (US, HU accents with f keys)";

  replace key <FK14> { [ odoubleacute , Odoubleacute ] };
  replace key <FK15> { [ oacute       , Oacute       ] };
  replace key <FK16> { [ uacute       , Uacute       ] };
  replace key <FK17> { [ udoubleacute , Udoubleacute ] };
  replace key <FK19> { [ odiaeresis   , Odiaeresis   ] };
  replace key <FK20> { [ eacute       , Eacute       ] };
  replace key <FK21> { [ aacute       , Aacute       ] };
  replace key <FK22> { [ udiaeresis   , Udiaeresis   ] };
  replace key <FK24> { [ iacute       , Iacute       ] };

};

After searching around some more and quite a bit of trial and error I have figured out that inet(evdev) takes precedence, because by default it is listed after my own symbols in an xkb_layout, but by using a complete layout file as made possible by @edyounis in #3999 I was finally able to switch the order and override them to get the desired results without modifying the system files!

I really wish xkb was a little more intuitive to configure. and didn't require duplicating entire layouts, keymaps, etc. to make those sort of changes.

@tmccombs: I too think it could be easier. But you don't have to duplicate entire layouts.

For example, I wanted to remap the Alt Gr key, the one on the right side of the space bar, to the super key (aka Windows key). I use the super key as my Sway modifier (set $mod Mod4). My keyboard layout of choice is programmer Dvorak, so I needed to modify that.

Here's what I did:

Relevant bit of ~/.config/sway/config:

input type:keyboard {

  # Modified programmer Dvorak. File at ~/.xkb/symbols/dvp_alt_gr_remapped_to_super
  xkb_layout "dvp_alt_gr_remapped_to_super"

  # Capslock key should work as escape key
  # See /usr/share/X11/xkb/rules/xorg.lst for options
  xkb_options caps:escape

  repeat_delay 250
  repeat_rate 45
}

The entirety of ~/.xkb/symbols/dvp_alt_gr_remapped_to_super:

default partial alphanumeric_keys
xkb_symbols "basic" {
        include "us(dvp)"
        name[Group1] = "Modified programmer Dvorak";
        key <RALT> { [ Super_L, Super_R ] };
};

I think those efforts are reasonable.

Here's a more involved example, remapping all kinds of keys: Changing Keyboard Layouts with XKB


I'm not sure why I had to add both Super_L and Super_R to the mapping to make it work with Sway. When I tried key <RALT> { [ Super_L] }; neither the physical super key (left of the space bar) nor the Alt Gr key would work as the Sway modifier.

With key <RALT> { [ Super_R] }; the super key would be accepted as Sway's modifier, but not so with Alt Gr.


I have this ridiculous issue on linux where I can use xmodmap to disable the numeric keypad dot key, which for some reason gets fired off if i type hu (as in github) like githu.........b, as well as when I open new windows in chrome. Incredibly annoying, especially considering I don't even have a numeric keypad -- and apparently super+2 doesn't work to switch to a new workspace either so I remapped caps to super. Big thanks to @mb720 for happening to come up with a nicely working solution on the same day I needed one! In my ~/.config/sway/config:

input type:keyboard {
        xkb_layout "keybounce_fix"

        xkb_options caps:super

        repeat_delay 250
        repeat_rate 45
}
````

In ~/.xkb/symbols/keybounce_fix:

partial alphanumeric_keys

xkb_symbols "basic" {
include "us"
replace key { [ ] };
};
```

Haha I spoke too soon. This fix doesn't seem to persist across suspend-resume at all. do i have to resort to some hack outside of sway to fix this (I have something in mind already), or is there something in-WM to deal with that?

Not exactly the same issue, but how do I map a key sequence like RCtrl-g to dead_greek?

@j0hnmeow

I found this for my keybounce fix under X back when I was still using that as my daily driver:

xmodmap -e 'keycode 129='

by running xev and seeing what came up... I don't really remember how I translated 129 to <KPDL> but it involved a bunch of grepping in /usr/share/x11/xkb/symbols if I recall correctly.

replace key <KPDL> { [ ] };

you want something else in the brackets there for your remapping needs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jakubn551 picture jakubn551  Â·  4Comments

dnkl picture dnkl  Â·  4Comments

soymjolk picture soymjolk  Â·  3Comments

johanhelsing picture johanhelsing  Â·  3Comments

RyanDwyer picture RyanDwyer  Â·  3Comments