Skip to content
This repository has been archived by the owner on May 8, 2024. It is now read-only.

Remapping capslock from .Xmodmap does not work as intended #148

Closed
jaseg opened this issue Feb 23, 2014 · 6 comments
Closed

Remapping capslock from .Xmodmap does not work as intended #148

jaseg opened this issue Feb 23, 2014 · 6 comments

Comments

@jaseg
Copy link

jaseg commented Feb 23, 2014

Hi,
I'm using a slightly customized variant of the US-international keyboard layout where I remapped the capslock key to act as a second escape key. Before using fcitx, I did this with the following shell script calling xkbcomp and xmodmap:

#!/bin/bash
# Remaps [TAB] to mean [ESCAPE] (nice for vim) and properly assigns the "Windows
# key" to MOD4 (nice for the awesome window manager)
# Also, sprinkles some unicode over unused or poorly used keys.
# <LGST> is that key next to left shift that is not found on US keyboards
xkbcomp - $DISPLAY<<EOF
xkb_keymap {
xkb_keycodes  { include "evdev+aliases(qwertz)"};
xkb_types     { include "complete"};
xkb_compat    { include "complete"};
xkb_symbols   {
    include "pc+us(altgr-intl)+inet(evdev)+group(alt_shift_toggle)+level3(ralt_switch)+capslock(escape)"
    key <LSGT> { [ doublelowquotemark, leftdoublequotemark, U2665, U2606 ] };
    key <AB01> { [ z, Z, U2190, U21E6 ] };
    key <AB02> { [ x, X, U2192, U21E8 ] };
    key <AB05> { [ b, B, U2714, U2718 ] };
    key <AB07> { [ m, M, mu,    U26A1 ] };
    key <AE01> { [ 1, exclam, U2610, exclamdown ] };
    key <AE02> { [ 2, at, U2611, dead_doubleacute ] };
    key <AE03> { [ 3, numbersign, U2612, dead_macron ] };
};
xkb_geometry  { include "pc(pc104)"};
};
EOF
xmodmap -e "add mod4 = Multi_key"

Now, for fcitx I generated a .Xmodmap using xmodmap -pke. In the xmodmap, the entries for the escape and capslock keys both correctly only contain escape, not capslock mappings. After starting fcitx, however, the capslock key will both emit an escape keycode and capslock the keyboard (which is extremely annoying). I have tracked this down to the fact that just xkbcomp is not enough to remap the caplock key, the xkbcomp script above is needed for that. Executing the script above solves the problem until a new keyboard is added to the system, fcitx is restarted or the fcitx input method is changed.

How am I supposed to do this remapping properly? As far as I can tell, the .Xmodmap file is a poor hack and a proper solution would require a custom xkb script to be loaded, though I do not know how to do that with fcitx. Any comments are appreciated.

@ghost
Copy link

ghost commented Feb 24, 2014

fcitx has an addon called "X Keyboard Integration" (if installed, at fcitx-config-gtk -> Addon -> X Keyboard Integration). There you can configure any custom xmodmap command and/or xmodmap script which fcitx will execute every time it is necessary to preserve any changes that might be set by running this commands.

@jaseg
Copy link
Author

jaseg commented Feb 24, 2014

I was already using this. I just found a solution while writing this reply. The problem was that as one might have guessed after attentively reading xmodmap's manpage, xmodmap -pke, which I used to generate my ~/.Xmodmap, only generates a keymap script and ignores any modifiers (of which capslock is one).

Here is the output of xmodmap -pke after loading my customized .Xmodmap:

[...]
keycode   9 = Escape NoSymbol Escape NoSymbol Escape Escape
[...]
keycode  66 = Escape NoSymbol Escape NoSymbol Escape Escape
[...]

And this is what xkbcomp -a :0 says:

xkb_keymap {
xkb_keycodes "evdev+aliases(qwerty)" {
    minimum = 8;
    maximum = 255;
     <ESC> = 9;
[...]
    <CAPS> = 66;
[...]
};
[...]
xkb_symbols "pc+us+us:2+inet(evdev)" {
[...]
    key  <ESC> {
//      type= "ONE_LEVEL",
        symbols[Group1]= [          Escape ]
    };
[...]
    key <CAPS> {
//      type= "ONE_LEVEL",
        symbols[Group1]= [          Escape ],
        actions[Group1]= [ LockMods(modifiers=Lock) ]
    };
[...]
    modifier_map Lock { <CAPS> };
};
xkb_geometry "pc(pc104)" {
[...]
};
};

