WAD DO ... (KEYSTACK /w ...)

#1
When I do
Code:
do i=1 to 5 ( keystack /w18 "a" )
all 5 a's appear at once after a single 1-second delay.

I don't mind that they appear at once (that's expected) but it would seem that each one should get its own 1-second delay and that I should see all 5, at once, after 5 seconds?
 
May 20, 2008
450
2
#2
Here is another example with interesting behavior:

do i=1 to 5 (keystack /w%@eval[i * 18] "a")
This waited five seconds and output all at once.

This appears to contradict what is said in the help: "Each time the KEYSTACK command is executed, it will clear any remaining keystrokes stored by a previous KEYSTACK command."
 
Dec 2, 2008
212
2
Canada
#4
My guess is that keystack places the values onto the keyboard buffer and then sends a request to windows that there is a keyboard entry but by the time windows gets to keyboard request message on the message queue, the keyboard buffer has already been changed by the next keystack command
 
#5
My guess is that keystack places the values onto the keyboard buffer and then sends a request to windows that there is a keyboard entry but by the time windows gets to keyboard request message on the message queue, the keyboard buffer has already been changed by the next keystack command
I figure each KEYSTACK starts a thread. In the first example, 5 threads are started nearly simultaneously so their output appears nearly simultaneously after each has waited 1 second. In the last example, I figure windows is switching between 5 threads before each has output "ab". I figure Rex will say it's going to stay that way (sigh!). But it seems that KEYSTACK would benefit from a /S(ynchronous) option.
 

rconn

Administrator
Staff member
May 14, 2008
10,533
94
#6
When I do
Code:
do i=1 to 5 ( keystack /w18 "a" )
all 5 a's appear at once after a single 1-second delay.

I don't mind that they appear at once (that's expected) but it would seem that each one should get its own 1-second delay and that I should see all 5, at once, after 5 seconds?
WAD -- you're not doing what you think you're doing.

First, KEYSTACK is mostly useless in the current TCC session; it's intended for feeding keystrokes to *other* applications. You'll see all kinds of odd behavior in the current session that you won't see when sending to another session, because you won't return to the command line (and TCC won't start reading the characters you've piled up in the keyboard buffer) until your DO loop exits.

What you're actually doing here is creating 5 threads, each of which waits for one second and then sends an "a". (Why aren't you just doing this in a single KEYSTACK call instead of trying to loop?)
 

rconn

Administrator
Staff member
May 14, 2008
10,533
94
#7
Here is another example with interesting behavior:

do i=1 to 5 (keystack /w%@eval[i * 18] "a")
This waited five seconds and output all at once.

This appears to contradict what is said in the help: "Each time the KEYSTACK command is executed, it will clear any remaining keystrokes stored by a previous KEYSTACK command."
WAD. Subsequent KEYSTACKs do not reach into the system keyboard buffer and pull out characters inserted by previous KEYSTACKs.

Back in the 4DOS days this was true, because (1) there wasn't any threading in KEYSTACK, and (2) the inserted characters were in a buffer maintained by 4DOS and fed one at a time into the system. But it hasn't worked that way for at least 10 years.
 
#8
My original intention was to feed keystrokes to FireFox and Iexplore, like this

Code:
browser & do i=1 to 50 ( keystack /w2 "x")
to see how many actually wound up in the Google search box. I managed it by other means. Iexplore is ready to accept keystrokes about a second faster than FireFox.

KEYSTACK would benefit from a /S(ynchronous) option. Wouldn't that be easy? ... just wait for the thread before returning.
 
May 20, 2008
450
2
#10
WAD. Subsequent KEYSTACKs do not reach into the system keyboard buffer and pull out characters inserted by previous KEYSTACKs.
I had also added a timer around that command. It completed and had returned to the command prompt in 0.0 seconds. The first wait was one second, the last five seconds. So, it was back at the prompt waiting before the first keystack wait had expired. Thus, the last keystack command had executed before the wait of the prior four had completed. Are you saying that the wait happens 'after' the characters are in the keyboard buffer and not before?
 

rconn

Administrator
Staff member
May 14, 2008
10,533
94
#12
I had also added a timer around that command. It completed and had returned to the command prompt in 0.0 seconds. The first wait was one second, the last five seconds. So, it was back at the prompt waiting before the first keystack wait had expired. Thus, the last keystack command had executed before the wait of the prior four had completed. Are you saying that the wait happens 'after' the characters are in the keyboard buffer and not before?
No, I'm saying that the thread that is created by KEYSTACK is the one doing the waiting, not the main TCC I/O thread.
 

rconn

Administrator
Staff member
May 14, 2008
10,533
94
#13
My original intention was to feed keystrokes to FireFox and Iexplore, like this

Code:
browser & do i=1 to 50 ( keystack /w2 "x")
to see how many actually wound up in the Google search box. I managed it by other means. Iexplore is ready to accept keystrokes about a second faster than FireFox.

KEYSTACK would benefit from a /S(ynchronous) option. Wouldn't that be easy? ... just wait for the thread before returning.
The simple solution is to insert a DELAY in your loop instead of a /Wx.

Adding a /S option to KEYSTACK is possible (though not easy). Go ahead and add it in the Feedback forum and we'll see if there's any interest.
 
#14
That also tells me that when the target of KEYSTACK is another window (process), and I have two strings to send, allowing the window to respond to the first string before sending the second, I have two choices to ensure events are done in the correct sequence:
1/ wait until a response to the first string is detected before sending the second one (the only reliable way), OR
2/ use a single KEYBOARD command, with a sufficient (excessive?) delay between the two strings.
The problem I am faced with is that in many of my uses of KEYSTACK often the only response to the first string is the location of the cursor in a the browser tab, which I have not figured out how to detect.
 
May 20, 2008
450
2
#15
No, I'm saying that the thread that is created by KEYSTACK is the one doing the waiting, not the main TCC I/O thread.
I was trying to reconcile the behavior with what the help had said: "Each time the KEYSTACK command is executed, it will clear any remaining keystrokes stored by a previous KEYSTACK command." Since the first wait had not yet expired when the last command was executed, shouldn't the characters from the prior keystack commands have been cleared?
 

rconn

Administrator
Staff member
May 14, 2008
10,533
94
#16
I was trying to reconcile the behavior with what the help had said: "Each time the KEYSTACK command is executed, it will clear any remaining keystrokes stored by a previous KEYSTACK command." Since the first wait had not yet expired when the last command was executed, shouldn't the characters from the prior keystack commands have been cleared?
See my previous response -- KEYSTACK hasn't behaved that way for 10+ years. By request from the users who are now complaining about it in this thread! :banghead:
 

rconn

Administrator
Staff member
May 14, 2008
10,533
94
#17
That also tells me that when the target of KEYSTACK is another window (process), and I have two strings to send, allowing the window to respond to the first string before sending the second, I have two choices to ensure events are done in the correct sequence:
I don't understand how this is related to this thread. That's always been an issue with sending keystrokes to another program; there isn't any reliable way (in Windows) to detect what another app is doing unless that app tells you about it.