Script delays on clicking button (controlling Sys Prefs pane)

This script is “working” but it gets stuck at the end with a delay clicking and holding on the “Apply Settings” button. The “Apply Settings” button turns blue, but instead of a quick click, it appears to press and hold on the button and it stays blue for about 6 seconds.

tell application "System Preferences"
	activate
	reveal (pane id "what.xgestures")
end tell
tell application "System Events"
	tell application process "System Preferences"
		tell tab group 1 of window "xGestures"
			click radio button "Pressing a key on the keyboard:"
		end tell
	end tell
end tell
tell application "System Events"
	tell application process "System Preferences"
		tell window "xGestures"
			click button "Apply Settings"
		end tell
	end tell
end tell

During that time the button is “held down” the AppleScript editor says “running.” and then when the “Apply Settings” button is released, the script stops with saying results: “missing value”

It does everything I want it to, but I’d like to get rid of the delay at the end with the “Apply Settings” button. Does anyone know what I can change to get rid of the delay at the end when I just want a quick click of the button?

Thank you so much.

Also here a screenshot of the preference pane:

Model: Macbook Pro
AppleScript: 2.1.2
Browser: Safari 5.1.2
Operating System: Mac OS X (10.6)

I wonder if the “missing value” I’m getting in the Applescript Editor log when I run them from there are clues to what’s wrong?

Here’s the log after I run the script:

tell application "System Preferences"
	activate
	reveal pane id "what.xgestures"
		--> missing value
end tell
tell application "System Events"
	click radio button "Clicking and holding a mouse button, or double clicking and holding:" of tab group 1 of window "xGestures" of application process "System Preferences"
		--> radio button "Clicking and holding a mouse button, or double clicking and holding:" of tab group 1 of window "xGestures" of application process "System Preferences"
	click button "Apply Settings" of window "xGestures" of application process "System Preferences"
		--> missing value
end tell

Result:
missing value

:rolleyes:

Ut oh, no replies to this at all… Is this a more complex issue than I understand or do I need to explain the issue better? Someone please let me know, thank you.

Hi, Alex.

Firstly, welcome to MacScripter. I’m sorry you initially had problems posting. (I forwarded your e-mail to the site’s owner, Ray Barber. Glad you’re now sorted out in that respect.)

Secondly, I’m sorry to see you haven’t had a reply yet. I assumed when I first saw your post that xGestures was some new facility in Lion, but it’s actually a third-party application which installs its own preference pane. So it’s probable that few people here have experience of it. I downloaded it this afternoon, installed it, and tried your script with exactly the same result as you. There doesn’t appear to be anything wrong with the script itself and changing ‘click button “Apply Settings”’ to ‘perform action “AXPress” of button “Apply Settings”’ makes no difference. It seems to be just a peculiarity of that button in that pane that clicking it through GUI Scripting lasts several seconds.

I’ve been trying to change the setting with “defaults write”, but with no luck so far. :confused:

Wow! Thank you so much for looking into this in so much detail! I guess it’s just one of the weird glitches maybe having to do with the pref pane coding? I’m at least emboldened by the fact that the script seems written ok considering I don’t really know what I’m doing. :stuck_out_tongue:

I guess I started to get the feeling this was a pretty esoteric issue because whenever I’ve tried to google the scenario is was leading to dead ends. If you think of any workaround that will be greatly appreciated. Also, if I somehow figure something out, I will update this post in hopes it’ll help anyone else who may ever run into a similar problem in the future. Thanks again. :slight_smile:

I’m having the same bug (?) with FileMaker Pro (versions 11 and 12). Specifically, if you use System Events to click a button that opens a new window, the window successfully opens immediately and is responsive to direct user input (clicking, typing, and so on), but the interface is non-responsive for about 6 or 7 seconds to ANY Apple Events regarding the interface elements. The ‘click’ Apple Event is supposed to respond with the object that was clicked, but as you described, some applications (or system pref panels) respond with ‘missing value’ after a 7-second delay.

I’ve tested this in some other windows in FileMaker:

  • Manage Database window - clicking Options. while a filed is selected, or any other button that opens a new dialog/window.
  • the Sort dialog - clicking the Specify. button next to “Reorder based on summary field” shows this bug.
  • the Layout Setup dialog - clicking the Properties. button next to “Table View” in the “Views” tab shows this bug.

Also, I’ve tried a BUNCH of work-arounds that fail to help:
ignoring application response: No good, since this doesn’t wait for the click command, but the interface still won’t respond to any requests to interact with the new window that was opened until the 7-second wait is over.
with timeout 0.1 seconds: No good. I wrap this with “try” and then ignore the timeout error. This also allows the script to continue, but the interface still won’t respond to commands after this until the 7-second wait is over.
perform action “AXPress”: Using this instead of ‘click’ gives the same result.

It seems the only work-around will be to give up on trying to use actual System Events that interact with objects on the interface and instead go with clicking at coordinates relative to the corner of the window in question. This is a LOT less reliable, but it seems FileMaker’s UI Scripting support (and xGestures!) is flawed enough to prevent the alternative, unless a 7-second delay is acceptable for each action that pops a new window. It might be in your example, as long as you have your script ignore the ‘missing value’ bug, but in my scenario I am trying to automate the modification of the field options for hundreds or thousands of fields in a very complex database system. So, adding a 7-second delay for every dialog/window-opening button will mean adding hours to the execution time. That might be preferable to clicking by coordinates, but neither is a good situation to be in, especially when I’m trying to monitor progress and have to wait 7 seconds per new dialog/window.

