question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

qtile and keyboard layout / xmodmap: is the layout reset/changed?

See original GitHub issue

I experience this issue on two different machines (with the same distribution: ArchLabs).

The issue is that my modifier mapping (xmodmap) gets changed once Qtile has finished to startup.

I have setup Qtile as follow:

# init runs login which runs zsh
# zsh sources .zprofile, which runs startx if we are in TTY1
# startx runs ~/.xinitrc

# typical ~/.xinitrc
[ -r /etc/X11/xinit/.Xmodmap ] && xmodmap /etc/X11/xinit/.Xmodmap
[ -r ~/.Xmodmap ] && xmodmap ~/.Xmodmap
[ -r ~/.Xresources ] && xrdb -merge ~/.Xresources
[ -r ~/.xprofile ] && . ~/.xprofile

exec qtile

And the content of ~/.Xmodmap to map CapsLock to Hyper key:

clear Lock
keycode 66 = Hyper_L
remove mod4 = Hyper_L
add mod3 = Hyper_L

I added xmodmap >> ~/xmodmap.log everywhere, and here is the summary of what happens:

> in zprofile

> in xinitrc

> before xmodmap (initial fr layout)
lock        Caps_Lock (0x42)
mod3      
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)

> after xmodmap (ok)
lock      
mod3        Hyper_L (0x42),  Hyper_L (0xcf)
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce)

> in qtile startup once script (still good)
lock      
mod3        Hyper_L (0x42),  Hyper_L (0xcf)
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce)

> at this point, Qtile is ready and my Qtile key Hyper+Return does not work,
> I use the backup Super+Return key to launch a terminal

> output of xmodmap (mod3 cleared, and Hyper on lock??)
lock        Hyper_L (0x42)
mod3      
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)

I tried to look at the source code, particularly at keyboard-related widgets, but couldn’t find code susceptible to run and change the keyboard layout/mappings, so I don’t know why they get changed. Any idea 🙂 ?

I’m not even sure it’s caused by Qtile, but the hints to say so are here: mapping ok while in startup_once hook, mapping changed after that and before doing anything else 😕

EDIT: based on comment from @tych0, maybe another program is problematic, like gnome-keyring-daemon or polkit-gnome-authentication-agent-1. I’ll try to stop running them and see if the issue persists.

EDIT2: nope, still same result.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
vividncommented, Sep 17, 2022

So after many additional hours of looking into this, I’ve learned that the xmodmap modifier table is reset after the first key press on the keyboard, so anything done in the qtile config will get thrown away unless you put a delay in to run xmodmap and then make sure to press a key on the keyboard before the delay expires.

I think this is because qtile doesn’t register the keyboard until a key is pressed, after which it detects it and setxkbmap is run, which resets the modifier keys. I don’t know the internals here. setxkbmap is also run whenever a new keyboard is plugged in so the hyper modifier is also lost in this case as well.

After much scouring of the internet, it seems the best solution is to define your own xkb symbols file that sets up hyper to be a modifier. That way, after plugging in new keyboards and when qtile starts it gets reset to the correct desired behavior.

For example, here is my symbols file, adapted from https://gist.github.com/nh2/ff15f412881f35ab7730

xkb_symbols "us-altgr-intl-hyper"
{
  include "us(altgr-intl)" 
  include "level3(ralt_switch)"

  key <CAPS>  { [ Hyper_L ] };
  modifier_map Mod3 { <CAPS> };
  modifier_map Mod3 { <HYPR> };
};

for those using NixOs, put this into xkb.nix:

{ config, pkgs, ... }:
let symbols_file = pkgs.writeText "symbols/us-altgr-intl-hyper" ''
xkb_symbols "us-altgr-intl-hyper"
{
  include "us(altgr-intl)"
  include "level3(ralt_switch)"

  key <CAPS>  { [ Hyper_L ] };
  modifier_map Mod3 { <CAPS> };
  modifier_map Mod3 { <HYPR> };
};
'';
in {
    services.xserver = {
      layout = "us-altgr-intl-hyper";
      extraLayouts.us-altgr-intl-hyper = {
        description = "Custom layout with hyper guaranteed to be mod3";
        languages = [ "eng" ];
        symbolsFile = symbols_file;
    };
  };
}

and then import it into configuration.nix imports = [ ./xkb.nix ]

you can then start to add your own custom keys as well.

0reactions
pawamoycommented, Sep 23, 2022

Wow, thanks a lot for the thorough investigation, and for reporting all this here! I’ve not hacked on Qtile for a while but this will definitely be useful when I start again 😄

Read more comments on GitHub >

github_iconTop Results From Across the Web

Frequently Asked Questions — Qtile 0.9.0 documentation
Alternatively, you can just cycle through your layouts a few times, ... To see a list of modifier names and their matching keys,...
Read more >
xmodmap resets when keyboard mode changes
I would like to swap them to a more standard layout, so that, from top to bottom, I would have Light Toggle ,...
Read more >
How do I clear xmodmap settings? - keyboard - Ask Ubuntu
So I'm trying to reset my keyboard to the default settings, but the xmodmap manpage is woefully devoid of "reset all" or "clear...
Read more >
suspend/resume resets "setxkbmap" keyboard layout back to ...
I'm seeing what could be the same or a related bug. If I change modifier mappings with xmodmap then suspend/resume, they're reset. For...
Read more >
Key mapping reverts to default after changing keyboard layout ...
Xmodmap " would be executed automaticaly every time KDE start. And it worked until I've had to change keyboard layout to say, Serbian...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found