UI Scripting Window menu

Hi,

Does anyone know if this is the natural progress of scripting the Window menu for all apps:

tell application "Safari" to activate
tell application "System Events"
	tell process "Safari"
		tell menu bar 1
			tell menu bar item "Window"
				tell menu "Window"
					tell menu item "MacScripter"
						click
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

That part with ‘tell menu “Window”’ seems to be not necessary.

Edited: after looking at the System Events dictionary, it seems like the ‘tell menu bar item “Window”’ is not needed.

Edited: why do they do that?

Edited: here’s some sites to open with the script:

tell application "Safari"
	launch
	activate
	open location "MacScripter.net"
	open location "Google.com"
end tell
beep 1
delay 2
tell application "System Events"
	tell process "Safari"
		tell menu bar 1
			tell menu bar item "Window"
				tell menu "Window"
					tell menu item "MacScripter"
						click
					end tell
				end tell
			end tell
		end tell
	end tell
end tell

Thanks,
kel

Hi,

the standard reference to the menu “Window” is

menu 1 of menu bar item "Window"  of menu bar 1 of process "Something"

a menu bar item has always only one menu, the reference by index is sufficient.

Consider that the literal string “Window” is localized, so it’ll fail on non-english systems

PS: And your script assumes that “Open pages in tabs instead of windows” is set to never

Hi Stefan,

That’s exactly what I wanted to know.

Thanks a lot,
kel

Hi,

Does anyone know what’s the purpose for the ‘menu bar item’?

Edited: come to think of it, it’s more like what’s the purpose of the menu item. Getting mixed up. :slight_smile: I need to reread Stefan’s post.

Thanks,
kel

I have a theory on why you need the menu bar item. Menus could have many items, so you wouldn’t want it cluttering up the main menu bar.

Hi Stefan,

That’s right. Are tabs considered as window in Safari?

Good catch, if it’s true. I hate to change to tabs to check if they are windows. I need to check on that, but I would think that the tabs are in the windows.

Later,
kel

tabs are an element of a window.
A window can have multiple tabs.
A tab has always a parent window

Hi Stefan,

I checked it out and all I need is the current tab in a window.

Thanks a lot,
kel

Hello kel.

You’ll find the name of the current tab of a window, by looking at the document behind the window.

If the window has a tab, it sure has a document.

Maybe this simple script may help :


activate application "Safari"
tell application "System Events" to tell process "Safari"
	tell window 1
		set theClasses to class of every UI element
		--> {button, button, button, group, tab, group, group, button, static text, tool bar}
		set tabIndexes to {}
		repeat with i from 1 to count theClasses
			if (item i of theClasses as text) is "tab" then copy i to end of tabIndexes
		end repeat
		log tabIndexes
		--> (*5*) # now we have a list of indexes of tab items but I don't like to use a loop to do that
		# So I choose to identify them by their role
		properties of every UI element whose role is "AXTabGroup"
		--> {{description:"groupe d'onglet", orientation:missing value, position:{835, 294}, class:tab, role description:"groupe d'onglet", accessibility description:missing value, focused:false, title:missing value, size:{1630, 24}, help:missing value, enabled:missing value, maximum value:missing value, role:"AXTabGroup", entire contents:{}, subrole:missing value, selected:missing value, name:missing value, minimum value:missing value}}
		
	end tell
end tell

KOENIG Yvan (VALLAURIS, France) jeudi 18 juillet 2013 12:40:41

Hello.

I wonder if this will work for applications that aren’t scriptable (but with UI Elements enabled).

tell application "Safari" to activate

tell application "System Events" to tell process "Safari"
	set l to name of first UI element whose role is "AxWindow"
	
end tell

I also wonder how I get at the document behind the window, if any. ( I have seen Stefan do it with Preview I believe, but I can’t for the bare life of me find that post!) :confused:

Here is at least one way to get the file URL behind a window:

tell application "System Events"
	tell process "Preview"
		set fileBehindWindow to value of attribute "AXDocument" of (first UI element whose role is "AxWindow")
	end tell
end tell
fileBehindWindow

And here is how to get the title, which is what you want to figure out which tab is the current tab.
I used Preview since it isn’t scriptable, uneccesary to say: I think UI Elements must be enabled for both of those snippets to work.

tell application "System Events"
	tell process "Preview"
		set theWinTitle to value of attribute "AXTitle" of (first UI element whose role is "AxWindow")
	end tell
end tell
theWinTitle

I don’t know if you have got hold of this script kel, it is great for figuring out UI Scripting. You can find it here.

