Remap/rebind keys

Great.

The reason I think a layout would be good is that it just remaps the keys at a low level, there’s nothing else in the way to mess things up.

What do you think you’d get from a script that you can’t get from this?

Bearing in mind that if global shortcuts work in the game we can script the layout change and probably check if the game is running. I can help with that too, but maybe not tonight (getting a little late).

Anyway I’ve done it now, so at least you have a workaround. :slight_smile:

default
xkb_symbols "basic" {

    include "de"

    key <AD01> { [     u,             U,        at,            Greek_OMEGA   ] }; // q
    key <AD02> { [     Up,            Up,       U017F,         section       ] }; // w
    key <AC04> { [     d,             D,        dstroke,       ordfeminine   ] }; // f
    key <AC01> { [     Left,          Left,     ae,            AE            ] }; // a
    key <AC02> { [     Down,          Down,     U017F,         U1E9E         ] }; // s
    key <AC03> { [     Right,         Right,    eth,           ETH           ] }; // d
    key <AD03> { [     t,             T,        EuroSign,      EuroSign      ] }; // e
    key <AB02> { [     KP_Insert,     KP_0,     guillemotleft, U2039         ] }; // x
    key <AB03> { [     n,             N,        cent,          copyright     ] }; // c
};

You can save it as /usr/share/X11/xkb/symbols/custom

sudo nano /usr/share/X11/xkb/symbols/custom

# paste the layout above
# Ctrl + S to save and Ctrl + X to exit

and then add it in the same way you just did by selecting “A user defined custom layout” (I haven’t actually done this on KDE before but it’s the only option for a custom layout).

Then just switch with whatever key or combo you chose in “Switching to another layout”.

EDIT:

If you really want Enter to switch, I might be able to make two layouts and a script to switch between your normal layout and the other two. As in replace the German with a slightly modified version of the one above and a slightly modified version of German, for the duration of the game and then go back to the normal German.

Anyway if you’re willing, please test this, and we can talk about the rest.

1 Like

I created the a file file called custom in /usr/share/X11/xkb/symbols/
But it doesn’t appear in the list of the other layouts :frowning:

No problem, it is really late. I will continue to follow the thread tomorrow and keep trying

It should be called “A user defined custom layout”.

If that doesn’t work you can use this

setxkbmap de,custom

The command is only temporary, until you logout.

I found it, It’s called in german “Eine benutzerdefinierte Belegung” ^^
Thank you very much

1 Like

I will mark the thread as “solved” in the next 2 or 3 days.
Maybe there is someone who can suggest a solution with the script so that you don’t have to switch the layout in the game and it works automatically with enter like it worked on windows

See my edit above, we should be able to get Enter to do the switching, but we’d need a script to run setxkbmap in order for it to work. I can do that tomorrow.

I think then it should be what you asked for. :crossed_fingers:

I’ve tried it in the game and it doesn’t work. Only in the chat but not in the gameplay itself :frowning:
Well, I’m going to bed too.
Good night and see you tomorrow

Ah that’s a pity, perhaps it’s grabbing the input at a lower level. :frowning:

Good night. :slight_smile:

EDIT:

I’ve had a look at xremap, it looks pretty good. It should handle everything, assuming it works at all for this use case. Even if it does, I’m not sure if it’ll solve the original problem of keys getting stuck, but :crossed_fingers:

Have you tried specifying the device?

sudo xremap --device "Logitech K400 Plus" ~/.xremap_remap.yml

What’s the contents of ~/.xremap_remap.yml?

Anyway here’s a quick config that might work, but I’m not sure about the application matching. :crossed_fingers:

If it doesn’t work, then try without the application matching, and play around with exact_match.

default_mode: active

keymap:
  - name: Company Of Heroes 2
    remap:
  - mode: active
    exact_match: true
    # application:
    #   only: steam_app_231430.steam_app_231430
    remap:
      KEY_ENTER: [ KEY_ENTER, { set_mode: not_active } ]
      w: up
      a: left
      s: down
      d: right
      e: t
      q: u
      f: d
      c: n
      x: kp0

  - mode: not_active
    exact_match: true
    # application:
    #   only: steam_app_231430.steam_app_231430
    remap:
      KEY_ENTER: [ KEY_ENTER, { set_mode: active } ]

