Last active
January 1, 2021 02:41
-
-
Save c4710n/54084b1a39567f3a0890e3dcb2b6e04f to your computer and use it in GitHub Desktop.
macOS: position window with builtin utilities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env osascript | |
# | |
# Usage: | |
# $ ./position-window.applescript <position> | |
# Available postions: | |
# - left | |
# - right | |
# - full | |
# - center | |
# | |
# Note: | |
# Currently, I have no idea about how to get the actived display. | |
# Because of that, this script supports one display only. | |
# | |
# References: | |
# + https://daringfireball.net/2006/12/display_size_applescript_the_lazy_way | |
# + http://stackoverflow.com/questions/5292204/macosx-get-foremost-window-title | |
# + https://github.com/1MikeMakuch/growwin/blob/6dc53c9f07b6e1ad397e09976705a12ccc633085/GrowLeft.scpt#L48 | |
on run argv | |
global _desktopWidth, _desktopHeight | |
global _frontApp, _frontAppName | |
global _gap | |
set _gap to 15 | |
tell application "Finder" | |
set _desktopSize to bounds of window of desktop | |
set _desktopWidth to item 3 of _desktopSize | |
set _desktopHeight to item 4 of _desktopSize | |
end tell | |
tell application "System Events" | |
set _frontApp to first application process whose frontmost is true | |
set _frontAppName to name of _frontApp | |
end tell | |
-- the first argument passed from CLI | |
set argv1 to item 1 of argv | |
if argv1 is "left" then | |
set position to leftPosition(_desktopWidth, _desktopHeight, _gap) | |
else if argv1 is "right" then | |
set position to rightPosition(_desktopWidth, _desktopHeight, _gap) | |
else if argv1 is "full" then | |
set position to fullPosition(_desktopWidth, _desktopHeight, _gap) | |
else if argv1 is "center" then | |
set position to centerPosition(_desktopWidth, _desktopHeight, _gap) | |
else | |
beep | |
display alert "Position window with unknown position, exiting" | |
return | |
end if | |
set x to item 1 of position | |
set y to item 2 of position | |
set width to item 3 of position | |
set height to item 4 of position | |
positionCurrentWindow(_frontAppName, x, y, width, height) | |
end run | |
on positionCurrentWindow(appName, x, y, width, height) | |
tell application "System Events" to tell process appName | |
-- The trick here is that you can't rely on "window 1" to be the one you're after, | |
-- So let's filter the UI elements list by subroles. | |
-- Emacs return a a total bogus AXTextField:AXStandardWindow, but we can stil work with it | |
set theWindows to (every UI element whose subrole is "AXStandardWindow") | |
-- For Activity Monitor (others?) | |
if theWindows is {} then set theWindows to (every UI element whose subrole is "AXDialog") | |
if theWindows is {} then | |
beep | |
return | |
end if | |
set theWindow to (first item of theWindows) | |
set position of theWindow to {x, y} | |
set size of theWindow to {width, height} | |
end tell | |
end positionCurrentWindow | |
on leftPosition(desktopWidth, desktopHeight, gap) | |
set width to (desktopWidth - 3 * gap) / 2 | |
set height to desktopHeight - 2 * gap | |
set x to gap | |
set y to gap | |
return {x, y, width, height} | |
end leftPosition | |
on rightPosition(desktopWidth, desktopHeight, gap) | |
set width to (desktopWidth - 3 * gap) / 2 | |
set height to desktopHeight - 2 * gap | |
set x to width + 2 * gap | |
set y to gap | |
return {x, y, width, height} | |
end rightPosition | |
on fullPosition(desktopWidth, desktopHeight, gap) | |
set width to desktopWidth - 2 * gap | |
set height to desktopHeight - 2 * gap | |
set x to gap | |
set y to gap | |
return {x, y, width, height} | |
end fullPosition | |
on centerPosition(desktopWidth, desktopHeight, gap) | |
set width to desktopWidth * 0.67 - gap | |
set height to desktopHeight * 0.85 | |
set x to desktopWidth * 0.33 | |
set y to gap | |
return {x, y, width, height} | |
end centerPosition |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment