-
hi, is it possible to make script like this?
|
Beta Was this translation helpful? Give feedback.
Replies: 10 comments 4 replies
-
Welcome to AutoKey. Sort of... TL;DR: Most of this is uncharted territory and would require significant experimentation. Let's break this down. (Thinking out loud ...) To get it out if the way first, read this and don't use There are no API calls, etc. that do exactly what you want, so you have to try to work around it. I don't want to just say, "no", because our scripts are coded in native Python, so if you're skilled enough, you can do almost anything. You could write a script that uses an AutoKey stored variables to count how many times it has been called and how long ago the last call was. This would allow you to detect multiple taps of a hotkey and differentiate between two taps that were pressed close together in time. That solves one problem, but creates another one - acting on a single tap is now hard. You could have your script trigger on the first hotkey keypress, and then call wait for keypress after checking the time. When it returns (there's no return code), you could check the time again. If the elapsed time is shorter than how long you told it to wait for the same keypress, then you got one. If the elapsed time is also short enough for your definition of a double tap, then you'd have a double tap. But this won't easily work directly because the second tap of the same hotkey will launch a new instance of your script and that makes things rather convoluted. I don't know what the first script instance would see. I don't immediately see any way to directly detect press and hold, but if your keyboard is setup for autorepeat when a key is held down long enough (it's a common setting), you would actually have multiple keypresses occurring at a rapid rate (determined by the keyboard key repeat parameters). You could detect this as above, but you could end up with a lot of instances of your script running simultaneously which might get AutoKey upset. It's multi-threaded, so it can do that, but I don't have a lot of confidence in it if you stress it. We don't have much experience with multi-threaded use cases, so there may be bugs. To avoid some of this, you might have to use one hotkey to enter "multipress detection" mode and have your script look for multiple presses of another key that is not a hotkey. All of these approaches come with housekeeping overhead of setting up initial conditions and then resetting them once the event has been successfully or unsuccessfully completed. You would probably get more feedback/support for a question like this on Gitter where our developer(s) and advanced users hang out. |
Beta Was this translation helpful? Give feedback.
-
AutoKey is part of the way to getting you there, but not quite: The AutoKey API offers the keyboard.wait_for_keypress function, but it doesn't provide a return code, so you can't currently test for its event in a conditional statement. There's an open enhancement issue for it here. Also, the AutoKey API doesn't currently offer a keyboard.wait_for_keyrelease function, which could also be useful as part of responding to key-presses. There's an open enhancement issue for that here. Last, but not least, Joe made an excellent point that pressing the trigger key would retrigger the script, so you'd probably want to use a different key as the trigger for a script that listens for specific key-presses with some Python or Bash code. |
Beta Was this translation helpful? Give feedback.
-
I did find script for autohotkey, so I hoped something like that could work for Autokey unfortunately I am not coder, I can only handle simple bash script, so I was thinking, when you create script you click |
Beta Was this translation helpful? Give feedback.
-
I will give it a try thx for your answers |
Beta Was this translation helpful? Give feedback.
-
I gave it a serious try the other night for a couple of hours and had high hopes for the conditional statements I was throwing around, but I ended up getting nowhere fast. It could be done with external libraries that don't ship with Python by default and have to be installed (like pygame or pynput, etc., with some examples of that here), but I haven't yet figured out a way to do it without adding any libraries, which would be ideal. |
Beta Was this translation helpful? Give feedback.
-
@Elliria I didn't try converting my pseudocode into Python (yet). Did you try something like what I suggested? What can't you do without additional capabilities (modules)? I didn't seem to need any, but since I don't have working code, I don't know if I missed anything. |
Beta Was this translation helpful? Give feedback.
-
It's a mess. Do not try this at home. I tried several variants of something like this nested if statement, which didn't even venture to deal with long-presses and only attempted to differentiate between single-presses and double-presses: retCode = keyboard.wait_for_keypress("a",timeOut=1)
if retCode:
if retCode:
keyboard.send_keys("double-tapped")
else:
keyboard.send_keys("single-tapped") Then, I tried several variants of this nested if statement, with the idea being that if you press the "a" key once, you get an a, if you press it twice, you get aa, and if you hold it down, you get aaaaaaaaaaaa and so on, so if you can test for three or more presses, two presses, or one press of the "a" key, that should do it. It fell over because the nesting didn't count them properly: retCode = keyboard.wait_for_keypress("a",timeOut=1)
if retCode:
if retCode:
if retCode:
keyboard.send_keys("long-pressed")
engine.run_script("foo")
elif retCode:
if retCode:
keyboard.send_keys("double-tapped")
engine.run_script("foo")
elif retCode:
keyboard.send_keys("single-tapped")
engine.run_script("foo")
else:
pass It gave me output, but it didn't accurately catch all the presses of the "a" key, so this it's some seriously bad code. In one of my experiments, I tried to get each of the conditions to update a counter variable that starts out at zero (with Despite that (and figuring that I'd fix that mess later), I tried combining the counter with using I also tried putting several variants of the above scripts into a function and having it call itself from within the conditions so that it would reset (and avoid the problem of not being able to get the script to reset itself) and I managed to make that fail as well. Eventually, I suspected that going to bed would offer me a greater chance of success, so I gave that a try and it worked perfectly. I didn't try your pseudo-code, but that's probably because by the time I looked at it, my brains were spaghetti from all that miserable messing around and I took one look at it and ran away screaming. I'll have to take another look at it, but I suspect it will look just fine other than the pesky problem of recognizing each press of the "a" key. Last, but not least, for the heck of it, I tried several variants of this just now, also with no success, although I love how it looks and when I'm making code fall over hard, I have to get my satisfaction from somewhere: retCode = keyboard.wait_for_keypress("a",timeOut=1)
def foobarbazbat():
if retCode:
if retCode:
if retCode:
keyboard.send_keys("long-pressed")
return
keyboard.send_keys("double-tapped")
return
keyboard.send_keys("single-tapped")
return
foobarbazbat() |
Beta Was this translation helpful? Give feedback.
-
Unpacking this a bit. Looking at the API call, I don't see anything about it returning a return code at all. That was the initial problem referenced in another enhancement issue #659. Other API calls have a "Returns" item specified, but this one does not. Note that my pseudocode did not rely on a return code, but deduced what had occurred by comparing timestamps. The way I did it, the initial instance would keep running until it either got what it wanted or too much time had elapsed. Subsequent invocations (from user pressed hotkey) would just increment the presses counter and exit to keep from draining resources. I see no need for the script to be recursive because it is retriggered externally and just need to know if the current instance is the first one or not. The Python if statement does not modify the value that it tests, so nesting identical if statements is pure overhead. This might not be the case if the expression tested by the if command had side effects such as modifying variables or other program state factors. Intentionally using side effects like this can be quite convenient, but makes reading and debugging code a lot more difficult. |
Beta Was this translation helpful? Give feedback.
-
It doesn't offer a return code, which is why someone had originally contributed a sample script using the retCode variable with a Boolean value to verify whether the wait for a key-press had fired or not. The recursion in my attempts was used to listen for successive key-presses, but yeah, it's definitely overhead and isn't fully working. In my tests, I wasn't able to update a counter variable reliably inside of the if statements because of concatenation issues that had caused the script to get all confused instead of reporting the number of key-presses. I'll mess with your pseudo-code at some point. If I parse my |
Beta Was this translation helpful? Give feedback.
-
You're over thinking it. Your script has to save the time it was last called in a local saved variable and compare it with the time it was called now. To do that, it has to know if this is the first time it was called which it can do by looking at the value of the presses (counter) local stored variable which will start out undefined or 1 (one), depending on how you code it. There should be no need to reference logs or anything else outside of your script. |
Beta Was this translation helpful? Give feedback.
I will give it a try
thx for your answers