I’d advise setting up xremap so you don’t need sudo.

sudo gpasswd -a $USER input
echo uinput | sudo tee /etc/modules-load.d/uinput.conf
echo 'KERNEL=="uinput", GROUP="input", TAG+="uaccess"' | sudo tee /etc/udev/rules.d/99-input.rules

# then reboot

EDIT:

Fixed syntax error

1 Like

I tried for hours, needed dozens of restarts because I messed up my keyboard and wasted more than half a day to gain the following insights.

At first there were several errors because of the syntax, but thanks to ChatGPT I got it to work without any errors:

default_mode: active

keymap:
  - name: Company Of Heroes 2
    mode: active
    exact_match: true
    application:
      only: kate.kate # just for testing
    remap:
      KEY_ENTER: [ KEY_ENTER, { set_mode: not_active } ]
      w: up
      a: left
      s: down
      d: right
      e: t
      q: u
      f: d
      c: n
      x: kp0

  - mode: not_active
    exact_match: true
    application:
      only: kate.kate # just for testing
    remap:
      KEY_ENTER: [ KEY_ENTER, { set_mode: active } ]

As soon as I tried to press a key in any window (no matter which), the error came up
application-client: KDE (supported: false)
There seems to be a bug with Plasma 6 so I uninstalled xremap-kde and installed xremap-x11-bin. Now the application monitoring seems to work. The toggle with “enter” also works.

