Get window of certain tab in Applescript - applescript

So I'm trying to set the variable called theWindow to a window with a tab whose URL contains "google.com".
tell application "Google Chrome"
set theTabs to a reference to (tabs of windows whose URL contains "google.com")
set theTab to item 1 of theTabs
set theWindow to window of theTab
end tell
However, this doesn't work and the code returns:
Google Chrome got an error: Can’t get window of tab id 384 of window id 383." number -1728 from window of tab id 384 of window id 383

I don't use Chrome so you may have to convert but this is how it might be done with Safari.
tell application "Safari"
set sst to "nikon"
repeat with w in windows
if exists (tabs of w whose URL contains sst) then
set wix to index of w
set wid to id of w
exit repeat
end if
end repeat
end tell
display dialog "Window: " & wix & return & "Window ID: " & wid
It cycles through open windows and checks if any of its tabs have a matching URL. If at least one does, then it provides the index and ID for that window. Obviously, if multiple tabs match the search term then the result will be affected.

Related

Applescript, "A class name can't go after this identifier error", what does it mean?

Someone tried to help me set up a keyboard macro using a program called keyboard maestro on macos to control youtube, his example had safari:
set tabURL to "YouTube.com"
tell application "Safari"
set windowsList to index of every window
repeat with i in windowsList
try
tell window i
set current tab to (first tab whose URL contains tabURL)
end tell
set index of window i to 1
exit repeat
end try
end repeat
end tell
It worked, I simply changed the name safari to google chrome, I put in this code:
set tabURL to "YouTube.com"
tell application "Google Chrome"
set windowsList to index of every window
repeat with i in windowsList
try
tell window i
set current tab to (first tab whose URL contains tabURL)
end tell
set index of window i to 1
exit repeat
end try
end repeat
end tell
it gave me this error message
2020-09-10 15:02:26 Execute an AppleScript failed with script error: text-script:165:176: script error: A class name can’t go after this identifier. (-2740)
what does it mean? any help appreciated.
tell application "Google Chrome"
repeat with thisWindow in windows
set cnt to 1
repeat with thisTab in (tabs of thisWindow)
if URL of thisTab contains "youtube.com" then
set active tab index of thisWindow to cnt
set index of thisWindow to 1
exit repeat
end if
set cnt to cnt + 1
end repeat
end repeat
end tell
this is the fix if anyone cares.

How to click button in AppleScript?

