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

How do I find keycodes for special German / Danish / Nordic keys to use in defsrc? #360

Closed
humanplayer2 opened this issue Sep 19, 2021 · 11 comments

Comments

@humanplayer2
Copy link

humanplayer2 commented Sep 19, 2021

I'm trying to set up using a laptop with a Danish keyboard. It's a ThinkPad, and I have been using the X220 DE template by @slotThe to get started defining my defsrc block.

The template quickly doesn't match, as my keyboard has ½ left of 1, so I replace that just with ^ as in the X220 template, to get started. Alas:

kmonad: Parse error at 24:3:
   |
24 |   ^    1    2    3    4    5    6    7    8    9    0    kp+  grv       bspc
   |   ^
unexpected '^'
expecting ')' or keycode

Figuring that maybe I can't just paste, I try replacing ^ with +:

kmonad: Parse error at 24:3:
   |
24 |   +    1    2    3    4    5    6    7    8    9    0    kp+  grv       bspc
   |   ^
unexpected '+'
expecting ')' or keycode

OK. So I look up the keycodes in Keycode.hs and see that maybe I should use kp+ instead of just +. Succés! Now that doesn't error.

Alas, my first Danish character does:

kmonad: Parse error at 25:58:
   |
25 |   tab  q    w    e    r    t    y    u    i    o    p    å    kp+       ret
   |                                                          ^
unexpected 'å'
expecting ')' or keycode

OK. I cant find anything relevant in Keycodes.hs, so to move on, I replace it with what is in the X220 template, namely ß -- eszett, the german double s. Alas, to no avail:

unexpected 'ß'
expecting ')' or keycode

Now I'm confused. I can't seem to find anything in Keycodes.hs. Others have seemingly had it working earlier. I'm at a loss.

How do I figure out what keycodes I should use to define my defsrc block?

I apologize if I have missed something obvious. I'm on the Ubuntu-related Pop!_OS 21.04 running Wayland.

@slotThe
Copy link
Member

slotThe commented Sep 20, 2021

The template quickly doesn't match, as my keyboard has ½ left of 1

The defsrc block is not really meant as an accurate representation of the layout that you want, but more of your physical keyboard as a whole. As a rule of thumb, always specify a generic US keyboard layout there.

It is also rather restricted in terms of what it accepts, hence symbols that wouldn't phase the parser in a deflayer block are giving you some troubles here.

@david-janssen
Copy link
Collaborator

@slotThe is spot on. The ink on your keys doesn't match the events that get sent to the kernel. The easiest solution would be to run evtest on your keyboard and inspect the events that get sent to the kernel. Those have to line up with your (defsrc ...) definition, and then the rest should work.

@humanplayer2
Copy link
Author

Thank you! Defining a US layout was straightforward, and I have now verified its correctness with evtest.

Mapping the US layout back to Danish, I run into some unforeseen and undesirable behavior.

Following the "Special characters" section in this suggested wiki-etry, I've added the following to else empty ~/.XCompose

include "%L"
<Multi_key> <a> <o> : "å"
<Multi_key> <a> <e> : "æ"
<Multi_key> <o> <e> : "ø"
<Multi_key> <1> <2> : "½"
<Multi_key> <1> <0> : "´"
<Multi_key> <1> <p> : "¨"
<Multi_key> <1> <a> : "'"

and use the following config.kbd:

(defcfg
  input   (device-file "/dev/input/by-path/platform-i8042-serio-0-event-kbd")
  output  (uinput-sink
            "KMonad: X1C9"
            "/usr/bin/sleep 1 && /usr/bin/setxkbmap -option compose:ralt")
  cmp-seq ralt
)

(defalias
    å #(ralt a o)
    æ #(ralt a e)
    ø #(ralt o e)
    ½ #(ralt 1 2)
    ´ #(ralt 1 0)
    ¨ #(ralt 1 p)
    ' #(ralt 1 a)
)

(defsrc
  esc  f1   f2   f3   f4   f5   f6   f7   f8   f9   f10  f11  f12  home end  ins  del
  grv  1    2    3    4    5    6    7    8    9    0    -    =         bspc
  tab  q    w    e    r    t    y    u    i    o    p    [    ]         ret
  caps a    s    d    f    g    h    j    k    l    ;    '    \
  lsft 102d z    x    c    v    b    n    m    ,    .    /              rsft
  wkup lctl lmet lalt           spc            ralt cmps rctl      back up   fwd
                                                                   left down rght
)