BUT: It is the same behavior as with the workaround to change the keyboard layout. It behaves exactly the same. In the text editor and in the ingame-chat it works but not in the actual gameplay!
And in the terminal I got strange symbols. When I type wasd, it says ^[[A^[[D^[[B^[[C.

I found out it works with the GUI tool input remapper but with this tool I can’t toggle on/off or monitor any application. Then I came across a post in the Steam community and tried this out:

xmodmap -e 'keycode 25 = Up'
xmodmap -e 'keycode 38 = Left'
xmodmap -e 'keycode 39 = Down'
xmodmap -e 'keycode 40 = Right'

And this also works in game!
So I changed the keyword keymap: to modmap: but then I get an error again:

Error: Failed to load config '/home/tom/.xremap_remap.yml': modmap[0]: unknown field `mode`, expected one of `name`, `remap`, `application`, `window`, `device` at line 5 column 5

I haven’t gotten any further so far.

EDIT:

I got this output

Benutzer tom wird zur Gruppe input hinzugefügt.
uinput # this line is missing from the comand on GitHub
KERNEL=="uinput", GROUP="input", TAG+="uaccess"

You should just need to stop xremap, that reset everything for me. That can be done with Ctrl + C or Ctrl + Alt + C, or by closing the terminal it’s running in.

Sorry I was testing on my laptop (with KDE) and posted on my desktop. I missed out two remap: fields when copying it over. I’ve fixed it now.

Mine says true, but I didn’t use a pre-compiled version. The application matching seems less than perfect.

I did expect it may, that’s why I said “assuming it works at all for this use case”.

Sounds like you were typing into the same terminal that xremap was running in, that’s how the arrow keys are displayed.

Your config doesn’t work in kate for me, but it’s fine once I remove the application fields.

I’m surprised xmodmap works if the others don’t. I used keymap because it allows you to have modes and sequences of key presses.

You can test modmap with this, but i don’t know how to switch it using xremap (or if it’s even possible). I think you’d have to kill xremap and then start it with a different config.

modmap:
  - name: Company Of Heroes 2
    # application:
    #   only: kate.kate # just for testing
    remap:
      w: up  # we really only need one for testing
      a: left
      s: down
      d: right
      e: t
      q: u
      f: d
#      c: n
      x: kp0

If modmap works then we could try that plus a script that uses xmodmap, replace $USER with your username.

modmap:
  - name: Company Of Heroes 2
    remap:
      enter:
        skip_key_event: false
        press: { launch: ["/home/$USER/.local/bin/remap"] }
        release: { launch: ["echo"] } # Required dummy command

Create the file ~/.local/bin/remap with the contents below

#!/usr/bin/bash

if [[ $1 == reset ]] || [[ -e /tmp/remapped ]]; then
    # reset
    rm /tmp/remapped 2> /dev/null
    xmodmap -e 'keycode 25 = W'       # w
    xmodmap -e 'keycode 38 = A'       # a
    xmodmap -e 'keycode 39 = S'       # s
    xmodmap -e 'keycode 40 = D'       # d
    xmodmap -e 'keycode 26 = E'       # e
    xmodmap -e 'keycode 41 = F'       # f
    xmodmap -e 'keycode 24 = Q'       # q
    xmodmap -e 'keycode 54 = C'       # c
    xmodmap -e 'keycode 53 = X'       # x
else
    # activate
    touch /tmp/remapped
    xmodmap -e 'keycode 25 = Up'      # w
    xmodmap -e 'keycode 38 = Left'    # a 
    xmodmap -e 'keycode 39 = Down'    # s
    xmodmap -e 'keycode 40 = Right'   # d
    xmodmap -e 'keycode 26 = T'       # e
    xmodmap -e 'keycode 41 = D'       # f
    xmodmap -e 'keycode 24 = U'       # q
    xmodmap -e 'keycode 54 = N'       # c
    xmodmap -e 'keycode 53 = KP_0'    # x
fi

and make it executable with chmod +x ~/.local/bin/remap.

Then do the same with this ~/.local/bin/start_stop_remap

#!/usr/bin/bash

if [[ -e /tmp/start_remap ]]; then
    killall xremap
    sleep 2
    ~/.local/bin/remap reset
    rm /tmp/start_remap

else
    touch /tmp/start_remap
    xremap ~/.xremap_remap.yml& # add --device if needed
    sleep 2 
    ~/.local/bin/remap
fi

Then before you start the game run start_stop_remap and run it again after the game to reset things. I had to add a small delay of 2s to make sure it worked properly, so it will take that long to exit after xremap is started.

When you run start_stop_remap the first time the config will be active, ie w = Up, if you need it the other way round then we can edit the script. When you run it the second time it will reset it to normal ie w = w.

I’ve tested it here and it works, but unfortunately I don’t have a suitable game to test whether it’ll work for your use case. I copied it manually again and double checked it’s correct, but if there are any errors let me know.

If it works then add the rest of your config to ~/.local/bin/remap

:crossed_fingers:

That’s expected, after a reboot you should be able to run xremap without sudo. I created the second command based on what’s said in the readme on github.

If this module is not loaded, add to /etc/modules-load.d/uinput.conf:

uinput


I meant to ask this sooner, but clearly forgot. Have you opened an issue with ahk_x11 about the stuck key issue?

2 Likes

That is really detailed, thank you very much for the effort. I will try it tomorrow.
But why does it have to be so complicated. With ahk_x11 it should be just w::up,… thats all.
I also came across a program called Autokey. It can start a script with a hotkey.
Isn’t there a realy simple solution which I overlook?

No and I don’t know how. I don’t even know if the problem is with ahk_x11 or with my Manjaro / Plasma instalation (it is a new installation but I still have dual boot). Maybe it’s too bleeding edge or corrupted.

I’m thinking of switching to Kubuntu and trying it out with stable 24.04 to compare. Unfortunately I have, in the “best Germany ever” as our former Chancellor Merkel once said, an internet connection like in Burkina Faso. Downloading the game and proton (~50Gb) takes 6 hours and I pay 40€ /m for this crap.

However, I’d like to try your solution first.

1 Like

Well ahk_x11 is much more complicated, but it’s already written for you along with a PKGBUILD to build and install the software, so that complexity is hidden. You just have to install it and then configure it.

I’m trying to replicate the behaviour with what’s easily available, using what knowledge I have (and without the ability to test it properly myself). It’s a bit hacky, but I’m not going to try writing a full ahk_x11 replacement, or a new configuration syntax to map to the underlying software (both of which are much more complicated and time consuming).

In this case you have to install it manually, but then the config is just in remap though admittedly the syntax isn’t as nice, and it’s only a subset of the full functionality of ahk_x11 (assuming it works properly).

There’s no need for separate software to create keyboard shortcuts. You can bind start_stop_remap (or any other command/script) to a keyboard shortcut in

System Settings → Keyboard → Shortcuts → Add New

Though Autokey may offer more advanced features.

We may well be overlooking something simple, I don’t know every piece of software that could possibly be used for this. The game complicates things though, as they often grab input at a very low level (as we’ve found with this one).

The other thing that complicates it, is the requirement for Enter to switch between the key mappings. If it weren’t for that we may just be able to make a single script (which uses xmodmap) bound to a keyboard shortcut.

It’s possible it is distro specific, things do vary between distros. Testing with another distro is a good idea. However it’s also possible that it’s down to how ahk_x11 (and possibly the game) works, or that the devs can fix it either way. It’s also possible that it can’t be fixed. I don’t know enough about it to say.

The devs may well have a better idea, as they understand their software.

If you haven’t already got a Github account then create one, and then create a new issue. Much like you did here but only include the ahk_x11 stuff. Try to include as much relevant information as possible. I did mean to suggest it in my first post but I clearly forgot.

However it may be hit and miss, you don’t always get a response and if you do it may not be very helpful. It varies a lot depending on the issue, project, the devs, etc.

I hope it works. :crossed_fingers:

1 Like

Yes it works, you forgot an than in ~/.local/bin/start_stop_remap.

No, as soon as I click it the first time, w=w etc., the second time it works and you can toggle the mapping. It also works smoothly in-game as if wasd are the real arrow keys. No lag, stutter or anything else.

Tried Kubuntu 24.10 and it behaves the same. This also applies to the online accounts. Google login doesn’t work like it soesn’t work in Manjaro. So I tried 24.04 LTS with Plasma 5 and the online accounts don’t work there either. So I gave it up because I need calendar, Google Drive and email. Now I’m on Linux Mint 22 but ahk_x11 behaves the same. So no improvement or difference.

Maybe I give Manjaro Gnome a try because it doesn’t make any difference (for the wasd script) but the online accounts should work.

1 Like

Glad it works. :slight_smile:

I was just testing you. :grin:

I also missed & off the end of the xremap call, sorry about that, fixed now.

That missing & would cause this, because the call to remap comes after that and isn’t run because xremap is blocking it.

Great, that’s what I expected (if it worked). :slight_smile:

The scripts should work there too, as long as xremap and xmodmap are installed.

Now. I find this more simple solution to me because of the GUI.

Install xmodmap from AUR or in terminal:

sudo pacman -S xorg-xmodmap

Install Autokey from AUR or terminal:

sudo pamac install autokey

or sudo pamac install autokey-git I’m not shure

start Autokey and add a new script
call it what you want e.g. remap_on

import subprocess

# remap arrow keys to wasd
subprocess.run("xmodmap -e 'keycode 25 = Up'", shell=True)
subprocess.run("xmodmap -e 'keycode 38 = Left'", shell=True)
subprocess.run("xmodmap -e 'keycode 39 = Down'", shell=True)
subprocess.run("xmodmap -e 'keycode 40 = Right'", shell=True)

subprocess.run("xmodmap -e 'keycode 26 = t'", shell=True) # e
subprocess.run("xmodmap -e 'keycode 41 = d'", shell=True) # f
subprocess.run("xmodmap -e 'keycode 24 = u'", shell=True) # q
subprocess.run("xmodmap -e 'keycode 54 = n'", shell=True) # c
# subprocess.run("xmodmap -e 'keycode 40 = x'", shell=True) #num_0 can't find this

assign a hotkey e.g. alt+x
click on save

add a second script and call it remap_off:

import subprocess

# remap wasd back to default
subprocess.run("xmodmap -e 'keycode 25 = W'", shell=True)
subprocess.run("xmodmap -e 'keycode 38 = A'", shell=True)
subprocess.run("xmodmap -e 'keycode 39 = S'", shell=True)
subprocess.run("xmodmap -e 'keycode 40 = D'", shell=True)

subprocess.run("xmodmap -e 'keycode 26 = E'", shell=True) # e
subprocess.run("xmodmap -e 'keycode 41 = F'", shell=True) # f
subprocess.run("xmodmap -e 'keycode 24 = Q'", shell=True) # q
subprocess.run("xmodmap -e 'keycode 54 = C'", shell=True) # c
# subprocess.run("xmodmap -e 'keycode 40 = x'", shell=True) #num_0 can't find this

assign a hotkey e.g. alt+c
click on save

go to edit / preference and check:
Automaticaly start AutoKey at login.

that seems to work. I will find out in the next days how to monitor an application because AutoKey has (under the hotkey) an entry “Window filter”

EDIT:
To find out the keycodes run this:

xmodmap -pk

Obviously use whatever you want. :slight_smile:

However I’m not sure why you think it’s so complicated, it’s just copy two files, make them executable and optionally bind one script to a key or combo (I used xremap to bind it to Enter but obviously that’s not the only option).

Then to use, you press the key/combo (or run the script in a terminal) and start your game, play, end the game and press it again.

(For completeness, I’ve updated remap with the rest of the config and removed the space at the beginning of the shebang, tested and copied directly from my laptop this time)

:man_shrugging:


Anyway as you seem to have removed the requirement for Enter to switch, it could be done in a single script bound to a key or combo.

You could use Autokey or xremap to run remap to do this if you wanted, or just create a global shortcut in System Settings.

Running remap with Autokey.

import subprocess

subprocess.run("~/.local/bin/remap", shell=True)

Combine this or the one below with window filtering and you might be able to use Enter to switch. However it’ll be mapped to the normal keys ie w=w until you press Enter (or whatever key/combo you decide on).

Your two scripts combined (a python version of remap).

import subprocess
from pathlib import Path

p = Path("/tmp/remapped")

if p.exists():
    # remap wasd back to default
    subprocess.run("xmodmap -e 'keycode 25 = W'", shell=True)
    subprocess.run("xmodmap -e 'keycode 38 = A'", shell=True)
    subprocess.run("xmodmap -e 'keycode 39 = S'", shell=True)
    subprocess.run("xmodmap -e 'keycode 40 = D'", shell=True)

    subprocess.run("xmodmap -e 'keycode 26 = E'", shell=True) # e
    subprocess.run("xmodmap -e 'keycode 41 = F'", shell=True) # f
    subprocess.run("xmodmap -e 'keycode 24 = Q'", shell=True) # q
    subprocess.run("xmodmap -e 'keycode 54 = C'", shell=True) # c
    subprocess.run("xmodmap -e 'keycode 53 = x'", shell=True) #num_0 
    p.unlink()
else:
    # remap arrow keys to wasd
    subprocess.run("xmodmap -e 'keycode 25 = Up'", shell=True)
    subprocess.run("xmodmap -e 'keycode 38 = Left'", shell=True)
    subprocess.run("xmodmap -e 'keycode 39 = Down'", shell=True)
    subprocess.run("xmodmap -e 'keycode 40 = Right'", shell=True)

    subprocess.run("xmodmap -e 'keycode 26 = t'", shell=True) # e
    subprocess.run("xmodmap -e 'keycode 41 = d'", shell=True) # f
    subprocess.run("xmodmap -e 'keycode 24 = u'", shell=True) # q
    subprocess.run("xmodmap -e 'keycode 54 = n'", shell=True) # c
    subprocess.run("xmodmap -e 'keycode 53 = KP_0'", shell=True) # num_0
    open(p, 'a').close()

It’s called KP_0 or KP_Insert (depends if num lock is on). I’ve added it into remap and the combined python version above.

 90     0xff9e (KP_Insert)  0xffb0 (KP_0)   0xff9e (KP_Insert)  0xffb0 (KP_0)

With AutoKey it works quite well. If I set “enter” as hotkey and “steam_app_231430.steam_app_231430” as window filter it toggles it in the chat. the only thing is that I have to press enter again before I quit the game otherwise the mapping stays in the desktop, browser etc. and you can no longer switch it with enter (which is good)

However, AutoKey completely destroys my Gnome extensions but I found out if you uncheck “show a notification icon” in edit / preference everything should work.

I messed something up with the solution using xremap and the 2 (or rather 3) scripts. Because toggling doesn’t work
This is how I did it now:
~/.coh.yml:

modmap:
  - name: Company Of Heroes 2
    application:
      only: steam_app_231430.steam_app_231430
    remap:
      enter:
        skip_key_event: false
        press: { launch: ["/home/tom/.local/bin/remap"] }
        release: { launch: ["echo"] } # Required dummy command

~/.local/bin/start_stop_remap:

#!/usr/bin/bash

if [[ -e /tmp/start_remap ]]; then
    killall xremap
    sleep 2
    ~/.local/bin/remap reset
    rm /tmp/start_remap

else
    touch /tmp/start_remap
    xremap --device "Logitech K400 Plus" ~/.coh.yml& # add --device if needed
    sleep 2 
    ~/.local/bin/remap
fi

~.local/bin/remap

#!/usr/bin/bash

if [[ $1 == reset ]] || [[ -e /tmp/remapped ]]; then
    # reset
    rm /tmp/remapped 2> /dev/null
    xmodmap -e 'keycode 25 = W'       # w
    xmodmap -e 'keycode 38 = A'       # a
    xmodmap -e 'keycode 39 = S'       # s
    xmodmap -e 'keycode 40 = D'       # d
    xmodmap -e 'keycode 26 = E'       # e
    xmodmap -e 'keycode 41 = F'       # f
    xmodmap -e 'keycode 24 = Q'       # q
    xmodmap -e 'keycode 54 = C'       # c
    xmodmap -e 'keycode 53 = X'       # x
else
    # activate
    touch /tmp/remapped
    xmodmap -e 'keycode 25 = Up'      # w
    xmodmap -e 'keycode 38 = Left'    # a 
    xmodmap -e 'keycode 39 = Down'    # s
    xmodmap -e 'keycode 40 = Right'   # d
    xmodmap -e 'keycode 26 = T'       # e
    xmodmap -e 'keycode 41 = D'       # f
    xmodmap -e 'keycode 24 = U'       # q
    xmodmap -e 'keycode 54 = N'       # c
    xmodmap -e 'keycode 53 = KP_0'    # x
fi

and

chmod +x ~/.local/bin/remap
chmod +x ~/.local/bin/start_stop_remap

Anyway, I can live with the AutoKey solution.
but maybe you can explain to me what I messed up.

If someone reads this in the future who just wants to remap the keys for a game (without toggling), the easiest way is to install xremap and in ~/.my_script.yml:

modmap:
  - name: Company Of Heroes 2
    application:
      only: steam_app_231430.steam_app_231430
    remap:
      w: up
      a: left
      s: down
      d: right
      # etc.

and then somehow insert this into the autostart:

xremap --device "Logitech K400 Plus" ~/.my_script.yml

TThe mapping is only active in the game then because the application monitoring works well and you don’t need to install any additional tools or write any additional scripts
EDIT:
and of course this to be able to run xremap without sudo:

Do you get any error messages?

Your files work here, I had to remove the device from start_stop_remap and the application fields from coh.yml because my keyboard is different and I don’t have the game. If there aren’t any extra spaces or lines at the top of the scripts, then I’d say it’s probably the application matching.

No error. If I click on start_stop_remap the terminal start reamap and as its finished it dissapears.
However I stick with the AutoKey solution. This thread can be closed.