The solution is to include the line clear Lock at the end of the generated ~/.Xmodmap.

@jaseg jaseg closed this as completed Feb 24, 2014
@jaseg
Copy link
Author

jaseg commented Feb 25, 2014

Unfortunately, I have to re-open this issue. The problem persists, under the following conditions:

  • I turn on my bluetooth keyboard
  • I press a key, the bluetooth keyboard connects
  • At this point, fcitx should apply my ~/.Xmodmap from src/module/xkb/xkb.c
  • Apparently, that does not work as indicated by capslock still locking caps and xkbcomp -a
  • When I now switch windows in my window manager (awesome), fcits prints the following on stderr:
xmodmap:  please release the following keys within 2 seconds:
    Super_L (keysym 0xffeb, keycode 133)
  • Then, my system will freeze for about two seconds and my (actually pretty darn fast) CPU will run at 100%
  • Then, capslock is escape. Only, may god help you if capslock is still enabled, since then you will have capslock enabled an no capslock keys to turn it off. This is some Dante stuff going on here.

At this point, I see two things that need to be done:

  • Since it seems to be generally unadvisable to use xmodmap to do anything, add proper xkbcomp handling to src/module/xkb/xkb.c.
  • At any point when switching IMEs or when loading xmodmap/xkbcomp configs, unlock capslock.

@jaseg jaseg reopened this Feb 25, 2014
@wengxt
Copy link
Member

wengxt commented Feb 25, 2014

First of all, following behaviour I discussed is based on 4.2.8.3.

that cpu hog is kinds of expected, you need to send a whole new key map to X server by using xmodmap. But you only use one layout right? did you have the us(altgr-intl) as the first input method in your fcitx settings? Fcitx will not apply xmodmap if it thinks layout doesn't need change.

And could your configuration be done by 'setxkbmap' command? fcitx's xkb integration is kinds of a limited version of setxkbkmap, which only do the layout change (and keep all xkb option as it is).

For your bluetooth keyboard case, the new keyboard event from X server is so confusing, that I've never figure out a way to listen to real hardware keyboard plugin event. If you suspend, and resume, x sever send new keyboard event, but it doesn't reset the keymap modified by xmodmap. If you execute xkbcomp (or do whatever its code does), will also trigger new keyboard event in X server, I examine all the fields in the event from xserver and I don't find a way to distinguish between them. So I never know when it will comes to a consistent state, the newly pluged keyboard doesn't affect by the xmodmap which is expected, no matter xmodmap is executed by fcitx or not.

I could not implement a feature (named, apply xmodmap on new keyboard plugin) which is not supported by display server. You need to suffer this situation by yourself.

While, for your specific problem, it's easy to make fcitx not to touch any your keyboard settings. Disable the xkb addon, by configuration tool (permenant) or command line option fcitx --disable fcitx-xkb (temporarily).

And xmodmap or similar will go away in wayland world, I do consider xmodmap as a depracated thing. To summarize, fcitx xmodmap integration has its limitation, which is not resolvable for your work case.

@wengxt wengxt closed this as completed Feb 25, 2014
@godhelpjun
Copy link

godhelpjun commented Feb 26, 2018

On my ubuntu 16.04,gnome desktop ,I use setxkbmap -o 'caps:swapescape' to swap escape key with caps key.
every time I switch to fcitx,the swap effect disappears .
I tried the followings,none of those woks for me:
1.fcitx --disable fcitx-xkb
then it says:
(WARN-4779 /build/fcitx-PSoVA1/fcitx-4.2.9.1/src/module/dbus/dbusstuff.c:246) DBus Service Already Exists
(ERROR-4779 /build/fcitx-PSoVA1/fcitx-4.2.9.1/src/lib/fcitx/instance.c:440) Exiting.

2..use the config panel to disable(unchecked) the x keyboard integration addon

3.configure x keyboard integration addon ,add the file full file path to the 'apply this custom xmodmap script after layout changes',which file contains expression something like this: 'keycode 66 = ESCAPE',which works fine for xmodmap.

4.unchecked the option 'allow to override the system x keyboard setting'

it is really a pain when I using vim.
what I did wrong?
please help.thanks.

@Ipphig
Copy link

Ipphig commented Feb 18, 2021

On your ~/.xinitrc, the first let fcitx run, the after let xmodmap read ~/.Xmodmap.

Something like this,
fcitx -dr &
sleep 2
xmodmap ~/.Xmodmap &

Adjust sleep 2 seconds with your need. In my case 2 does the job.

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

No branches or pull requests

4 participants