Skip to content
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

Changing keyboard layout #908

Open
shader opened this issue Mar 14, 2023 · 7 comments
Open

Changing keyboard layout #908

shader opened this issue Mar 14, 2023 · 7 comments

Comments

@shader
Copy link

shader commented Mar 14, 2023

What's the recommended way to change a keyboard layout during use?

I normally use the colemak layout, but i have an external keyboard that has a custom layout assuming qwerty input mappings. If I try to use setxkbmap to change the keyboard layout, it mostly works in subordinate X windows (e.g. Firefox) but not in the exwm keys that don't go to Firefox (e.g. C-x ...).

I think this is an EXWM issue, because of the way it affects those specially grabbed keys.
Any workaround ideas or things I should test?

@tazjin
Copy link

tazjin commented Mar 14, 2023

You can use Emacs input methods in EXWM via toggle-input-method (I think the default shortcut is C-\). This works in all X windows that support xim input (which excludes e.g. modern Qt applications, but definitely works in Firefox/Chromium).

This requires a little bit of setup, on the Emacs side:

(require 'exwm-xim)
(exwm-xim-enable)

and on your session level, these environment variables:

    XMODIFIERS = "@im=exwm-xim";
    GTK_IM_MODULE = "xim";
    QT_IM_MODULE = "xim";
    CLUTTER_IM_MODULE = "xim";

For the occasional case where I have to type something in Russian or Arabic in a Qt-window (e.g. Quassel IRC), I have shortcuts that use setxkbmap which also affects shortcuts in Emacs (making them mostly impossible to use). To work around this I set the shortcuts in Emacs in all alphabets, which is a bit cumbersome, but fortunately not actually needed very often.

@medranocalvo
Copy link
Collaborator

I don't fully understand the issue, possibly because I don't usually change keyboard layouts. There is some support in EXWM for updating the global keys "when the keyboard is updated" (see exwm-input--init and xcb-keysyms.el), but I'm not sure which cases it supports. Neither I'm sure what behaviour you miss.

Please, create a minimum configuration and set of steps that allow me to reproduce the issue (see for example #924 (comment)).

@eval-on-point
Copy link

I don't completely understand the issue either, but I have had a good experience mapping my keyboards with kmonad/kmonad: An advanced keyboard manager rather than setxkbmap. This changes my keyboard layout globally, not just in X11 sessions.

@shader
Copy link
Author

shader commented Sep 17, 2023

Well, I just spent an hour or two but couldn't get a truly minimal config working (couldn't get a minimal exwm config to work on my system for some reason).

However, I was able to narrow down some cases where the problem occurs and where it doesn't, so maybe this will be enough for you to reproduce it.

Potentially confounding configuration

I'm not expecting you to try reproducing my configs; just thought I should mention them briefly since I wasn't able to bypass them to make a working minimal setup.
I'm using guix system, and configuring exwm primarily with a custom doom module based on doomemacs/doomemacs#4004 (never got merged). I also experimented with configuring exwm-xim but I'm not sure if it's working right now or not.

Variant A - produces problem

In xinitrc:

setxkbmap us -variant colemak &
exec emacs -f exwm-enable
  • Note that setxkbmap is called before launching emacs. Obviously necessary if it's going to happen in xinitrc because of the exec, but this seems to be necessary for producing the problem.

Once exwm is loaded:

M-x async-shell-command RET firefox
C-c w c     ; doom keybinding for create workspace, really any "C-c" or "C-x" command that would be captured by exwm in line mode and not sent to firefox should be a good test

Expected result -> nothing unusual happens; chord input correctly

In some terminal:

setxkbmap us -model pc105

Changes the layout back to qwerty. Most keys should work as expected in any emacs buffer, or when typing in firefox (e.g. input fields, C-t for new tab, etc.)
However, "captured keys" don't notice the change:

  • In normal emacs: C-c w n goes to next workspace
  • In firefox: C-c w n for some reason captures C-c w k instead (n is mapped to k in colemak)

Variant B - doesn't have problem

I only found this while working on making a minimal config today.

In xinitrc:

exec emacs -f exwm-enable

Later, in terminal: setkbmap us -variant colemak; proceed as above after "exwm loaded".
No problems with captured keys in either layout.

Workaround

Since my objective was to switch to qwerty for my external keyboard (since it handles layouts itself via firmware), I found it was easier to just use kmonad and only set the layout for the internal keyboard. Then the layout works everywhere, and I don't have to switch when attaching the external.

Another potential workaround based on variant B above would is just to not call setxkbmap until after emacs launches, and call setxkbmap during emacs' init after exwm instead.

@eval-on-point
Copy link

setxkbmap us -variant colemak &
exec emacs -f exwm-enable

stands out to me as a possible issue. The & is telling the shell to execute setxkbmap in the background. So, emacs may be launching before setxkbmap is finished changing the layout. What happens if you remove the &?

@shader
Copy link
Author

shader commented Sep 20, 2023

What happens if you remove the &?

I tried it; no difference. Good catch though.

@shobute
Copy link

shobute commented Dec 20, 2023

Since my objective was to switch to qwerty for my external keyboard (since it handles layouts itself via firmware), I found it was easier to just use kmonad and only set the layout for the internal keyboard.

Note that kmonad isn't needed here. You can set the layout for a specific keyboard with setxkbmap using the -device flag (device IDs can be found with xinput list, see the man page for more information). That way you can change the layout for one keyboard, while leaving any others alone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants