sezanzeb / input-remapper

🎮 ⌨ An easy to use tool to change the behaviour of your input devices.
GNU General Public License v3.0
3.71k stars 152 forks source link

Home row mods fine tune #243

Open br-lemes opened 2 years ago

br-lemes commented 2 years ago

Hi! This is a great software and I'm able to do funny things with it. Currently I'm implementing home row mods and I have a suggestion I think it would make it better.

If I use: if_tap(k(f), h(Shift_L))

I have to hold some time before being able to use it as Shift. If I type quickly it will not work.

If I use: if_single(k(f), h(Shift_L))

It works nice, and I can type significantly faster.

But I want to use a triple function key, this way: if_tap(k(f), if_single(k(4), h(Shift_L)))

This way I can have 'k' on tap, '4' on hold an release without a combination and Shift on hold with a combination. It works, but it fells in the first case where I need to hold the key more time and it results in a slower typing and some some undesired characters some times.

It would be nice if we have a if_tap variation (if_singletap maybe) where a combination breaks the waiting time earlier, so I can type faster.

It could be: if_singletap(tap: Macro | None, single: Macro | None, else: Macro | None, timeout: int | None)

I'm reading the source to see if I can implement that myself, but I never worked with Python so it may not happen.

sezanzeb commented 2 years ago

It would be nice if we have a if_tap variation (if_singletap maybe) where a combination breaks the waiting time earlier

if_single supports a timeout argument, does that do what you need?

if_single(k(a), k(b), timeout=300)

is almost the same as

if_tap(k(a), k(b), timeout=300)

except that if you hit another key it will run k(b).

br-lemes commented 2 years ago

if_single supports a timeout argument, does that do what you need?

I thought I couldn't nest if_single but I was just using it wrong. I can now, but that doesn't change the result.

if_tap(k(f), if_single(k(4), h(Shift_L)))

is exactly the same as

if_single(k(f), if_single(k(4), h(Shift_L)), 300)

I still have to wait before hitting another key.

  1. :heavy_check_mark: tap: f
  2. :heavy_check_mark: hold and release: 4
  3. :heavy_multiplication_x: hold and hit another key quickly before timeout: 4g (g is the another key in this example)
  4. :heavy_check_mark: hold, wait timeout and hit another key: G (Shift + g, when g is the another key as before)

See that it already does what I need, but I'd like to eliminate or reduce this annoying time frame where the bad result appears [3].

If I reduce the timeout, I'll have to tap too quickly for the first case [1]. That's why I proposed this if tap[1]/single[2]/else[4] structure.

sezanzeb commented 2 years ago

I think I understand the issue

if_single(k(f), if_single(k(4), h(Shift_L)), 300)

  1. if_single-1 waits for a key
  2. within the timeout, g is pressed
  3. if_single-2 waits for a new key
  4. if_single-2 observes that g is released and that no other key was pressed
  5. if_single-2 runs k(4)

So the result is g4

Is the expected behavior of if single:

The latter seems to be the intuitive answer, but what if a combination triggers if_single?

image

In this case it should wait if another key is pressed in addition to he two that are already pressed.

sezanzeb commented 2 years ago

Similarly, in this example:

image

If 1 is pressed and then 2, the second call to if_single sees 1 and 2 as its trigger and waits for a third key

sezanzeb commented 2 years ago

Maybe the upcoming macro functions if_held and if_released could help, see https://github.com/sezanzeb/key-mapper/issues/198#issuecomment-958788175

Also, there was the idea of adding something like if_lt($_time, 300, ...) at some point, which might also help for those use cases

br-lemes commented 2 years ago

Thanks! I understood pretty well what's happening under the hoods. I'll stay tuned for the new upcoming macros.