Writing an AppleScript to open Image Capture and click the Import All button.
tell application "Image Capture"
activate
tell application "System Events"
tell process "Image Capture"
click button "Import All" of group 1 of splitter group 1 of window 1
end tell
end tell
end tell
Image Capture opens but the script throws an error message saying it couldn't find the button "Import All".
Have followed advice on other threads on how to check the location in Accessibility Inspector and how to translate that to AppleScript instructions.
What's missing?
To get the button and group numbers, you have 2 ways: use the utility aplication provided by Apple in the developper toolkit "Accessibility Inspector" or use small scripts to find the number yourselves.
I prefer using script method. it is a bit longer sometime, but it always works. Just write a script with instruction get UI elements. Here is a small example of such script:
-- return lis of UI elements of active application and paste result in Excel
property tab : ASCII character 9
global T
-- to find last active application
tell application "System Events"
set frontmostProcess to first process where it is frontmost
set visible of frontmostProcess to false
repeat while (frontmostProcess is frontmost)
delay 0.2
end repeat
set secondFrontmost to name of first process where it is frontmost
set frontmost of frontmostProcess to true
end tell
set ActifProcess to secondFrontmost as text
tell application ActifProcess to activate -- set active the last actived application
delay 1
-- recursive loop to list all elements of active window
tell application "System Events" to tell process ActifProcess to set myWindow to front window
set T to ""
getUI(myWindow, 1)
set the clipboard to T
display dialog "Result is in clipboard. paste in Excel or text document"
on getUI(UIObjet, myLevel) -- get recursively the list of UI elements
set AppleScript's text item delimiters to {"//"}
tell application "System Events" to set UIliste to UI elements of UIObjet
repeat with oneUI in UIliste
tell application "System Events"
set UItext to ("Level=" & myLevel & tab & "Name=" & (name of oneUI) & tab & (description of oneUI) & tab & "Class=" & (class of oneUI) as string) & tab & "Title=" & (title of oneUI) as string
set UItext to (UItext & tab & "Value=" & (value of oneUI) as string) & tab
try
set UItext to (UItext & "Position=" & (position of oneUI) as text)
end try
set UItext to UItext & return
try
set NbSub to count of UI elements of oneUI
on error
set NbSub to 0
end try
set T to T & return & UItext
end tell
if NbSub > 0 then
getUI(oneUI, myLevel + 1) -- there are other sub UI elements, get them
end if
end repeat
end getUI
Copy this script in Script Editor. Make active the window/application you want to get UI elements. Make this script active and run.
The result is sometime not easy to interpret because developper of the application/window you're looking for may not have use UI element clear names or titles which describe what they are. Then you will have to look their relative position in the window.
The "import all" button is "button 3 of group 2 of splitter group 1 of window 1" for image capture version 6.6. Also, I prefer to use button number, instead of button name to make sure the script works with any language.
tell application "Image Capture"
activate
tell application "System Events"
tell process "Image Capture"
click button 3 of group 2 of group 1 of splitter group 1 of window 1
end tell
end tell
end tell
Please note that any next changes done by Apple on Image Capture will impact your script.

AppleScript: Get list of windows on all desktops