(deflayer default
  esc  f1   f2   f3   f4   f5   f6   f7   f8   f9   f10  f11  f12  home end  ins  del
  @½   1    2    3    4    5    6    7    8    9    0    +    @´        bspc
  tab  q    w    e    r    t    y    u    i    o    p    @å   @¨        ret
  caps a    s    d    f    g    h    j    k    l    @æ   @ø   @'
  lsft 102d z    x    c    v    b    n    m    ,    .    -              rsft
  wkup lctl lmet lalt           spc            ralt cmps rctl      back up   fwd
                                                                   left down rght
)

That works, partially, but with a lot of issues. The keys work, but in different ways, each key acts unexpected in combination with ´Shift´ and ´AltGr´.

Am I missing some step?

@david-janssen
Copy link
Collaborator

No, that is how special characters work in Linux, we use compose sequences to emit rapid macros that tell the OS what to encode. I.e. we emit something like altgr -> shifted-' -> e to emit an e-umlaut. This is an alright method of emitting special characters if you don't need them too much.

The other option that might work better if you have to use special characters a lot is to simply emit the raw keycodes that your keyboard would have (i.e. if you test evtest on æ and it says that internally it's coded as ;, you can encode your keyboard to just emit a ; (maybe document it in the comments of your keymap). Then you can let the internationalization settings of your OS deal with translating it into a æ.

Do you understand what I'm describing?

@humanplayer2
Copy link
Author

I believe I do, and thank you for it!

As option 1 doesn't seem to work ideally for me (e.g., I do need my Shift + ø to be Ø, not Œ ), I tried option 2.

Option 2 works under X, but not under Wayland, when I boot with no remappings active and my input source set to Danish, run kmonad with a config file where deflayer default is identical with defscr from my comment above, with nothing in my .XCompose.

@david-janssen
Copy link
Collaborator

Good to hear it works well under X. In regards to Wayland, I haven't had a chance at all to test things on Wayland (I'm a sucker for XMonad, so I'm going to ride this sinking ship for as long as I can). I should probably install it and run a standard WM, at least for testing purposes. I'll have a go at that when I've finished wrapping up the current refactoring I'm working on.

I'm guessing that if an actual, physical keyboard can be made to work well with Wayland using Danish input mappings, then KMonad must be doable too, since we don't rely at all on X. What I would investigate first, if I were you, is if Wayland will map *all * keyboards to Danish-mode. I.e. when you start KMonad we essentially 'create' a simulated keyboard using the uinput subsystem of the linux kernel, you might need to execute a command to make Wayland interpret this new keyboard as a Danish one. I'd think that approach is likely to produce desired results.

@humanplayer2
Copy link
Author

The KMonad name did seem to hint to somebody's preferences :)

I'm sorry if I'm being slow here, but what you are suggesting is that I as a first step get my hands on an external, non-Danish keyboard and check whether that acts as desired with my input source set to Danish, under Wayland?

And if not, then troubleshoot that, learn a lesson, and apply the same to KMonad?

@david-janssen
Copy link
Collaborator

I'm sorry if I'm being slow here, but what you are suggesting is that I as a first step get my hands on an external, non-Danish keyboard and check whether that acts as desired with my input source set to Danish, under Wayland?

Oops: didn't explain my suggestion correctly.

What I was suggesting was treating your KMonad remapping entirely as US-english, but keeping in the back of your head that your OS is going to be remapping some US keys to Danish keys. So don't try to get KMonad to emit special characters, like Ø (which it will try to do using compose sequences), instead just get KMonad to emit the US character which your OS will interpret as Ø. That was all the shifting behavior etc. should just work out of the box.

@david-janssen
Copy link
Collaborator

Oh: and as an addendum, how you could do that under X:

After KMonad is launched, call an setxkbmap dk command, setting the (OS) keyboard map to something. Whenever you plug in a new keyboard, that command needs to be called, and when KMonad starts it 'plugs in' a simulated keyboard, so you'll have to call that after you start KMonad. There is a post-init setting in the defcfg section that will let you do this automatically, but experiment by hand first.

@slotThe
Copy link
Member

slotThe commented Nov 17, 2021

This seems fixed so I'm closing for now

@tuxflo
Copy link

tuxflo commented Jan 25, 2024

Sorry for commenting on an old, closed issue, but I wondered how exactly I could achieve the behavior described in:

What I was suggesting was treating your KMonad remapping entirely as US-english, but keeping in the back of your head that your OS is going to be remapping some US keys to Danish keys. So don't try to get KMonad to emit special characters, like Ø (which it will try to do using compose sequences), instead just get KMonad to emit the US character which your OS will interpret as Ø. That was all the shifting behavior etc. should just work out of the box.

Because this is exactly what I'm looking for. Basically, I want to be able to insert foreign symbols (German umlauts in my case) while a modifier key is pressed. I want to be able to get upper- and lowercase characters, which doesn't seem to work if I use the symbols directly in my kmonad mappings.

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

No branches or pull requests

4 participants