I’m using “Keystroke” to fill the UI with the assigned variable, but when I switch to another application the script continues to apply the keystroke.
I'm using the below code to make the application active again, but is there a possibility to stop the combination key until the script gets completed
on ActiveError()
global frontApp, frontAppName, windowTitle
set windowTitle to ""
tell application "System Events"
set frontApp to first application process whose frontmost is true
set frontAppName to name of frontApp
tell process frontAppName
tell (1st window whose value of attribute "AXMain" is true)
set windowTitle to value of attribute "AXTitle"
end tell
end tell
end tell
if frontAppName is not equal to "Adobe InDesign 2022" then
tell application "Adobe InDesign 2022" to activate
-CustomAlert()
end if
return {frontAppName, windowTitle}
end ActiveError
Thank you
When I get the reference to a window using for example:
tell application "Safari"
set theWindow to first window
end tell
log(process(theWindow)) -- # Safari
tell application "Terminal"
set theWindow to first window
end tell
log(process(theWindow)) -- # Terminal
to process(theWindow)
-- How to get app name from "theWindow"
end process
From the variable theWindow, is it possible to extract the app name "Safari"? I need to know this information from a handler because the handler can accept window reference of other application as well.
tell application "Safari"
set theWindow to first window
end tell
log (process(theWindow))
tell application "Terminal"
set theWindow to first window
end tell
log (process(theWindow)) -- # Terminal
to process(theWindow)
try
theWindow as text
on error errorMessage
end try
set ATID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "\""
set appName to text item 2 of errorMessage
set AppleScript's text item delimiters to ATID
return appName
end process
I am trying to write an apple script that when executed, will make the currently focused window "always on top". Is this possible?
In objective-c I can do this on windows my process owns by using [NSWindow setLevel:] but my struggle is to do it for windows my process does not own. So I am now trying to do it via apple script.
I tried this:
global frontApp, frontAppName, windowTitle
delay 3
set windowTitle to ""
tell application "System Events"
set frontApp to first application process whose frontmost is true
set frontAppName to name of frontApp
tell process frontAppName
set level of window 1 to 3
tell window 1
set windowTitle to value of attribute "AXTitle"
end tell
end tell
end tell
return {frontAppName, windowTitle}
However this gives me error -
System Events got an error: Can’t make level of window 1 of process "firefox" into type specifier.
This script works when terminal application(or any application) is not in FullScreen mode. It will return the correct value of false. When you make the application fullscreen it returns any empty value. The only thing I can think of is that when you go fullscreen it puts it on a different desktop? Am I missing something to activate the app differently now that it is fullscreen?
tell application "System Events" to set the visible of every process to true
set white_list to {"Finder", "AppleScript Editor", "Google Chrome"}
tell application "System Events"
set process_list to the displayed name of every process whose visible is true
set process_number to (number of items in process_list)
set myList to process_list
end tell
repeat with theItem in myList
if theItem is not in white_list then
log theItem
tell application "System Events" to tell process theItem
set isFullScreen to the value of attribute "AXFullScreen" of windows
end tell
end if
end repeat
return theItem & " application is FullScreen: " & isFullScreen
This line won't work as written...
set isFullScreen to the value of attribute "AXFullScreen" of windows
"windows" will return a list of windows and you can't get that attribute from a list. So you would want to write it as...
set isFullScreen to the value of attribute "AXFullScreen" of window 1
However, with that said I tried this and it seems you can't get the windows from a full screen process. The list of windows is always empty {}. So this approach of determining if an application is full screen will not work.
You'll need to think of another way to figure out if an application is full screen. I tried a couple things and couldn't find a solution. Sorry.
I am attempting to write an applescript script that will allow me to resize all windows of all running applications whenever I choose (I currently use Stay, but find that it is glitchy at times, so I want to "re-invent" it)
I have been following some applescripting tutorials and have come up with the following code to do so, but it is buggy:
tell application "Finder"
set rect to bounds of window of desktop
end tell
property excludedApplicationNames : {"Finder"}
tell application "System Events"
say "a"
repeat with theProcess in processes
say "b"
if background only of theProcess is false then
say "c"
set theProcessName to name of theProcess as string
if theProcessName is not in excludedApplicationNames then
say theProcessName
tell application theProcess
set bounds of windows of process theProcess to rect
end tell
end if
end if
end repeat
end tell
say "done"
The problem is that when this code encounters my only terminal window (with several open tabs), it error: System Events got an error: Can’t set application (item 2 of every process) to {0, 0, 1280, 900}.System Events got an error: Can’t set application (item 2 of every process) to {0, 0, 1280, 900}.
Changing tell application theProcess to tell application theProcessName doesn't help (same error), and neither does changing it to tell application "System Events" (Error: System Events got an error: Can’t make item 2 of every process into type integer.)
Interestingly, this works as expected:
tell application "Finder"
set rect to bounds of window of desktop
end tell
tell application "Terminal"
repeat with theWindow in windows
set bounds of theWindow to rect
end repeat
end tell
So I'm very confused.
What am I doing wrong? How can I fix this?
tell application "Finder"
set {0, 0, dtw, dth} to bounds of window of desktop
end tell
tell application "System Events"
repeat with p in (processes where background only is false)
tell p
if name is not in {"Finder"} then
set position of windows to {0, 0}
set size of windows to {dtw, dth}
end if
end tell
end repeat
end tell
Took about 3 seconds on my Mac
Maximizes Terminal windows to fill the screen (except for the 4px area taken up by Dock)
tell application "Finder"
set dtb to bounds of window of desktop
end tell
tell application "System Events"
bundle identifier of processes where background only is false
end tell
repeat with bid in result
tell application id bid
try
if name is not in {"Finder"} then
set (bounds of windows where visible is true) to dtb
end if
end try
end tell
end repeat
Took about 0.3 seconds on my Mac
Doesn't work with all applications like Preview or Reeder
Uses bundle identifiers because a few applications have different process and application names
Resizes Terminal windows so that they have a few pixels empty space above and below them
I use this script to maximize windows:
try
tell application "Finder" to set dtb to bounds of window of desktop
tell application (path to frontmost application as text)
if name is in {"Terminal"} then
error
else
set bounds of window 1 to dtb
end if
end tell
on error
tell application "System Events" to tell (process 1 where it is frontmost)
try
click (button 1 of window 1 where subrole is "AXZoomButton")
end try
end tell
end try
In many applications that don't have basic AppleScript support the zoom button also maximizes windows to fill the screen.
This one take the size of the dock into account. I have mine on the right side of the monitor, but it should be easy to modify to accommodate the dock being on the bottom.
tell application "Finder"
set dtb to bounds of window of desktop
end tell
tell application "System Events" to tell process "Dock"
set dockDimentions to size in list 1
set dockWidth to item 1 of dockDimentions
end tell
tell application "System Events"
bundle identifier of processes where background only is false
end tell
repeat with bid in result
tell application id bid
try
if name is not in {"Finder", "System Preferences", "Notepad", "Terminal", "Activity Monitor"} then
set x to item 1 of dtb
set y to item 2 of dtb
set w to (item 3 of dtb) - dockWidth
set h to item 4 of dtb
set (bounds of windows) to {x, y, w, h}
end if
end try
end tell
end repeat
This eventually did the trick for me:
property blacklist : {"Finder", "Preview", "Console", "AppleScript Editor", "Spotify", "TaskCoach"}
property buttonApps : {"LyX", "Eclipse"}
property buttonMaps : {{name:"LyX", Button:1, pname:"lyx"}, {name:"Eclipse", Button:2, pname:"eclipse"}}
tell application "Finder" to set theBounds to bounds of window of desktop
tell application "System Events"
set bids to bundle identifier of processes where background only is false
end tell
repeat with bid in bids
tell application id bid
if name is not in blacklist then
set appName to name as string
if name is "Terminal" then
set newBounds to {0, 0, (item 3 of theBounds) - 10, item 4 of theBounds}
repeat with theWindow in windows
if visible of theWindow is true then
say appName
set bounds of theWindow to newBounds
end if
end repeat
else if name is not in buttonApps then
repeat with theWindow in windows
if visible of theWindow is true then
set bounds of theWindow to theBounds
end if
end repeat
else if name is in buttonApps then
-- get the buttonNumber
repeat with buttonApp in buttonMaps
if (name of buttonApp as string) is appName then
set theButton to Button of buttonApp
end if
end repeat
tell application "System Events"
repeat with theProcess in (processes where bundle identifier is bid)
try
tell theProcess to tell window 1 to click button theButton
end try
end repeat
end tell
end if
end if
end tell
end repeat
Note that "Spotify" and "Task Coach" are blacklisted because I am not able to resize them by:
setting the window bounds
clicking on the green button
clicking on "Window">"Zoom" in the menu bar
using the ⌘F10 shortcut that I had mapped it to.
If anyone is able to come up with a better solution, I'm all ears