I need to get a count of all windows per application. Every way I've tried to do this, I only get a count of windows that are assigned to the current (Mission Control) Desktop. (I'm currently running Mac OS X 10.7, so post-Spaces.) Is there any way to get a per-application count of all windows across all Desktops?
The crux of what I've tried:
tell application "System Events"
repeat with _app in (every process whose visible is true)
tell _app
log (name as string) & ": " & (count of every window)
end tell
end repeat
end tell
Note that the whose visible is true clause isn't the problem. It finds all of the appropriate processes, but once I ask the processes for windows, they only count the ones in the active Desktop.
I've tried pulling the log line out of the tell and using name of _app and count of every window of _app, but there's no difference. I've tried grabbing things other than processes from System Events, but anything useful ends up effectively being just a different way to get the same object. I've tried iterating over UI elements, but no windows show up that aren't on the current Desktop, though I do get a menubar for each application.
I'm fine with iterating across all Desktops (though not actually switching to all of them), but I can't even find a way to get a list of Desktops. This answer claims to describe how to do that, but I only ever get a single element inside every desktop. Not that there's an obvious way to get windows once you have that Desktop object anyway.
It's also worth pointing out that desktops are controlled by the Dock, and not by Mission Control. I'm not aware of any way for AppleScript to talk to the Dock, so if you know of something, then an answer or comment about that might help point me in the right direction.
Am I trying to do something impossible?
I ran your code, setting up the Applescript version to 2.4 (do that as a habit); on the first run, your code presented me with the appropriate count of all the windows per application.
This code is what I tried, and the results seem to be satisfactory. Is there something I'm not seeing?
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
tell application "System Events"
set my_list to {}
repeat with _app in (every process whose visible is true)
tell _app
log (name as string) & ": " & (count of every window)
set my_list to my_list & {name as string, count of every window}
end tell
end repeat
log my_list
end tell
As the OP is over six years old and I am unable to test under OS X 10.7, which is what was being used at that time, nonetheless, the following example AppleScript code works for me under macOS Catalina and returned the correct window count across all Desktops/Spaces, with the exception of any application that does understand the given AppleScript command and why the try and on error statements are being used.
Example AppleScript code:
tell application "System Events" to ¬
set appBundleIdentifierList to ¬
the bundle identifier of ¬
(every process whose visible is true)
repeat with appBundleIdentifier in appBundleIdentifierList
try
tell application id appBundleIdentifier to ¬
set {appName, winCount} to {name, (count windows)}
log appName & ": " & winCount
on error errorMessage
log errorMessage
end try
end repeat
Sample output on my system that has multiple Desktops/Spaces with windows of the application on all or some of the Desktops/Spaces and the window count for each is correct across all Desktops/Spaces, not just the active Desktop/Space the script was run from.
(*Safari: 6*)
(*Terminal: 2*)
(*TextEdit: 4*)
(*Script Editor: 7*)
(*Finder: 3*)
(*BBEdit: 1*)
(*Norton Secure VPN got an error: every window doesn’t understand the “count” message.*)
(*Music: 2*)
Notes:
Not all applications are AppleScript scriptable, in that some do not contain an AppleScript dictionary within their application bundle.
Since the application process cannot return the correct number of windows across all Desktops/Spaces, this method relies on the application to return the number of windows across all Desktops/Spaces.
Update:
The following example AppleScript code does the following:
Gets the bundle identifier of every process whose visible is true.
For each bundle identifier, get its name and the window count by querying the application directly. If the application understands the AppleScript command, then if goes to the next item in the appBundleIdentifierList list. If it does not understand, then the window count is calculated by the following:
Attempts to get an invisible window count as they would not show up on the Window menu of an application.
Calculates the window count by the number of windows shown on the Window menu of the application.
Failing these methods it get the window count by querying the application process, with is only accurate fo the active Desktop/Space and is included only for completeness of trying to ascertain the window count just using basic vanilla AppleScript.
Goes to the the application in the appBundleIdentifierList list.
Example AppleScript code:
set menuName to "Window"
tell application id "com.apple.systemevents" to ¬
set appBundleIdentifierList to ¬
the bundle identifier of ¬
(every process whose visible is true)
repeat with appBundleIdentifier in appBundleIdentifierList
try
tell application id appBundleIdentifier to ¬
set {appName, winCount} to {name, (count windows)}
log appName & ": " & winCount & ¬
" -- By querying the application directly."
on error
set winCount to 0
set notVisibleWindowList to {}
set errAppName to ¬
name of application id appBundleIdentifier
tell application id "com.apple.systemevents"
try
tell application process errAppName
set notVisibleWindowList to ¬
(windows whose visible is false)
if notVisibleWindowList is {} then ¬
set winCount to ¬
length of notVisibleWindowList
end tell
end try
try
set theTargetMenuItemsList to ¬
the reverse of ¬
(get name of ¬
menu items of ¬
menu menuName of ¬
menu bar item menuName of ¬
menu bar 1 of ¬
application process errAppName)
on error
set theTargetMenuItemsList to {}
end try
end tell
if theTargetMenuItemsList is not {} then
repeat with anItem in theTargetMenuItemsList
if contents of anItem is ¬
missing value then exit repeat
set winCount to winCount + 1
end repeat
log errAppName & ": " & winCount & ¬
" -- By querying the Window menu of the application process."
else
try
tell application id "com.apple.systemevents" to ¬
set winCount to ¬
(count windows of ¬
application process errAppName)
log errAppName & ": " & winCount & ¬
" -- By querying the application process. " & ¬
"May not be accurate, verify as necessary."
end try
end if
end try
end repeat
Running both versions of the example AppleScript code to show the difference in output:
First version of example AppleScript code:
(*Safari: 6*)
(*TextEdit: 4*)
(*Finder: 3*)
(*BBEdit: 1*)
(*Norton Secure VPN got an error: every window doesn’t understand the “count” message.*)
(*Music: 2*)
(*Sublime Text 2 got an error: every window doesn’t understand the “count” message.*)
(*DiskCatalogMaker got an error: every window doesn’t understand the “count” message.*)
(*Script Editor: 7*)
(*System Preferences: 2*)
(*VMware Fusion got an error: every window doesn’t understand the “count” message.*)
(*Activity Monitor got an error: every window doesn’t understand the “count” message.*)
(*Terminal: 2*)
Second version of example AppleScript code:
(*Safari: 6 -- By querying the application directly.*)
(*TextEdit: 4 -- By querying the application directly.*)
(*Finder: 3 -- By querying the application directly.*)
(*BBEdit: 1 -- By querying the application directly.*)
(*Norton Secure VPN: 0 -- By querying the application process. May not be accurate, verify as necessary.*)
(*Music: 2 -- By querying the application directly.*)
(*Sublime Text 2: 4 -- By querying the Window menu of the application process.*)
(*DiskCatalogMaker: 2 -- By querying the Window menu of the application process.*)
(*Script Editor: 7 -- By querying the application directly.*)
(*System Preferences: 2 -- By querying the application directly.*)
(*VMware Fusion: 1 -- By querying the Window menu of the application process.*)
(*Activity Monitor: 0 -- By querying the Window menu of the application process.*)
(*Terminal: 2 -- By querying the application directly.*)
As you can see even Activity Monitor, a native default macOS application, the Window menu had to be queried as the application directly didn't understand the basic count windows AppleScript command.
Although the output of the second version of the code was accurate across all Desktops/Spaces at the time it was executed, any application that has "By querying the application process. May not be accurate, verify as necessary." as part of its output only includes the window count of the active Desktop/Space it was executed form. The bottom line is using basic vanilla AppleScript there is no guarantee to get a complete accurate window count of every visible application unless all the applications at that time cen be queried directly. Querying the Window menu by its application process should also be accurate.
With that said, I think other methods may need to be used to get an accurate count.

