RedBearAK / toshy

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

(Question) Remap Original Super Key Functions to Ctrl and New Super Key Functions to Caps Lock #417

Open Rookiecom opened 2 weeks ago

Rookiecom commented 2 weeks ago

Is it possible to map the original functionality of the Super key to the Ctrl key, but map the new functionality of the Super key (for example, Super-D --> Delete) to the Caps Lock key?

RedBearAK commented 2 weeks ago

@Rookiecom

Can you be more specific about what you mean by the "original functionality of the Super key"? The Ctrl key does become a Super key under Toshy's modmapping, but only in non-terminal applications.

The latter part of the sentence also doesn't make it clear to me what you're looking to accomplish.

It's possible to modmap any single key into any other single key. Did you just want to turn the Caps Lock key into a Super key? Exactly what functionality are you looking for, in the end?

Rookiecom commented 2 weeks ago

@Rookiecom

Can you be more specific about what you mean by the "original functionality of the Super key"? The Ctrl key does become a Super key under Toshy's modmapping, but only in non-terminal applications.

The latter part of the sentence also doesn't make it clear to me what you're looking to accomplish.

It's possible to modmap any single key into any other single key. Did you just want to turn the Caps Lock key into a Super key? Exactly what functionality are you looking for, in the end?

I apologize for causing any confusion due to my impatience and for not explaining the issue clearly.

Screenshot from 2024-10-05 21-59-30

1728136830225

When Toshy is not installed, pressing the Super key usually behaves as shown in the picture(show app). However, if Toshy is installed, pressing the Ctrl key has no effect. Therefore, I want to separate the function of the Ctrl key. I want the current Ctrl key to take on the function of the original Super key, and the Caps Lock key to take on the function of the Super key as defined by Toshy. Screenshot from 2024-10-05 22-06-19

So when I mention the original function of the Super key, I am referring to the function it had before Toshy was installed.

RedBearAK commented 2 weeks ago

@Rookiecom

OK, I figured this was about GNOME.

So, GNOME is one of a few desktop environments where the Meta/Super/Win key is set up to perform an action by itself. But modifier-only shortcuts have a tendency to interfere with remapped shortcut combos that involve that modifier, and the modifiers also have to be moved around in order to simulate the Mac-style shortcuts. The Meta/Super/Win key ends up on the physical Ctrl key, and then when you're in an "terminal" app it disappears entirely.

Making the Caps Lock key into the Meta/Super/Win key is one idea, but if the GNOME overlay-key modifier-only shortcut was re-enabled, it would once again interfere with some shortcuts, and the Ctrl key would still also be a Meta/Super/Win key.

Toshy's config tries to make things work like macOS, so in GNOME it enables the "Show the overview" shortcut with the combo of Shift+Ctrl+Space and this is remapped onto from the physical equivalent of Cmd+Space, like the Spotlight shortcut in macOS.

The screenshot you showed is not the Overview, but the screen you get from the shortcut "Show all apps". On either the main Overview screen or the Apps screen, you can search for and launch apps and control panels, and search for files. But if you would prefer to see the Apps screen when you use Cmd+Space, you'll need to set up an override, or just change the shortcut associated with the "Show all apps" shortcut in the GNOME keyboard settings to be Shift+Ctrl+Space. (It's Super+A by default, and it can always be reset to the default.) An easy way to change the shortcut is to just press Cmd+Space after clicking to change the shortcut. It should end up showing Shift+Ctrl+Space, and then Cmd+Space will show the Apps screen.

The overlay-key is a toggle that cycles between the desktop, the Overview screen, and the Apps screen. That can't really be mimicked with a regular shortcut. So Toshy just uses the closest imitation of Spotlight, which is the main Overview screen.

If you wanted to have other functions on the Caps Lock key, like your Super+D -> Delete example (where would that be useful?), you might want to turn the Caps Lock into a Hyper key instead, and then set up a keymap to do some Hyper+key remaps onto existing combos. Either general or app-specific.

This issue thread discusses how to set up a Hyper key modifier. On the Caps Lock key.

