spyoungtech / ahk

Python wrapper for AutoHotkey with full type support. Harness the automation power of AutoHotkey with the beauty of Python.
MIT License
887 stars 66 forks source link

[help wanted] Opposite method of block_forever()? #243

Closed YI8it closed 10 months ago

YI8it commented 1 year ago

Hi! I just found this wrapper and hope to have much fun with it. Good initiative! =) I can't seem to figure out one thing though: what method has the opposite effect to "block_forever()"? That is, how can I stop "block_forever()" and let the script exit? I couldn't find anything in the documentation.

Here's what I was hoping to do:

from ahk import AHK

def my_callback():
    print('Hello callback!')

def terminate_script():
    ahk.stop_hotkeys()
    ahk.exit_app()  # <- Some method that kills block_forever()

ahk = AHK()
ahk.add_hotkey('#n', callback=my_callback)
ahk.add_hotkey('#j', callback=terminate_script)
ahk.start_hotkeys()
ahk.block_forever()`

I tried without "block_forever()" and with my own sleep function:

from ahk import AHK
import time

def my_callback():
    print('Hello callback!')

def terminate_script():
    global snooze
    snooze = False
    ahk.stop_hotkeys()

snooze = True
ahk = AHK()
ahk.add_hotkey('#n', callback=my_callback)
ahk.add_hotkey('#j', callback=terminate_script)
ahk.start_hotkeys()  # start the hotkey process thread
while snooze:
    time.sleep(2)`

This code needs more CPU-cycles than your "block_forever()", though.

spyoungtech commented 1 year ago

There's no builtin or intended way to stop block_forever -- but you could use ctrl+c to trigger a keyboard interrupt, which will break the loop.

try:
    ahk.block_forever()
except KeyboardInterrupt:
    pass
print('done blocking')

Beyond this, something like you've implemented would also work, but there's no builtin functionality for this. There is a plan to implement something like exit_app, but it won't stop block_forever.

As a possible alternative to what you've implemented, you could use key_wait to block until a specific key is pressed.

YI8it commented 1 year ago

No wonder I couldn't find it then =) Could I just change the definition from async def block_forever(self) -> NoReturn: to async def block_forever(self, run=True) -> NoReturn: and then pass 'False' when I want to terminate it?

spyoungtech commented 10 months ago

Hmm. I'm not sure that makes much sense in the context of asyncio, or maybe I'm not fully understanding the meaning. In any case, the block_forever methods are mostly there as a very simple convenience. I don't think we plan to add any functionality for interrupting the 'block forever' state.

But if you come up with a novel idea that may be useful to other users, feel free to share it in discussions or open a pull request :)