Can't retrieve custom title of OSX terminal tabs

I'm trying to select a certain terminal tab in OSX and send keystrokes to it. But Terminal in OSX 10.8.4 doesn't seem to store anything but "Terminal" for a tab's custom title, even if you set a custom title with the inspector. Any ideas? Here is the code I'd like to use to select the right tab:
tell application "Terminal"
set allWindows to number of windows
repeat with i from 1 to allWindows
set allTabs to number of tabs of window i
repeat with j from 1 to allTabs
if custom title of tab j of window i contains "blah" then
set frontmost of window i to true
set selected of tab j of window i to true
end if
end repeat
end repeat
end tell
I'm working on an older version of OSX, so I couldn't duplicate your problem (your code works fine for me), but perhaps try:
if ((custom title of (current settings of (tab j of (window i)))) as string) contains "blah" then
Make sure you set the tab name this way:
tell "application" "Terminal"
# ...
set the_tab to tab 1 of the front window -- replace with your tab selector
tell settings set "Basic"
set custom title of the_tab to "My Tab Name"
end tell
# ...
end tell
You should be able to get retrieve the tab name:
tell "application" "Terminal"
set the_name to custom title of the_tab as string
end tell
Works for me on OSX 10.8.4

How to close safari tabs by url using applescript

I'm looking for a way to close specific tabs in safari by the url.
I would probably expand on something like this:
tell application "Safari"
repeat with t in tabs of windows
tell t
if name starts with "google.com" then close
end tell
end repeat
end tell
the problem here is that i haven't found a way how to get the url value of a tab and close them based on that.
You can get the URL from Safari based on the active tab.
tell application "Safari"
set w to first window
set t to current tab of w
display dialog (URL of t as string)
end tell
And then you could iterate over every tab/page like this :
tell application "Safari"
set windowCount to number of windows
repeat with x from 1 to windowCount
set tabCount to number of tabs in window x
repeat with y from 1 to tabCount
set thistab to tab y of window x
set foo to URL of thistab
if foo is not equal to "bar" then close thistab
end repeat
end repeat
end tell
Here is another method:
set closeURLs to {"http://www.yahoo.com", "http://www.apple.com"}
repeat with theURL in closeURLs
tell application "Safari" to close (every tab of every window whose URL contains (contents of theURL))
end repeat

Resources