https://github.com/RedBearAK/toshy/issues/388

If you can describe what other actions/combos you would want to use from the Hyper key on Caps Lock, I can help you make custom keymaps to make that work.

The "Finder Mods" in the config file make things like Cmd+Delete work like they do in the Finder, so I'm not sure where your Super+D -> Delete example was meant to be used, but file managers shouldn't need something like that.

Rookiecom commented 2 weeks ago

@Rookiecom

OK, I figured this was about GNOME.

So, GNOME is one of a few desktop environments where the Meta/Super/Win key is set up to perform an action by itself. But modifier-only shortcuts have a tendency to interfere with remapped shortcut combos that involve that modifier, and the modifiers also have to be moved around in order to simulate the Mac-style shortcuts. The Meta/Super/Win key ends up on the physical Ctrl key, and then when you're in an "terminal" app it disappears entirely.

Making the Caps Lock key into the Meta/Super/Win key is one idea, but if the GNOME overlay-key modifier-only shortcut was re-enabled, it would once again interfere with some shortcuts, and the Ctrl key would still also be a Meta/Super/Win key.

Toshy's config tries to make things work like macOS, so in GNOME it enables the "Show the overview" shortcut with the combo of Shift+Ctrl+Space and this is remapped onto from the physical equivalent of Cmd+Space, like the Spotlight shortcut in macOS.

The screenshot you showed is not the Overview, but the screen you get from the shortcut "Show all apps". On either the main Overview screen or the Apps screen, you can search for and launch apps and control panels, and search for files. But if you would prefer to see the Apps screen when you use Cmd+Space, you'll need to set up an override, or just change the shortcut associated with the "Show all apps" shortcut in the GNOME keyboard settings to be Shift+Ctrl+Space. (It's Super+A by default, and it can always be reset to the default.) An easy way to change the shortcut is to just press Cmd+Space after clicking to change the shortcut. It should end up showing Shift+Ctrl+Space, and then Cmd+Space will show the Apps screen.

The overlay-key is a toggle that cycles between the desktop, the Overview screen, and the Apps screen. That can't really be mimicked with a regular shortcut. So Toshy just uses the closest imitation of Spotlight, which is the main Overview screen.

If you wanted to have other functions on the Caps Lock key, like your Super+D -> Delete example (where would that be useful?), you might want to turn the Caps Lock into a Hyper key instead, and then set up a keymap to do some Hyper+key remaps onto existing combos. Either general or app-specific.

This issue thread discusses how to set up a Hyper key modifier. On the Caps Lock key.

388

If you can describe what other actions/combos you would want to use from the Hyper key on Caps Lock, I can help you make custom keymaps to make that work.

The "Finder Mods" in the config file make things like Cmd+Delete work like they do in the Finder, so I'm not sure where your Super+D -> Delete example was meant to be used, but file managers shouldn't need something like that.

Alright, I understand what you mean. Now, my current need is: pressing CapsLock should be equivalent to pressing Ctrl after installing toshy. Is this doable? Sorry, I didn't quite see the issue you mentioned.

Rookiecom commented 2 weeks ago

I just want to make using Ctrl more convenient, for example, in the terminal, pressing Ctrl-A to go to the beginning of the line. If CapsLock can replace Ctrl, it would make my pinky much more comfortable.

RedBearAK commented 2 weeks ago

I just want to make using Ctrl more convenient, for example, in the terminal, pressing Ctrl-A to go to the beginning of the line. If CapsLock can replace Ctrl, it would make my pinky much more comfortable.

This is relatively easy with a modmap. I’ll post the instructions later.

RedBearAK commented 2 weeks ago

OK, here we go. I don't know your technical level, and others who are less technical may read this and use the instructions, so I will be very thorough (also to avoid confusing myself). So don't take the instructions the wrong way if it seems like "baby steps" at times. And it will. 🌻 😸

Opening the config file for editing

You want to open up your config file for editing, in any "text" editor or "code" editor, avoiding "word processors" like LibreOffice Writer. It is a ".py" Python file, but literally is just plain text like all uncompiled "code" files.

