Blocking incorrect keystrokes

I have a microswitch feeding into an iKeys usb interface that triggers a script via the F1 key. When I push the button multiple times very fast to test it’s reliability it triggers incorrect keystrokes and all sorts of things happen within the application that I don’t want to happen. I’m guessing the speed of the button trigger is causing some issues but I’m wondering if there is a way to block certain keystrokes from getting triggered?

Example:

tell application "Sound Studio"
	activate
end tell

tell application "System Events"
	tell process "Sound Studio"
		keystroke "n" using {command down} --command n opens a new file
		keystroke "R" using {command down} --shift command R opens a preference window
		delay 1
		keystroke "4" --types in the #4 which sets a saved preset in a pop scroll menu
		delay 1
		keystroke tab & return --tabs out of the preset window and presses return
		keystroke "r" using {command down}
	end tell
end tell

So when I push this once it works fine. If I push it very fast I usually get a Mix Paste menu that can be activated by Shift Command V. How could I block Shift Command V from getting activated? thx

Why don’t you just limit the script to run only once every 1, 2 or 3 seconds?

I should have explained the setting this is used in. Children have access to this button. I have it set up so they can record themselves but if they push it too fast too many times in a row, which happens fairly often, the application brings up a few other menus.

Add a step that writes the date the script is run to a file. Each time the script runs this date is read in and made sure that at least 2 seconds passed since the last run before further execution is allowed.


set _lastrun to dateOfLastRun()
if _lastrun is false then
   -- No date has been stored yet, allow execution
   set _allowExecution to true
else if ((current date) - _lastrun) ≥ 2 then
   -- Allow execution, if at least 2 seconds passed since the last run
   set _allowExecution to true
else
  -- Do no allow execution in any other case
  set _allowExecution to false
end if

It probably would work if you put a delay before and after every keystroke line. Right now you have no delay between the last keystroke line of the script and the first keystroke line… so there’s no delay when the script is run fast a second time.

Also, you probably could change all the delays to be 0.5 seconds (or maybe even 0.25). That way you can add more delays and the script wouldn’t take any longer than it does now.

Also separate these into two lines:
keystroke tab
keystroke return

Obviously the keystrokes are happening too fast so you need a delay between every keystroke to make sure they don’t occur too fast.

Whatever application triggers the script, it seems that it does so by running it every time as an independent process or thread. That’s why including delays will not work, as multiple instances of the same code will still execute at the same time, only delayed.

So to fix this problem, you will have to make sure that this piece of code does not execute more than once at the same time.

That makes sense, good point. If this is the case then certainly delays won’t have the desired effect. The following script will check with system events. If your script is currently running then new instances won’t execute their code. I haven’t tested it but it seems like it should work.

-- get this script's name and the name of the running processes
set myName to getMyName()
tell application "System Events"
	tell processes to set nameList to name
end tell

-- only run the script code if the process is not running
if myName is not in nameList then
	-- execute your code here
end if

(*============== SUBROUTINES =============*)
on getMyName()
	set myPath to path to me as text
	if myPath ends with ":" then
		set n to -2
	else
		set n to -1
	end if
	set AppleScript's text item delimiters to ":"
	set myName to text item n of myPath
	if (myName contains ".") then
		set AppleScript's text item delimiters to "."
		set myName to text 1 thru text item -2 of myName
	end if
	set AppleScript's text item delimiters to ""
	return myName
end getMyName

At this point it would be interesting to know what software is being used to trigger the AppleScript. Also, does the software run a script document or launch a script application?

Hello,

I am back. Thanks for all the ideas. To answer your last post, I am running a script document using a program called iKeys. It comes bundled with the xKeys usb interface seen here:

http://www.xkeys.com/xkeys/xkswi.php

cc

Your problem might be solved by simply using an applet instead of the document. This way the same code can run only once at a time, because no matter how often iKeys tries to launch the application, it will only succeed to do so when the application isn’t running.

Ah. Good thinking. I’ll give it a try and let you know how it goes. Thanks

c

Success!!!

I will continue to monitor it all week but after multiple clicks, I have had no problems. Adrian, thanks for this simple and effective solution.

c

I’m back. With bad news. It seems the problem of unwanted menus continues. I feel I need a more robust, streamlined script or I need to go with something like MSP/Max/Jitter. Any more thoughts on this would be appreciated.

C

I gave you code in post #7 above which should prevent the problem… did you try that? I would try both that code and also add the delays like I explained in post #5. Doing those 2 things should definitely prevent multiple instances of your code from running simultaneously.

Hey thanks for reminding me about those previous post suggestions. I tried out your code but it would not do anything beyond activating Sound Studio. It seemed to just sit there as if the begin recording command was never allowed to perform. Thoughts?

cc