Set Mac application window bounds from Terminal? - terminal

Can the bounds of a Mac application window be set directly from Terminal?
I use this Applescript (called by keystroke handler Spark) all day long, varied per application –
set bounds of window 1 to {50, 50, 1200, 700}
Forklift 3.3.1 does not handle Applescript, and I have not found a way to do this using tell application "System Events" etc.
Internet search turns up nothing useful, but is there not a simple Terminal command like Applescript's set bounds that can do this?
Thank you.

This AppleScript code works for me using the latest version of macOS Mojave.
set frontMostApp to (path to frontmost application)
tell application "Finder" to set appName to name of (get properties of frontMostApp)
set bounds of window 1 of application appName to {50, 50, 1200, 700}
Here is a different version using only System Events
tell application "System Events" to tell window 1 of (process 1 where it is frontmost)
try
set position to {50, 50}
set size to {1200, 700}
end try
end tell

Related

How to get Application Name To Call from PID in Mac AppleScript

There is a script that lets you resize any app in mac. This is the code:
set theApp to "Application Name"
set appHeight to 1080
set appWidth to 1920
tell application "Finder"
set screenResolution to bounds of window of desktop
end tell
set screenWidth to item 3 of screenResolution
set screenHeight to item 4 of screenResolution
tell application theApp
activate
reopen
set yAxis to (screenHeight - appHeight) / 2 as integer
set xAxis to (screenWidth - appWidth) / 2 as integer
set the bounds of the first window to {xAxis, yAxis, appWidth + xAxis, appHeight + yAxis}
end tell
I want to change the size of a java application opened by a launcher. When I insert the name of any app, it works. However when I insert the name of the app that I want to resize it doesn't work. I know the process id of the app that I want to resize. Is there a way I can change this line set theApp to "Application Name" to use PID instead of Application name?
Thanks.
Not all apps are AppleScript scriptable and some that are do not support the bounds property, they use position property and size property. Also, sometimes you'll need System Events to position and size an app's window.
I use a keyboard shortcut assigned in FastScripts with the following example AppleScript code to automatically adjust the frontmost app's window. You can adjust the code to suite your needs.
If the frontmost app can't use the bounds property it silently errors, and then System Events does it.
tell application "System Events"
set frontmostProcess to name of process 1 whose frontmost is true
end tell
try
tell application frontmostProcess
set bounds of window 1 to {0, 22, 1136, 844}
end tell
on error
tell application "System Events" to tell application process frontmostProcess
set position of window 1 to {0, 22}
set size of window 1 to {1136, 822}
end tell
end try
Note: I am not affiliated with the developer of FastScript, just a satisfied user. It's also free for the first ten keyboard shortcuts.

How to resize Visual Studio Code window with Automator?

I'm trying to do a screencast and for that, I want to record the VSCode window at the same size every time. For that I've tried to use an Automator script to resize the window. It works with all the applications that I've tested but not with VSCode.
This is the script:
(* This AppleScript will resize the current application window to the height specified below and center it in the screen. Compiled with code from Natanial Wools and Amit Agarwal *)
set the_application to (path to frontmost application as Unicode text)
set appHeight to 720
set appWidth to 1280
tell application "Finder"
set screenResolution to bounds of window of desktop
end tell
set screenWidth to item 3 of screenResolution
set screenHeight to item 4 of screenResolution
tell application the_application
activate
reopen
set yAxis to (screenHeight - appHeight) / 2 as integer
set xAxis to (screenWidth - appWidth) / 2 as integer
set the bounds of the first window to {xAxis, yAxis, appWidth + xAxis, appHeight + yAxis}
end tell
And this is the error that happens when I try to resize the VSCode. Does anyone know what this error could be? Or does anyone know any other way to enforce the window size?
The bounds property and the window element only exist for applications that are scriptable. Most applications, including Microsoft Visual Studio Code, are not scriptable, so your current script will not work for any of these.
To manipulate the window of a non-scriptable application, you need to script the UI using System Events:
tell application "System Events"
set [[screenW, screenH]] to process "Finder"'s scroll areas's size
tell (the first process where it is frontmost)
set [[null, menuH]] to the size of its menu bars
tell the front window
set [appW, appH] to its size
set its position to [¬
(screenW - appW) / 2, ¬
(screenH - appH + menuH) / 2]
end tell
end tell
end tell

