jtroo / kanata

Improve keyboard comfort and usability with advanced customization
GNU Lesser General Public License v3.0
2.17k stars 112 forks source link

Feature request: repeat a macro while held #361

Closed rszyma closed 1 year ago

rszyma commented 1 year ago

Hi, I'm wondering if it's possible to define a infinitely repeating macro in Kanata. Specifically I wanted to create an action, where as long specified button is pressed it repeatedly left clicks mouse. I've read through docs and I didn't see a way to achieve this, so I tried some workarounds:

(defalias
  r1 (macro-release-cancel mlft 100 @r1)
)
(defalias
  r1 (macro-release-cancel mlft 100 @r2)
  r2 (macro-release-cancel mlft 100 @r1)
)

Running a config with any of the above declarations results in a panic:

thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', src/cfg/mod.rs:1316:37
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
zsh: IOT instruction (core dumped)  kanata -c=akko3068b.kanata.kbd
jtroo commented 1 year ago

Ah interesting. Regarding the crash, you tried to do recursion in the configuration file, which as you've found, crashes the program ๐Ÿ˜…. Kanata intentionally does not try to have a Turing complete configuration language, though at some point that may have accidentally been violated. In any case, this recursion is intended to break. The way I would try to fix this would be to catch and deny the recursion gracefully instead of crashing. The crash might stick around for a while though, depending on how hard it is to fix.

The exact use case you describe sounds like a job for AHK or xdotool. But it may also be possible for Kanata to have some "repeat while held" action that can be used with the special actions that don't support auto-repeat today, such as mouse buttons or the rpt action. Though from a Rust implementation standpoint, I would guess this will not play well with lifetimes, so I don't think this would be trivial to do.

Edit:

A repeat-while-held macro action may not actually be as bad as I had originally thought. Notably macro specifically, rather than any type of custom action.

rszyma commented 1 year ago

Bugs introduced by #366:

A bug with both macro-repeat-release-cancel and macro-repeat

Timeout is not working at all if it's used as the last value in the list of actions e.g.,

(defalias
    r2 (macro-repeat a 1000)
    r1 (macro-repeat-release-cancel a 1000)
)

A bug with macro-repeat-release-cancel

(May be related to the above bug)

When a button with the following action mapped:

(defalias
    r1 (macro-repeat-release-cancel a b c 1000)
)

is pressed and released, after a second or so, it sometimes repeats one of characters a b or c, until any key is pressed.

A panic or an unhelpful error message when a timeout in macro is too large.

TBH this bug is not strictly related to the macro-repeat feature (because it also applies to normal macro too) and it's not critical, but I'm going to mention it anyway:

A panic or a message Action macro only accepts delays, keys, chords, and chorded sub-macro will appear during config parsing when timeout in macro is too large. Whether a panic or the message is generated depends on position of the timeout in the list of actions is. For example, following declaration will cause panic (because it's at the end of the list):

(defalias
    r1 (macro-repeat-release-cancel a b c 10000)
)
thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', src/cfg/mod.rs:1335:37
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

while this won't panic (notice that the large number is in the middle):

(defalias
    r1 (macro-repeat-release-cancel 10000000 a b c 1000)
)
  ร— Error in configuration file
    โ•ญโ”€[akko3068b.kanata.kbd:67:1]
 67 โ”‚ (defalias  
 68 โ”‚   r1 (macro-repeat-release-cancel 10000000 a b c 1000) 
    ยท )                                          โ”ฌ
    ยท                                            โ•ฐโ”€โ”€ Error here
 69 โ”‚ 
    โ•ฐโ”€โ”€โ”€โ”€
  help: Action macro only accepts delays, keys, chords, and chorded sub-macros
jtroo commented 1 year ago

I wasn't able to reproduce this one, at least not using the address bar text box of Firefox.

When a button with the following action mapped:

(defalias
    r1 (macro-repeat-release-cancel a b c 1000)
)

is pressed and released, after a second or so, it sometimes repeats one of characters a b or c, until any key is pressed.

Maybe it's related to the application being tested in where it was failing to properly handle the too-rapid key events? The other two bugs are fixed in the new PR, and it may have fixed the one I can't reproduce by making the delay work and decreasing keypress rapidity.