reidprichard / window_tools

Some simple tools to add lots of functionality to Kanata (and potentially other hotkey tools). This project is on hold for now, but after some life changes are complete I will pick this back up (est. June 2024).
GNU General Public License v3.0
12 stars 0 forks source link

Feature: switch "active" layer rather than "base" layer / send fake keys on application switch #4

Open reidprichard opened 7 months ago

reidprichard commented 7 months ago

Without getting too much into the specifics of Kanata, layer-switch activates the base layer while layer-while-held/layer-toggle activates the "active" layer. The "active" layer overrides the "base" layer, but _ in the active layer falls through to the corresponding key of the base layer; _ in the base layer falls through to the corresponding key in defsrc.

Kanata's developer does not plan to expose layer-while-held directly via TCP, but he plans to expose press/release/tap/toggle actions for fake keys.

As a workaround, I think I can add an option so that kanata_helper_daemon follows this sequence:

  1. kanata_helper_daemon is started
  2. A new application (e.g. Windows Terminal) is activated.
  3. kanata_helper_daemon presses the WindowsTerminal fake key, which is mapped in kanata.kbd to (layer-while-held WindowsTerminal). This activated the WindowsTerminal layer as the "active" layer while keeping the default layer as the "base" layer.
  4. A new application (e.g. Firefox) is activated.
  5. kanata_helper_daemon releases the WindowsTerminal fake key and presses the Firefox fake key. As in 3, this must be mapped to (layer-while-held firefox).

I imagine there will be some implementation challenges with e.g. handling errors if a layer doesn't have a corresponding fake key, keeping track of state so fake keys are released at the proper time, etc. To get the most out of this feature, it may be necessary to get Kanata to send a list of all fake keys.

As a plus, additional commands could be run when application focus changed, such as requested in #3. I foresee this being a really powerful feature. For example, you could have each fake key mapped something like: (multi (layer-while-held layer-name) (cmd pwsh "'application-name: ' + (date +%s) >> application_timestamps.txt" if you wanted to keep track of how much time you're spending each day in each app. You could run a command to automatically mute your mic when you defocus Teams. You could run a command to enable audio compression with EqualizerAPO when you activate Teams. With this feature, kanata_helper_daemon won't be restricted to just per-application layer changes - you can do whatever you want when the application changes!

bogorad commented 7 months ago

So there will be some predictable naming convention for process names/fake-keys? Works for me :)

reidprichard commented 7 months ago

Yes, I'm thinking I'll have a command line argument to choose between the following behaviors:

  1. As before, activate the layer whose name matches the focused application (default). Layer names will be retrieved via TCP.
  2. Instead, hold down the fake key whose name matches the focused application. Depending on how gracefully Kanata handles being asked to press a fake key that doesn't exist, user may need to provide a list of fake key names.

If there's interest I could add a functionality, e.g.:

I think I've reverse-engineered Kanata enough to figure out how to press fake keys over TCP, so once I have time I should be able to get this moving.