Hi Everybody,

Actually I wasn’t planning to script the tabs in a window, but just bring the window to the front, as in the Frontmost window project we were writing about earlier. I was thinking what is the most generic way to do it with all (or most) applications (scriptable, non-scriptable, Smile, Finder, etc.). One thing I’m thinking is that I don’t want the ‘choose from list’ window to get too big. After sleeping on it, I might add the tabs also. I now have the tools to do it with all your scripts. Yeah, tabs might be good if I have to switch from tabs in different windows.

Hi McUsr,

I started writing a script to find the references to ui elements in the past, but never finished it before my computer with Jaguar went down. I’ll check out your posted script link. I’m doing pretty well with my old method and Xcode’s Accessibility Inspector, but anything that makes it easier is good.

Thanks everybody,
kel

Hello.
It is not my script, Nigel has written the better part of it. It’s really good. :slight_smile:

Hi McUsr,

Yes, I was looking at the reviews :slight_smile: in the post. Almost finished with the rough draft of the simple window to front script using ui scripting. I hate when I have to try sleeping when a script is almost done. Besides testing and tweaking it.

Goodnight and goodmorning,
kel

Well.

If you are used to UI Scripting the way you described, then the script won’t totally alleviate that way of working, but it gives you a great overview of the hiearchy. It is like the blue pill. :slight_smile:

If I get the time during the weekend, I’ll have a go with some UI Scripting of the same problem myself. you have given me som ideas. Have a good night.

Hi McUsr,

TGIF!

I’ve hardly used the AXObject thing, Now I see how you were showing me how to use it. Good easy example. Thanks.

In Jaguar, the beta ui element scripting app had just come out and didn’t work very well in that os.

Have a good day,
kel

Hello.

You have a nice day as well. I haven’t full control on this topic, because it is somewhat of a separate lingo. But as long as ui scripting is supported by an app, (assistive devices) then scripting by means of ui scripting, should be far more successful, than mere AppleScripting when you want to write once, and deploy/use for many apps. I believe many more apps, though not all support UI Scripting.

The examples, was actually not intended for learning, as I am learning this myself, but to be useful in your context.

I have figured out that the keywords are role, subrole, value and UI Elements. There are probably some more.

I really have to have a good look at this, and maybe find a document at developer connection.

Soon starting to be productive with FileMaker Pro now. :slight_smile:

P.S

When it is late, I am tired, and really don’t want to stop. Then I take the “Pacman test”: if I’m too tired to get a decent score, then I go to bed. :slight_smile:

Hi,

Finally got a rough draft. Still need to change the ‘menu bar item “Window”’ to the non-local way of doing it with the AX thing among other things probably. :slight_smile:

set my_name to name of me
tell application "System Events"
	-- show hidden processes
	set visible of every process to true
	set process_list to name of every process whose visible is true and name is not my_name
end tell
set user_list to {}
set i to 0
repeat with this_process in process_list
	set i to i + 1
	set end of user_list to ((i as string) & tab & (contents of this_process))
	tell application "System Events"
		set window_list to name of every window of process this_process
	end tell
	repeat with this_window in window_list
		set end of user_list to ((i as string) & tab & tab & (contents of this_window))
	end repeat
end repeat
set user_choice to (choose from list user_list) as string
if user_choice is "false" then error number -128 -- user canceled
set process_index to word 1 of user_choice
set user_process to item process_index of process_list
tell application "System Events"
	tell process user_process
		set frontmost to true
		if user_choice contains (tab & tab) then
			set user_window to (text ((count process_index) + 3) thru -1 of user_choice)
			tell menu bar 1
				tell menu bar item "Window"
					tell menu 1
						try
							tell menu item user_window
								click
							end tell
						on error -- it's a dialog window, so do nothing
						end try
					end tell
				end tell
			end tell
		end if
	end tell
end tell
-- Notes:
-- Some processes might not have the same name as the application.
-- Need to change the 'menu bar item "Window"' line.
-- Need to fix windows toggling like iTunes.

Learned a lot of new things plus reviewed old stuff.

Hi Yvan,

I still don’t understand what you meant by:

It seems like the properties of “AXTabGroup” doesn’t show anything useful. I’ll have to look more deeply into it.

Edited: the “Pacman test” LOL

Edited: darn, there’s a bug with the iTunes window!

Edited: iTunes window is toggling on and off! Need to fix that later.

Edited: I put the ‘end if’ in the wrong place.

Thanks a lot everybody,
kel