RedBearAK / toshy

Keymapper config to make Linux work like a 'Tosh!
https://toshy.app
GNU General Public License v3.0
226 stars 15 forks source link

(Question) How to write {} and [] #268

Open Mat1eub opened 2 months ago

Mat1eub commented 2 months ago

I'm in french (belgian) keyboard on macbook pro and I used to type {} with option+'(' and [] with option+shift+'(' but that's typing that instead :  and û Thank you so much for the work you already did and waiting for your answer !

RedBearAK commented 2 months ago

@Mat1eub

Non-US keyboard layouts have issues with the keymapper, for reasons I don't fully understand and don't have a true solution for yet. I'll try to keep the explanation as simple as possible.

Part 1: Option-key special characters

When you have the OptSpec layout enabled in Toshy preferences, there are only two layouts, and they are hard-coded to either the standard US layout, or the "ABC Extended" US layout. But the special characters are available while using either Option key position.

If you disable the Toshy OptSpec layout from the tray icon menu (or the GUI preferences app), and instead choose a "Macintosh" keyboard layout variant for your keyboard language, you'll have something more like what you might be used to from that keyboard while using macOS. But you'll have to enable the "Alt_Gr on Right Cmd" option in the tray icon menu (or the GUI preferences app), and you'll only be able to access the special characters using the Cmd key on the right side. This is a limitation in how Linux deals with the ISO level 3 characters for international layouts or special "symbol" layout variants.

How you get to these alternate layout variants like the "Macintosh" variant depends on which Linux desktop environment you are using. I don't think they always perfectly match the characters on a real Apple keyboard in macOS, but they might have the symbols you are looking for, in the same places.

Alternately, because the OptSpec remaps are hard-coded in the config file, you could actually change what those key combos do by modifying the config file to output the characters you expect, instead of Unicode symbols. But most of the other special characters will continue to be the ones from the US layout, or ABC Extended layout. I documented them here:

https://github.com/RedBearAK/optspecialchars

If you only need to access a few characters like your examples via the Option key, it is feasible to just edit the config file, and I can show you the lines that would need to be edited.

Part 2: The key definition file

The keymapper has a key definition file that maps key codes to key symbol names. I believe it originates from the Linux kernel input system, and it just uses a standard US layout to give the key codes symbol names. Without modifying that file, you can run into problems where the virtual keyboard device will emit incorrect characters for transformed shortcuts or macro strings. You might not have noticed this problem yet.

Here is a quick and very unfortunate example: The US layout is QWERTY. If you're on an AZERTY layout and press a combo like Cmd+A (which should be "Select all" in many apps), what will get sent to the application window is Alt+F4 to close the window, because you pressed the physical equivalent of Cmd+Q on a US keyboard, and that is a shortcut that gets transformed in the config file. On the other hand shortcuts that don't need to be remapped in the config file will operate normally, undergoing the normal layout translation.

In short, the keymapper isn't aware of the symbol on the key, only the key code, and for some reason the usual layout translation to the correct symbols doesn't apply to the output from the virtual keyboard. Or something.

Some of these things can be fixed by modifying the key.py file to more closely match your layout. But it can be somewhat complicated especially with characters that would normally be the base character on a US layout, but need the Shift key on an international layout. The key definition file only cares about the base key code.

Conclusion

I've been looking for a good solution to this for a long time, but haven't made much progress. Let me know if you want to try to fix your issues with the tweaks that I've described. Modifying the key.py file will only make sense if that is the only keyboard layout you will ever use. And you would need to keep a backup of the modified file, in case you need to reinstall Toshy, which would reinstall the keymapper from the source.

No international user has yet sent me a fully modified key.py file that I could include with the keymapper to make it easier for other users to deal with a non-US layout.

Mat1eub commented 2 months ago

It's only those few characters that need to be edited but I can't find the file where I can edit them like you told me to in the first part of your message. But that would be very much appreciated if you show me what to change

RedBearAK commented 2 months ago

In the tray icon menu there is an item "Open Config Folder" that gets you to the Toshy config location easily, which is ~/.config/toshy/.

The file for part 1 is located here:

~/.config/toshy/toshy_config.py

The file for part 2 is located in that same folder, but deeper inside a Python virtual environment folder, and the path will vary slightly according to the version of Python that was used to create the venv.

~/.config/toshy/.venv/lib/python3.12/site-packages/xwaykeyz/models/key.py

Check the Python version in a terminal with python --version. I have Python 3.12.x on Fedora 39.

The files can be edited in any text or code editor, of course. They are just text files with a .py extension.

Assuming that your keyboard layout looks like this:

https://keyshorts.com/blogs/blog/37615873-how-to-identify-macbook-keyboard-localization#belgian

http://kbdlayout.info/KBDBE/

Then the "(" and ")" keys you're talking about are on the "5" and "Minus" keys on a US layout.

Before editing either of the files, note that you'll need to keep a backup of the modified files somewhere outside the ~/.config/toshy location, or reinstalling Toshy will wipe out the changes you make in this case.

Taking a look at what the Option-key special characters are in the "[US MAIN]" section of the config file:

keymap("OptSpecialChars - US", {
...
    C("Alt-5"):                 UC(0x221E),                     # ∞ Infinity mathematical symbol
...
    C("Alt-Minus"):             UC(0x2013),                     # – En Dash punctuation mark
...
    C("Shift-Alt-5"):           UC(0xFB01),                     # fi Latin Small Ligature Fi
...
    C("Shift-Alt-Minus"):       UC(0x2014),                     # — Em Dash punctuation mark
...

You must be in GNOME or these Unicode characters wouldn't work at all. But you're just looking for regular characters so this modification should work:

keymap("OptSpecialChars - US", {
...
    # C("Alt-5"):                 UC(0x221E),                     # ∞ Infinity mathematical symbol
    C("Alt-5"):                 C("Shift-Left_Brace"),          # { Left curly brace
...
    # C("Alt-Minus"):             UC(0x2013),                     # – En Dash punctuation mark
    C("Alt-Minus"):             C("Shift-Right_Brace"),         # } Right curly brace
...
    # C("Shift-Alt-5"):           UC(0xFB01),                     # fi Latin Small Ligature Fi
    C("Shift-Alt-5"):           C("Left_Brace"),                # [ Left square bracket
...
    # C("Shift-Alt-Minus"):       UC(0x2014),                     # — Em Dash punctuation mark
    C("Shift-Alt-Minus"):       C("Right_Brace"),               # ] Right square bracket
...

Make this change, save the config file, and restart Toshy from the tray icon menu (or run toshy-services-restart in a terminal). See if that works.

Note that if you switched the "OptSpec Layout" to the "ABC Extended" you'd need to find those same lines and modify them in the "[ABC]" section, marked with the large ASCII art block. It comes just before the "[US MAIN]" block.

And if you disable the OptSpec Layout then those characters would stop working, or those keys would just do what they would normally do when Toshy is disabled. I don't know what that would be, and the layout shown on the second link above is quite confusing. I think there's even a mistake with an extra curly brace and missing square bracket.

For part 2, if you want to fix something major like swapping A and Q in the key.py file, it would go like this:

# https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h
class Key(IntEnum, metaclass=KeyMeta):
    """ representation of a single keyboard key"""
...
    # Q = 16
    Q = 30
...
    # A = 30
    A = 16
...

Editing this file also necessitates restarting Toshy (to restart the keymapper process using the new state of the file).

You'd probably also want to swap W and Z (since it's AZERTY vs QWERTY), maybe a couple of other things. Hard to say what shortcut might eventually cause you trouble if you leave the key definitions the way they are.

As noted before, any combo that doesn't get remapped by the keymapper or any normal typing will always work just fine without such modifications. They just get "passed through", so the keymapper doesn't cause a problem most of the time.

Let me know how it goes or if you need additional assistance with tweaking something.

Mat1eub commented 2 months ago

Ok, thank you so much for the help now I changed it but it writes ¨ and * for Alt+5 and Alt+Minus and it writes ^ and $ for Alt+Shift+5 and Alt+Shift+Minus.

Mat1eub commented 2 months ago

Do you think it has anything to do with that : AskRedKeyobard

RedBearAK commented 2 months ago

OK, I think I remember an important aspect of this problem, which is that when the virtual keyboard types the bracket and curly brace symbols, the system acts like you've typed the keys with those symbols on the US layout, which for French/Belgian are the two keys next to the Enter key.

So the "output" combo actually needs to be whatever physical keys you use (actually, the numeric key codes) to get to the characters you want when Toshy is not enabled.

Disable Toshy from the tray icon menu (Stop Toshy Services) and then tell me how you type the symbols you want (brackets, curly braces). Which physical keys do you use to get those characters to come out? In both sets of characters I think you'll be using the Alt_Gr key normally (without the keymapper being involved). But I can't tell what the other physical keys should be on your layout to get the left/right bracket and curly brace symbols.

Once we know that, we should be able to make it work.

But can you also show what you have selected for the keyboard in the hardware (Matériel) tab, and on the left what it shows in "Virtual Keyboard" (Clavier virtuel)?

{[}]

Wait, I may have it now. It does require Alt_Gr (testing on a French layout on my own keyboard, with the keymapper disabled), which for the keymapper config will be "RAlt".

keymap("OptSpecialChars - US", {
...
    # C("Alt-5"):                 UC(0x221E),                     # ∞ Infinity mathematical symbol
    C("Alt-5"):                 C("RAlt-5"),          # { Left curly brace
...
    # C("Alt-Minus"):             UC(0x2013),                     # – En Dash punctuation mark
    C("Alt-Minus"):             C("RAlt-Minus"),         # } Right curly brace
...
    # C("Shift-Alt-5"):           UC(0xFB01),                     # fi Latin Small Ligature Fi
    C("Shift-Alt-5"):           C("Shift-RAlt-5"),                # [ Left square bracket
...
    # C("Shift-Alt-Minus"):       UC(0x2014),                     # — Em Dash punctuation mark
    C("Shift-Alt-Minus"):       C("Shift-RAlt-Minus"),               # ] Right square bracket
...

In theory, that should get the correct characters to come out. Think of it as if the keymapper's virtual keyboard output is like a ghost sitting at your computer typing the characters for you. We have to tell it to "press" the same physical keys (the numeric key codes) you would normally use to get those characters (but the names of those keys still have to be what the names would be on the standard US layout, "5" and "Minus", because of the key definition file). Then the result should be what it would normally be.

Let me know how it goes this time.

Mat1eub commented 2 months ago

It works perfectly fine now I can finally type {}[] ! Thank you so much for the time you took to help me !

RedBearAK commented 2 months ago

Good to hear it is working, and this has helped me understand what the problem with the keymapper is. I'm planning on keeping this open until I find some sort of better solution. If I find one, I might ask you to test it.

Watch out for those other problems that may come from the bad key definitions. There are several keys on the right side of that layout that are in different places than the standard US layout, and the whole top row is different. Any combos that use a key in that area may not work correctly.