• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Finding the focused UI element
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Finding the focused UI element


  • Subject: Re: Finding the focused UI element
  • From: Arjen Baarsma <email@hidden>
  • Date: Thu, 17 Jul 2008 19:11:30 +0200

Thank you for your response Philip, that was indeed what I wanted my script to do: Open a context menu for the currently focused control so I can then navigate through this context menu with the keyboard. The idea is that it should work for (almost) any control in (almost) any application, but I may need to have to write separate scripts for different applications if I can't find a fast way to find the focused UI element of any arbitrary application.

I think you will have to search out third party utilities effect a solution because although a UI Browser may show you the focused element, it's not always the case that System Events scripting has a mapping implemented for it or if it does, implements it correctly.

Yeah, I fear it may not be possible using applescript alone. I've found ways to find the focused UI element using Objective-C/cocoa and the rest should also work there, so it might be an idea to write it using that instead (but I'd first have to learn how to do that then). If anyone happens to know a third party utility that could help, I'd be happy with that too.


The script works for many controls of most applications, but it's usually slow and sometimes even very slow. I've tested it in TextEdit and ScriptEditor (works) and the Finder (only works in list view), in Adium chat windows (works, becomes very slow when there are a lot of messages), in Apple Mail (slow and always shows the menu for the first item in a list instead of the selected one, will have to look into that later), safari (bad idea) and several preference windows (works) and also in some other applications.
This is what the entire script looks like at the moment. The beeps and the delay shouldn't be there in the final version of course since I just put them there for testing purposes.


delay 1 -- this is here to give me time to cmd-tab to another application
beep -- we've started
try
tell application "System Events"
set theControl to my findFocus(front window of (first application process whose frontmost is true))
end tell
sMenu(theControl)
end try
beep -- we're done


on sMenu(theControl) -- show the context menu
tell application "System Events"
if ("AXShowMenu" is in name of actions of theControl) then -- if theControl has a menu, show it
perform action "AXShowMenu" of theControl
else if class of theControl is not window then -- if not, try its parents (needed for e.g. toolbar buttons)
my sMenu(value of attribute "AXParent" of theControl)
end if
end tell
end sMenu


on findFocus(theParent) -- find the (deepest) UI element that has focus
tell application "System Events"
if exists (first UI element of theParent whose focused is true) then -- if we've found one with focus!
return my findFocus(first UI element of theParent whose focused is true)
-- what I'm doing here is searching the children of the UI element we've just found to see if any of them has focus (we want the deepest element with focus), which is necessary for e.g. the Finder
else if (exists focused of theParent) and focused of theParent then -- I've had to add the exists part because there are UI elements which you can't ask if they have focus, I may have to add it elsewhere as well
return theParent
-- when we've already found something with focus and none of its children has focus we're done
else
repeat with theChild in UI elements of theParent
set output to my findFocus(theChild)
if not (output is false) then return output
end repeat
-- keep searching as long as we haven't found anything with focus yet
return false
end if
end tell
end findFocus


Although the rest may also need improvement, it is at the moment the findFocus function that forms the problem. It should find the UI element that currently has focus and it does that perfectly, but it's VERY slow in many cases (it's not even fast when there's just a few dozen UI elements in a window). If it's not immediately clear how this function works, speeding it up is basically the same as speeding up the following function, which counts the number of UI elements on a form (andd takes the window in which to search as its argument)

on countUIEs(theParent)
	set res to 0
	tell application "System Events"
		repeat with theChild in UI elements of theParent
			set res to res + 1
			set res to res + (my countUIEs(theChild))
		end repeat
	end tell
	return res
end countUIEs

This already takes more than a second to run for me for a window containing only 39 UI elements (the script editor window).

For the UI element search speed, you may be able to apply the Serge- Garvey techniques: <http://www.google.com/search? client=safari&rls=en-us&q=Nigel+Garvey+Applescript +speed&ie=UTF-8&oe=UTF-8> (List Processing speed). There are a few people on this list you can help you speed up a script but you'd have to post it for them to be able to make any comments.

After reading this I've tried implementing such a technique by replacing the function above by the following function


on countUIEs2(theParent)
	set res to 0
	tell application "System Events"
		script s
			property sUIels : UI elements of theParent
		end script
		set n to number of sUIels of s
		repeat with i from 1 to n
			set res to res + 1
			set res to res + (my countUIEs2(item i of sUIels of s))
		end repeat
	end tell
	return res
end countUIEs2

This version indeed seems to be noticeably faster than the one above, but I'm afraid the difference in speed is not enough for my purposes here.
If anyone sees a way to speed up my function significantly or, even better, to quickly obtain the focused UI element of an application, that would be very helpful.


– Arjen
_______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users

This email sent to email@hidden
  • Follow-Ups:
    • Re: Finding the focused UI element
      • From: Bill Cheeseman <email@hidden>
References: 
 >Finding the focused UI element (From: Arjen Baarsma <email@hidden>)
 >Re: Finding the focused UI element (From: Philip Aker <email@hidden>)

  • Prev by Date: Re: Finding the focused UI element
  • Next by Date: Re: UI scripting question
  • Previous by thread: Re: Finding the focused UI element
  • Next by thread: Re: Finding the focused UI element
  • Index(es):
    • Date
    • Thread