If anyone has any brilliant or crazy ideas about how to get around this bug, I’d be happy to hear it.

Model: MacBook Pro 2,1
AppleScript: 2.1.2
Browser: Safari 537.22
Operating System: Mac OS X (10.8)

UPDATE:

Here’s the core of what I’ve been using over the last couple years. Basically, instead of telling System Events to click the button (which results in long delay), I call a handler that gets the object’s coordinates, then uses a third-party command-line executable to click at those coordinates. It works pretty well, and the window being moved or resized isn’t a problem since the coordinates are obtained immediately before clicking. You could even embed the command-line binary in your app bundle, instead of storing it in your Mac’s Library, as I do below. The command-line tool ‘cliclick’ was created by Carsten Blüm, but it looks like his license allows distribution in binary or code form, as long as you include the copyright notice - looks similar to other “attribution” licenses I’ve seen. The tool is open source and on GitHub: https://github.com/BlueM/cliclick - the already-compiled binary is at https://www.bluem.net/en/mac/cliclick/

This example will click the ‘full-screen’ button (little green button next to the close and minimize buttons) in your front-most Finder window. Obviously, you wouldn’t need coordinate-clicking for that since the delay bug doesn’t occur with the Finder and that button, but it works for my FileMaker scenario, and should cover other odd bugs like the one the original poster described.


property clickCommandPath : "" -- will be set to path to the executable for 'cliclick' - from https://www.bluem.net/en/mac/cliclick/
property clickCommandPosix : ""

on run
	
	-- NOTE!!! Change "YOUR_APP" to the ~/Library/Application Support/ sub-folder name you will use:
	set clickCommandPath to ((path to application support from user domain) as string) & "YOUR_APP:cliclick"
	set clickCommandPosix to POSIX path of clickCommandPath
	
	tell application "System Events"
		tell application process "Finder"
			set frontmost to true
			my clickObjectByCoords(button 2 of window 1) -- the 'full-screen' little green button
		end tell
	end tell
	
	
end run


on clickObjectByCoords(someObject)
	using terms from application "System Events"
		set {xCoord, yCoord} to position of someObject
		set {xSize, ySize} to size of someObject
	end using terms from
	
	set xClick to round (xCoord + xSize / 2) rounding down -- middle
	set yClick to round (yCoord + ySize / 2) rounding down -- middle
	
	clickAtCoords(xClick, yClick)
	
end clickObjectByCoords


on clickAtCoords(xClick, yClick)
	set xClick to round xClick rounding down
	set yClick to round yClick rounding down
	do shell script quoted form of clickCommandPosix & " -r " & xClick & space & yClick
	--do shell script quoted form of clickCommandPosix &  " -q"
	return ((xClick as string) & "," & yClick)
end clickAtCoords

Krioni, I just today revisited this thread and thank you for sharing your workaround. I’m confused as how to apply this to the xGestures script I have. Here’s the part where it delays:

tell application "System Events"
	tell application process "System Preferences"
		click button "Apply Settings" of window "xGestures"
	end tell
end tell

I’m not sure how to integrate your script and cliclick with that. For example where the comment says:

   -- NOTE!!! Change "YOUR_APP" to the ~/Library/Application Support/ sub-folder name you will use:

I’m not sure what would be in Application Support.

@AlexM:

Maybe you figured this out long ago, but what I meant was: the cliclick command-line tool needs to be installed somewhere on your computer, and I recommended having your own sub-folder (using a name of your choosing) inside ~/Library/Application Support/ and put cliclick in that sub-folder.

You can download the cliclick tool by going to: https://www.bluem.net/en/mac/cliclick/, although it looks like you might either need to compile it yourself, or use Homebrew or MacPorts to install it. Then, you’d need to set clickCommandPosix to the full POSIX path to the cliclick tool.


property clickCommandPath : "" -- will be set to path to the executable for 'cliclick' - from https://www.bluem.net/en/mac/cliclick/
property clickCommandPosix : ""

on run
   
   -- NOTE!!! Change "YOUR_APP" to the ~/Library/Application Support/ sub-folder name you will use:
   -- NOTE: OR, just set clickCommandPosix to the POSIX path of wherever you installed cliclick (for example, if you installed it using Homebrew, it would be in /usr/local/Cellar somewhere)
   set clickCommandPath to ((path to application support from user domain) as string) & "YOUR_APP:cliclick"
   set clickCommandPosix to POSIX path of clickCommandPath

   tell application "System Events"
      tell application process "System Preferences"
          set frontmost to true
          my clickObjectByCoords ( button "Apply Settings" of window "xGestures" )
      end tell
   end tell
end run


on clickObjectByCoords(someObject)
   using terms from application "System Events"
       set {xCoord, yCoord} to position of someObject
       set {xSize, ySize} to size of someObject
   end using terms from
   
   set xClick to round (xCoord + xSize / 2) rounding down -- middle
   set yClick to round (yCoord + ySize / 2) rounding down -- middle
   
   clickAtCoords(xClick, yClick)
   
end clickObjectByCoords


on clickAtCoords(xClick, yClick)
   set xClick to round xClick rounding down
   set yClick to round yClick rounding down
   do shell script quoted form of clickCommandPosix & " -r " & xClick & space & yClick
   --do shell script quoted form of clickCommandPosix & " -q"
   return ((xClick as string) & "," & yClick)
end clickAtCoords


@Krioni

Thank you, I had figured it out but I appreciate your followup.