[!NOTE] When you see a Tilde character ~, that represents your own home folder, like /home/myusername. This can be used in terminal commands and scripts to automatically adapt to the user's unique path. (You probably know this already, but some new Linux users might not.)

The tray icon menu has an item that usually works to directly open the config folder so you don't have to go looking for it. It's near the bottom of the menu and says "Open Config Folder".

If you want to go there manually, the config folder for Toshy is found at this path:

~/.config/toshy/

[!TIP] FYI for Linux newbies, any file or folder in Linux that starts with a "dot" character is normally "hidden" unless your file manager is set to show hidden files. Also in the terminal, commands like ls will not show "dotfiles" unless you add the -a flag to "show all" files.

Once you get the folder open, you might be able to double-click on the toshy_config.py folder to open it in an appropriate editor, but depending on how you have your file associations configured this might do something odd like open the file in Firefox. It's usually safer to open the file by right-clicking and using "Open With..." to pick an app like GNOME Text Editor or Visual Studio Code, or anything similar.

Do not go into the default-toshy-config folder. Those are backup default config files.

What to look for in the config file

Now that you have the config file open, look for this "tag": user_custom_modmaps

You should find a section looking like this, with nothing inside:

# Suggested location for adding custom modmaps for personal use.
###################################################################################################
###  SLICE_MARK_START: user_custom_modmaps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE

###  SLICE_MARK_END: user_custom_modmaps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE
###################################################################################################

This is prepared as a logical location for exactly this kind of user customization. Putting the modmap in any of the marked editable "slices" anywhere in the config file will protect your addition from a reinstall or manual update of Toshy. Outside the slices any changes will get overwritten and will only exist in a backup folder.

Setting up the modmap

# Suggested location for adding custom modmaps for personal use.
###################################################################################################
###  SLICE_MARK_START: user_custom_modmaps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE

modmap("CapsLock is Left Ctrl", {
    Key.CAPSLOCK:               Key.LEFT_CTRL,                  # Modmap Caps Lock to be a Ctrl key (not Cmd)
}, when = lambda ctx:
    cnfg.screen_has_focus and
    matchProps(not_clas=remoteStr)(ctx) )

###  SLICE_MARK_END: user_custom_modmaps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE
###################################################################################################

