I'm attempting to create a macro that will either activate, or launch, Firefox with a specific profile. I'm using a plugin so that each Firefox instance has the profile name in the title, so the following macro half works to invoke Firefox using the profile only if it hasn't already been launched.
But how can I identify and activate the window/app based on the word in its title? I can't just activate Firefox because it will not necessarily show the right instance, and invoking Firefox again with the same profile results in an error because that profile is already running.
Thanks. That should work. BUT, there is something buggy, maybe with Firefox, or maybe because of multiple instances: if I only have one instance of Firefox running, this works fine. If I have more than one, it still works fine UNLESS I am viewing, or have viewed, a different instance. Then, for some reason, it doesn't detect the window title text (until I switch back to the WYRD profile and try again).
Script debugger shows the windows with the words in the title, so I'm not sure why KM doesn't see them consistently:
{{"firefox", "firefox"},
{{window "[FNCLL] Posts | Chris Lott (@fncll@social.coop) | Elk" of application process "firefox"},
{window "Library" of application process "firefox", window "[WYRD] Download | Late Night Software" of application process "firefox"}}}
No, but you are creating multiple concurrent instances of it. When you ask KM to "get the window names from Firefox" it doesn't know which Firefox you mean, and will probably use the (most recently) frontmost.
Following on from @ccstone's smart idea, try the following in Script Debugger and let us know what you get:
tell application "System Events"
tell (processes whose name contains "Firefox")
return {its name, its id, its windows}
end tell
end tell
We need to target the correct instance of Firefox, and getting the "process id" of the one which has the window you want could enable that.
I'm not sure how well it's going to manage multiple instances of Firefox, but hopefully it's on the right track.
--------------------------------------------------------
# Auth: Christopher Stone <scriptmeister@thestoneforge.com>
# dCre: 2023/03/03 11:46
# dMod: 2023/03/03 11:46
# Appl: Miscellaneous AppleScript, System Events
# Task: Raise a Window of a Partially Named Process by Partial Name.
# Libs: None
# Osax: None
# URLs: https://forum.keyboardmaestro.com/t/activate-the-window-or-application-with-a-specific-word-in-title/31152/
# Tags: @Applescript, @Script, @System_Events, @Raise, @Window, @Partially, @Named, @Process, @KMF, @Chris_Lott
--------------------------------------------------------
set appName to "Firefox"
set windowNameContains to "WYRD"
raiseAppWindowByName(appName, windowNameContains)
--------------------------------------------------------
--ยป HANDLERS
--------------------------------------------------------
on flattenList(theList)
script util
property flattenedList : theList
property interimFlattenedList : missing value
end script
repeat while util's flattenedList's lists's length > 0
set util's interimFlattenedList to {}
repeat with currItem in util's flattenedList
tell currItem's contents
if its class = list then
set util's interimFlattenedList to util's interimFlattenedList & it
else
set end of util's interimFlattenedList to it
end if
end tell
end repeat
set util's flattenedList to util's interimFlattenedList
end repeat
return util's flattenedList as list -- "as list" assures that the return value is dereferenced
end flattenList
--------------------------------------------------------
on raiseAppWindowByName(appName, windowName)
tell application "System Events"
tell (application processes whose name is appName)
set windowList to (windows whose name contains windowName)
set windowList to my flattenList(windowList)
repeat with theWindow in windowList
tell contents of (get theWindow)
perform action "AXRaise"
end tell
end repeat
end tell
end tell
end raiseAppWindowByName
--------------------------------------------------------
This results in an invalid object reference, though it does refer to the proper instance of Firefox based on the name of the window it is trying to activate:
window "[WYRD] Activate the Window or Application With a Specific Word in Title - Questions & Suggestions - Keyboard Maestro Discourse" of application process "firefox"
And not sure if this helps, but the AEPrint window of Script Debugger has this:
'obj '{ 'form':'name', 'want':'cwin', 'seld':'utxt'("[WYRD] Activate the Window or Application With a Specific Word in Title - Questions & Suggestions - Keyboard Maestro Discourse"), 'from':'obj '{ 'form':'name', 'want':'pcap', 'seld':'utxt'("firefox"), 'from':[0x0,6a039fd "System Events"] } }
I just meant there is, as far as I know, no other way to use different profiles with Firefox than to run concurrent instances.
The output from your script:
{{"firefox", "firefox"}, {110446926, 111245841}, {{window "[UW] |Home - Radio Paradise" of application process "firefox"}, {window "[WYRD] DuckDuckGo โ Privacy, simplified." of application process "firefox"}}}
I'm still not sure if you want to activate just the correct instance of Firefox or a specific window in a specific instance -- if it's the latter you'll need more than just the prefix of the window name.
This should pop the right Firefox -- you could leave the prefix hard-coded or get it from a KM variable:
set theTarget to "[WYRD]"
tell application "System Events"
tell (processes whose name contains "Firefox")
set theList to {its id, name of its windows}
end tell
repeat with i from 1 to count of item 1 of theList
repeat with j from 1 to count of item i of item 2 of theList
if item j of item i of item 2 of theList starts with theTarget then
set processID to (get item i of item 1 of theList)
set frontmost of process id processID to true
return 0
end if
end repeat
end repeat
end tell
return "Not found"
If you want a specific window, set theTarget to the exact name and do the comparison using is rather than starts with, adding a couple of lines to get/target the window:
set theTarget to "[WYRD] A Particular Window Title"
tell application "System Events"
tell (processes whose name contains "Firefox")
set theList to {its id, name of its windows}
end tell
repeat with i from 1 to count of item 1 of theList
repeat with j from 1 to count of item i of item 2 of theList
if item j of item i of item 2 of theList is theTarget then
set processID to (get item i of item 1 of theList)
set winName to (get item j of item i of item 2 of theList)
set frontmost of process id processID to true
tell window winName of application process id processID to perform action "AXRaise"
return 0
end if
end repeat
end repeat
end tell
return "Not found"