How to set a window's index to last (furthest back) in applescript

I've seen a lot of posts for how to send a window to the front in applescript, but I want to be able to send it to the back. How do I write an applescript that will do this?
Maybe you don't actually need to move any windows. Maybe you can just hide your application so your window isn't showing. Since you don't want your window on the top then it's probably OK to just hide your application. It continues running and does its thing but its window doesn't cover any other windows.
Just change "Safari" to the name of your application.
set myAppName to "Safari"
tell application myAppName to activate
tell application "System Events"
-- wait until your application comes forward and then hide it
repeat
set p to first process whose frontmost is true
if name of p is myAppName then
set visible of p to false -- hide your application
exit repeat
end if
delay 0.2
end repeat
end tell
EDIT: if hiding your app doesn't work then you could just keystroke command-tab which is the application switcher command. Basically your app will come to the front and then the keystroke will make the previously frontmost application come to the front. So your window won't go all the way back but it won't be in the front. Maybe that will work.
set myAppName to "Safari"
tell application myAppName to activate
tell application "System Events"
-- wait until your application comes forward
repeat
set p to first process whose frontmost is true
if name of p is myAppName then exit repeat
delay 0.2
end repeat
-- use the application switcher to bring the previously frontmost application forward
keystroke tab using command down
end tell
Something like set index to 999 doesn't seem to work, but set index to (count windows) does:
tell application "TextEdit"
set index of window 1 to (count windows)
end tell
You might also raise all other windows:
tell application "System Events" to tell process "TextEdit"
repeat with w in windows 2 thru -1
perform action "AXRaise" of w
end repeat
end tell
This will move the front finder window to the back...
tell application "Finder" to set index of front Finder window to (count Finder windows)
I have not used "openFrameWorks" so I am not sure of how it works…
But rather than reinvent the wheel with Applescript.
Can you not set the window level in "openFrameWorks"
In xcode/Objective - c I would use the NSWindow Window Levels constants.
To set a normal window:
[awindow setLevel: NSNormalWindowLevel];
But set a window below other normal windows:
[awindow setLevel: NSNormalWindowLevel - 1000];
This will insure the window is always below any normal applications windows. Even when I click on it or drag it. It stays behind other windows.

Resizing all windows of all running applications

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

Embed external application inside a Cocoa SplitView

I would like to have an application under Mac OS X that enables me to have Sublime Text 2 and a terminal (for showing test result, run grunt tasks and so on) in the same fullscreen window. I couldn't find an application whith this behaviour and I think of reproducing it myself with cocoa split view.
I would like to know if it's possible and, if yes, how can I start implementing it
Thank you
You can't create a new application from 2 other applications. It won't work. However you can use applescript to make it easy for you to position these windows as you want.
As an example I'll use Safari and Terminal as my 2 applications. Open them and place them on the screen as you want them to appear. I opened each window large and positioned them side-by-side. Then I ran this applescript to get their window size and position properties...
tell application "System Events"
tell process "Safari"
set safariSize to size of window 1
set safariPosition to position of window 1
end tell
tell process "Terminal"
set terminalSize to size of window 1
set terminalPosition to position of window 1
end tell
end tell
return {safariSize, safariPosition, terminalSize, terminalPosition}
Then I copy/pasted the result from that script into the "theValues" variable in this script. Now whenever I want I can run this script to recreate those window positions.
set theValues to {{1001, 1025}, {0, 22}, {613, 1024}, {1003, 22}}
tell application "Safari" to activate
tell application "Terminal" to activate
tell application "System Events"
tell process "Safari"
set size of window 1 to item 1 of theValues
set position of window 1 to item 2 of theValues
end tell
tell process "Terminal"
set size of window 1 to item 3 of theValues
set position of window 1 to item 4 of theValues
end tell
end tell
I hope that helps. Good luck.

Resources