The conditional on this one will make this modmap (basically a change of the key's identity) active at all times, except when using any kind of known "remote desktop" or "virtual machine" app window (not_class=remoteStr). The same conditional expression used by the "General" modmaps and keymaps to enable common global shortcuts like Cmd+Z/X/C/V/Q/W and so on.

In the case that you want the Caps Lock key to be a logical Ctrl key only in "terminals", and perhaps you want Caps Lock to be an additional virtualized Cmd key outside of terminals, you'd do something more like this:

# Suggested location for adding custom modmaps for personal use.
###################################################################################################
###  SLICE_MARK_START: user_custom_modmaps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE

modmap("CapsLock is Right Ctrl in GenGUI", {
    Key.CAPSLOCK:               Key.RIGHT_CTRL,                 # Modmap Caps Lock to be a Cmd key
}, when = lambda ctx:
    cnfg.screen_has_focus and
    matchProps(not_clas=terms_and_remotes_Str)(ctx) )

modmap("CapsLock is Left Ctrl in GenTerms", {
    Key.CAPSLOCK:               Key.LEFT_CTRL,                  # Modmap Caps Lock to be a Ctrl key (not Cmd)
}, when = lambda ctx:
    cnfg.screen_has_focus and
    matchProps(clas=termStr)(ctx) )

###  SLICE_MARK_END: user_custom_modmaps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE
###################################################################################################

The order of the modmap structures is important in this case. One will "override" the other by being hit first in memory.

Testing the change to see if it works

With this kind of modification of the config file, it's a good idea to use the toshy-debug command in the terminal to run the configuration manually before attempting a services restart, in case there is a typo that will stop the config from loading. In which case there would be a helpful Python exception error in the terminal.

toshy-debug

Let the config start up completely (~7 seconds and output will stop) before touching the keyboard, or a key might seem to get "stuck" in the pressed state. If this happens and Ctrl+C or Cmd+Dot doesn't work, just close the terminal tab or window to kill the process.

After the initial output stops you can start pressing keys and see what happens. You should see the Caps Lock key becoming a Ctrl key, depending on which app window you are in, and which of the suggestions above you decided to use.

Older installs of Toshy may not have the newer toshy-debug alias, but will have or or both of these equivalents:

toshy-config-verbose-start (quicker to Tab-complete with tosh [Tab] co [Tab] ve [Tab][Enter])
toshy-config-start-verbose (the original script name)

To go back to normal operation of Toshy, just use the tray icon to restart the services. The debugging output in the terminal should automatically stop.

Let me know if you need any clarifications.

Edit: I tested the dual-modmap example myself and it seems to do exactly what I expected. Before that, I corrected a typo that was in the original unedited comment. Either example should work with no issue.

Rookiecom commented 1 week ago

not_class-->not_clas

# Suggested location for adding custom modmaps for personal use.
###################################################################################################
###  SLICE_MARK_START: user_custom_modmaps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE

modmap("CapsLock is Left Ctrl", {
    Key.CAPSLOCK:               Key.LEFT_CTRL,                  # Modmap Caps Lock to be a Ctrl key (not Cmd)
}, when = lambda ctx:
    cnfg.screen_has_focus and
    matchProps(not_clas=remoteStr)(ctx) )

###  SLICE_MARK_END: user_custom_modmaps  ###  EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE
###################################################################################################

After correcting the code above, the terminal behaves as expected, but in the graphical interface, like in a browser, pressing CapsLock + Tab switches tabs, which is as expected. However, pressing CapsLock + A results in 'Select All'. I know this is because the Ctrl + A effect provided by toshy isn't installed, but I expect it to behave like the Ctrl + A effect from toshy (moving to the beginning of the line). Pressing CapsLock + F moves forward, and pressing CapsLock + B moves backward... I mainly use these functions for quick text editing.

Additionally, I would like to ask how to set the Caps Lock key to function as Esc when tapped and as Ctrl(the ctrl after toshy is installed) when held down.

RedBearAK commented 1 week ago

I corrected that typo in the second example. Didn't notice it was also in the first example.

However, pressing CapsLock + A results in 'Select All'. I know this is because the Ctrl + A effect provided by toshy isn't installed, but I expect it to behave like the Ctrl + A effect from toshy (moving to the beginning of the line).

Yeah, this is why I suggested making it a Command key in non-terminal apps. If it's just a LEFT_CTRL key all the time, it's not going to do the same things in terminals and in GUI apps. The way Toshy gets the virtualized Cmd+A to be "select all" is just that Cmd is RIGHT_CTRL and the native Linux shortcut for "select all" is Ctrl+A. So naturally your CapsLock+A will do the same thing. When you aren't in a terminal.

This is a case where you might want to think about making the Caps Lock key a "Hyper" key when you aren't in terminals. Then you could set up a specific keymap to make Hyper+A and the other shortcuts do what you want.

I would like to ask how to set the Caps Lock key to function as Esc when tapped and as Ctrl (the ctrl after toshy is installed) when held down.

For that you would use a multipurpose_modmap() instead of a modmap(). The only difference is after the colon instead of a single key you'd put two different keys in a list "[]" format. But, I haven't been able to get multipurpose modmaps to work very well on my own system. You may need to tweak the "multipurpose" timeout setting that's with the "suspend" timeout in the early part of the config file. By default they are both 1 second.

This is an example where I tried to create a Hyper modifier as an alias to F19 (an innocuous key that has no special purpose in most desktop environments), and then used the new Hyper modifier in a keymap. I really had problems with the multipurpose modmap, especially when attempting to combine Hyper with some other modifier. But I'll leave it as an example of what a multipurpose modmap looks like.

# Create a new Hyper modifier key alias on F19
Modifier("HYPER", aliases=["Hyper"], key=Key.F19)

# # Physical CapsLock is Escape (when tapped) and F19 (when held with other key like modifier)
# multipurpose_modmap("CapsLock is Esc and F19", {
#     Key.CAPSLOCK: [Key.ESC, Key.F19],
# }, when = lambda ctx:
#     matchProps(not_clas=remoteStr)(ctx)
# )

# Physical CapsLock is F19
modmap("CapsLock is F19", {
    Key.CAPSLOCK: Key.F19,
}, when = lambda ctx:
    matchProps(not_clas=remoteStr)(ctx)
)

keymap("Testing Hyper modifier", {
    C("Hyper-Space"):           [ST("You pressed Hyper+Space"), C("Enter"), C("Enter")],
    C("Hyper-Shift-Space"):     [ST("You pressed Hyper+Shift+Space"), C("Enter"), C("Enter")],
}, when = lambda ctx:
    cnfg.screen_has_focus and
    matchProps(not_clas=remoteStr)(ctx)
)

I've bunched these together just because it's one related group of code, and you could probably put them all in the user_apps slice just for convenience, if you want to try messing with it.

RedBearAK commented 1 week ago

Or maybe, what you're looking for is this, which would mean all you'd have to do is make the Caps Lock key into a Super key when not in terminals. Is it emacs style shortcuts you're talking about? (This is from the General keymap.)

    # emacs style
    C("Super-a"):               C("Home"),                      # Beginning of Line
    C("Super-e"):               C("End"),                       # End of Line
    C("Super-b"):               C("Left"),
    C("Super-f"):               C("Right"),
    C("Super-n"):               C("Down"),
    C("Super-p"):               C("Up"),
    C("Super-k"):              [C("Shift-End"), C("Backspace")],
    C("Super-d"):               C("Delete"),

If you want them to be able to repeat, you'll need to put this in your keymapper_api slice:

ignore_repeating_keys(False)
Rookiecom commented 1 week ago

Or maybe, what you're looking for is this, which would mean all you'd have to do is make the Caps Lock key into a Super key when not in terminals. Is it emacs style shortcuts you're talking about?

    # emacs style
    C("Super-a"):               C("Home"),                      # Beginning of Line
    C("Super-e"):               C("End"),                       # End of Line
    C("Super-b"):               C("Left"),
    C("Super-f"):               C("Right"),
    C("Super-n"):               C("Down"),
    C("Super-p"):               C("Up"),
    C("Super-k"):              [C("Shift-End"), C("Backspace")],
    C("Super-d"):               C("Delete"),

If you want them to be able to repeat, you'll need to put this in your keymapper_api slice:

ignore_repeating_keys(False)

yeah, this is what I need. So I have set like this.

modmap("CapsLock is Right Ctrl in GenGUI", {
    Key.CAPSLOCK:               Key.Super,                 # Modmap Caps Lock to be a Cmd key
}, when = lambda ctx:
    cnfg.screen_has_focus and
    matchProps(not_clas=terms_and_remotes_Str)(ctx) )

modmap("CapsLock is Left Ctrl in GenTerms", {
    Key.CAPSLOCK:               Key.LEFT_CTRL,                  # Modmap Caps Lock to be a Ctrl key (not Cmd)
}, when = lambda ctx:
    cnfg.screen_has_focus and
    matchProps(clas=termStr)(ctx) )

and add ignore_repeating_keys(False), but it doesn't work.

RedBearAK commented 1 week ago

This doesn't exist:

Key.Super

What you need there is Key.LEFT_META. The keymapper's key definition file uses names from the Linux kernel input system, and it calls the Meta/Super/Win/Cmd key code META, like KDE Plasma.

Fix that and it should work. You could also try Key.RIGHT_META. Either should work.

RedBearAK commented 1 week ago

Though you still have to use Super for that modifier if you make yourself any custom remaps in a keymap. The Meta alias for use in shortcuts (not modmaps) was removed because it used to be used for Alt (historical anomaly in Linux), and that was a source of confusion.

Rookiecom commented 1 week ago

Oh, nice. It works!

Thank you!

May your project develop better and better!!!!

RedBearAK commented 1 week ago

It works!

Excellent.

May your project develop better and better!!!!

I do my best. Thanks.