I have a handy perl and applescript combo that creates events from highlighted text. It’s a little buggy, but I’m working on it. Today, I found an issue that I could reproduce reliably with some text I’d highlighted. I found that the input text I was entering using keystroke was going too slow and that if I increased the delay, it worked. However, I don’t like this solution, as I could imagine scenarios where even that 2 second delay might cause it to fail.
Keystroke goes ridiculously slow. I watch it enter the text and it appears to get hung up at different points. I suppose I could paste the text, but I’m avoiding mucking with the clipboard, which I’d prefer remain untouched by the script. Here’s the snippet of code where I do the keystroke (with my delay that fixed it):
on quickevent(inputText, locationVal, urlVal, notesVal)
tell application "Calendar" to activate
tell application "System Events"
keystroke "n" using {command down}
keystroke inputText
keystroke return
delay 2
key code 53
end tell
...
And here’s the text that reliably took more than 1 second to enter:
Is there some way to make keystroke go faster or is there a better method of putting the text in? Or - is there a way for me to loop and test whether keystroke is done so I can wait a variable amount of time depending on how long the input text is? OR: Perhaps there’s a way to enter all the keystrokes and key codes together so that they are guaranteed to happen sequentially?
The escape was needed in the old version of iCal so that the next step (getting the selected event) would work - otherwise there was a window in the way and the focus was wrong and getting the selected event wouldn’t work. It appears as though it may be unnecessary in this current version of iCal, but it’s not hurting anything, so I’ll leave it in there for backward compatibility.
If I understand your code correctly, you’re testing for the existence of the input text field before entering the “inputText”, is that correct? If that’s the case, then I don’t think this would solve my problem, which is the amount of time it takes to enter the text before performing the next step. The next step appears to be executing before the entry of the text is finished. I suppose I should have at least included the line following the code I pasted:
on quickevent(inputText, locationVal, urlVal, notesVal)
tell application "Calendar" to activate
tell application "System Events"
keystroke "n" using {command down}
keystroke inputText
keystroke return
delay 2
key code 53
end tell
set thisEvent to get_selected_event()
...
The call to get_selected_event returns an undefined value unless I add the extra second delay. I can reproduce the error by changing the delay to 1 second. Despite the delay, I can sit there and watch the text being entered, so I know that waiting for the entry field is not the problem. Text entry pauses in places, indirectly causing the error, because I think get_selected_event is being called before the event has finished being created (i.e. before the text has been fully entered).
But perhaps I can alter your code to test for the disappearance of the “pop over” to know when the event creation is complete? What do you think?
Try the script.
When I ran it, the field was filled quite instantly.
Setting the value is more efficient than keystroking the text.
I issued a return to validate the entry and it worked flawlessly.
If I issue the Escape, the entry is just cancelled so the previous work was just wasted time.
In the loop testing the availability of the text field, I am accustomed to put the short delay on entry but you may move it between end if and end repeat. If your machine is fast enough, it will never be applied.
With :
repeat
if exists first pop over then exit repeat
delay 0.1
end repeat
Try the script.
When I ran it, the field was filled quite instantly.
Setting the value is more efficient than keystroking the text.
I issued a return to validate the entry and it worked flawlessly.
If I issue the Escape, the entry is just cancelled so the previous work was just wasted time.
In the loop testing the availability of the text field, I am accustomed to put the short delay on entry but you may move it between end if and end repeat. If your machine is fast enough, it will never be applied.
With :
repeat
if exists first pop over then exit repeat
delay 0.1
end repeat
I had to allow FastScripts access to accessibility features (see image) and then the first time it ran, I had to click to allow access, but after that, it works well.
I hadn’t looked closely enough to see you weren’t using keystroke. Cool.
I wonder about compatibility. Do you know if an older OS would be able to run this? I believe I’ll run the old method on error.
I’m not really using Calendar so I don’t know how it behaved in older systems.
I would not be surprised if it behaved differently.
This afternoon I revised an old script because I just discovered that the same feature had three different GUI structure :
one applying for 10.4.x and older systems - I knew it
one applying from 10.5 thru 10.8.x - I knew it
one applying in 10.9.x - I was unaware of it
If Calendar (which was iCal) doesn’t behave in old system as it does in 10.9, Accessibility Inspector.app to learn the structure of its GUI.
Under 10.9 we have :
Application
AXWindow
Toolbar (one)
Button (two)
Pop Over (one)
Text Field (one)
At this time I don’t have a disk under 10.8.x
Yvan KOENIG (VALLAURIS, France) lundi 21 avril 2014 22:11:57
Don’t know if you know this and haven’t been following this thread, but fyi, if an app is not allowed access with assistive devices then you can go to Preferences > Security & Privacy > Privacy > Accessability and allow access to for that app. Of I’m way off then disregard this.