RedBearAK / toshy

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

(Question) Possible to automate native shortcut changes in KDE Plasma? #401

Open irfanhakim-as opened 2 months ago

irfanhakim-as commented 2 months ago

First of all, I'm almost certain this original title is not the best to describe my question - please feel free to update it.

I have been using the user_apps slice to add in my own keybindings, that are essentially mapping to existing keybindings within KDE Plasma. An example:

if DESKTOP_ENV == 'kde':
    keymap("User overrides: KDE Task Switcher", {
        C("RC-Grave"):              C("Alt-Shift-Tab"),             # Switch apps in reverse order
    }, when = lambda ctx:
        cnfg.screen_has_focus and
        matchProps(not_clas=remoteStr)(ctx)
    )

This maps Cmd + ` to Alt + Shift + Tab, an existing keybind on KDE that switches through apps in the task switcher in reverse (like on macOS).

There are many possible shortcuts however on KDE Plasma that I'm interested in, particularly window-management related ones (KWin), that do not have an existing keybinding for it that I could easily map to with Toshy.

Is it possible for me to use Toshy to create a new keybind for them instead of doing so via KDE Plasma's settings, for the benefit of maintaining a single Toshy config + ability to easily disable/enable it via service?

For this particular discussion, the short example of what I'm trying to achieve is to create a keybind for KWin's shortcut that is without a default shortcut, Move Window to the Center, to Cmd + Alt + C (or RC-Alt-C).

Full context of what I am trying to achieve I'm essentially trying to replicate the default keybindings of Spectacle (or its new "replacement", Rectangle), a popular window management tool I use daily on macOS. I did this easily on KDE Plasma before simply by editing the shortcuts in System Settings, but now wish to do it using Toshy for a "cleaner" solution. ```py keymap("User overrides: KDE Spectacle Window Management", { C("RC-Alt-Down"): C("Super-Down"), # Quick tile window to the bottom (kde) # C("RC-Ctrl-Shift-Left"): C(""), # Quick tile window to the bottom left (kde) # C("RC-Ctrl-Shift-Right"): C(""), # Quick tile window to the bottom right (kde) C("RC-Alt-Left"): C("Super-Left"), # Quick tile window to the left (kde) C("RC-Alt-Right"): C("Super-Right"), # Quick tile window to the right (kde) C("RC-Alt-Up"): C("Super-Up"), # Quick tile window to the top (kde) # C("RC-Ctrl-Left"): C(""), # Quick tile window to the top left (kde) # C("RC-Ctrl-Right"): C(""), # Quick tile window to the top right (kde) # C("RC-Alt-C"): C(""), # Move window to the center (kde) C("RC-Alt-F"): C("Super-Page_Up"), # Maximize window (kde) }, when = lambda ctx: cnfg.screen_has_focus and matchProps(not_clas=remoteStr)(ctx) ) ``` Actions without default shortcuts of their own are commented in this example.

Thank you!

RedBearAK commented 2 months ago

@irfanhakim-as

Is it possible for me to use Toshy to create a new keybind for them instead of doing so via KDE Plasma's settings, for the benefit of maintaining a single Toshy config + ability to easily disable/enable it via service?

As far as I know, not exactly. At least not the "easily disable/enable it via service" part.

What is possible is putting new shortcuts into place, but I have run into issues actually enabling the shortcuts reliably without either logging out and back in, or tweaking a shortcut in the Settings app and hitting the "Apply" button to let the system (Plasma, or KWin) refresh the state of the global shortcuts.

There are a couple of ways you're supposed to be able to manipulate the shortcuts assigned to existing actions in KDE. One is the kwriteconfig6 command, changing settings in kglobalshortcutsrc. The other is a D-Bus interface that can be used with a utility like gdbus. In both cases the the command syntax is fairly complex, but it is certainly scriptable to change shortcuts or add shortcuts to an action that has no default enabled. Though there are some significant differences between how this works in Plasma 5 versus Plasma 6.

What probably isn't going to be very practical is trying to get those shortcut changes to become active and deactivate along with the Toshy services or manual running of the Toshy config. You'll want to just put the native shortcut changes in place and leave them alone, and then have your remaps in your Toshy config, just like you've shown.

You will find some scripts in ~/.config/toshy/scripts/ that you way want to look at:

kglobalaccel-dbus.sh             # simplifies working with KGlobalAccel methods via gdbus
plasma_shortcuts_converter.py    # converts between shortcut strings and integers
plasma-task-switcher-fixer.sh    # has examples of using kwriteconfig5/6 to set shortcuts

That last one also has examples of using the gdbus command, but most or all of that is disabled because I ran into so many problems with attempting to use the D-Bus methods to script shortcut changes. That first script significantly simplifies trying to do the D-Bus method calls to the KGlobalAccel interface, so that can be used to experiment with the D-Bus calls. And apps like D-Spy can be used to explore all the D-Bus interfaces available on the system. I barely understand any of that, so I can't really explain further.

There's also a way to export a set of shortcuts from the Shortcuts settings panel, so you could set them up manually like you did before and then export just those shortcuts to a file, and you should be able to import them in another install of Plasma (but it may need to be the same version of Plasma, because things changed between 5 and 6). Not sure if there is a way to script that.

I am fairly certain some of the issues I ran into with the D-Bus calls are actually caused by some kind of bug, or lack of implementation of the proper way to "refresh" the system's understanding of the active global shortcuts. The usual "reconfigure" command for KWin doesn't seem to work with keyboard shortcut changes. Only the "Apply" button in the settings app seems to properly refresh the state of the active global shortcuts.

Wish I could be more helpful.

RedBearAK commented 2 months ago

This maps Cmd + ` to Alt + Shift + Tab, an existing keybind on KDE that switches through apps in the task switcher in reverse (like on macOS).

It's unfortunate that it's basically impossible to replicate how this really works on macOS, simply because it's very difficult to detect when the task switcher in various desktop environments is active.

I used macOS for two decades without realizing that if you do Cmd+Tab and then Cmd+Grave, it would move backwards in the task switcher. I had always relied on Shift+Cmd+Tab for that when needed, and used Cmd+Grave solely for in-app window switching. Sadly remapping Cmd+Grave to do the reverse app switching will block it from being able to do the in-app window switching. (But technically Shift+Cmd+Grave will still be available, for reverse in-app window switching.)

Anyway, that's why the shortcut doesn't/can't do the reverse app switching by default. Pretty sure it used to work that way in Kinto's default config, because the Kinto dev had always used the shortcut for that purpose. But I convinced him to let it do the in-app window switching by default.

Now that I think about it, it might be possible to kind of mimic the way that shortcut only becomes "reverse app switching" after an initial Cmd+Tab by using a custom function similar to the Finder Mods "Enter to Rename" mimicry function. I'll have to think about whether that could be reliable enough to be useful to anyone. 🤔