22

I use different screen resolutions based on the activity I'm doing during the day.
For example when I'm coding I prefer to have more space available.
Is it possible to associate a keyboard shortcut to change the scaled display resolution ?
(see the attached screenshot) enter image description here

1
  • display_manager.py worked for me. I created a Workflow using Automator and assigned a keyboard shortcut via System Preferences > Keyboard > Shortcuts. (My command: /path/to/display_manager.py res 1920 1080 60)
    – rinogo
    Commented Jun 3, 2020 at 1:04

12 Answers 12

18

Yes you totally can achieve this without running additional apps. On my system I created two different scripts. One script for adjusting the display resolution higher and one adjusting display resolution lower. On my system I just enabled both scripts as dictation commands but if you create a new Service through Automator, you can assign keyboard shortcuts to those services..

First, here are the two scripts I started with.

This one is for making the display resolution higher: if my display resolution is already at the default position

enter image description here

tell application "System Preferences"
    reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "Built-in Retina Display"
    click radio button "Scaled" of radio group 1 of tab group 1
    click radio button 4 of radio group 1 of group 1 of tab group 1
end tell
quit application "System Preferences"

Running that script will result in this:

enter image description here

This next script is for making the display resolution lower: if my display resolution is not set at the default setting

tell application "System Preferences"
    reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "Built-in Retina Display"
    click radio button "Scaled" of radio group 1 of tab group 1
    click radio button 3 of radio group 1 of group 1 of tab group 1
end tell
quit application "System Preferences"

Once I made sure both scripts work correctly, I then opened up Automator and created a new service for the display resolution higher and added the appropriate script as shown in the following image. I saved this file as rez_higher.workflow

enter image description here

From here, I opened up system preferences/keyboard/shortcuts/services. I located that new service I created and assigned it a keyboard shortcut

enter image description here

After this, just follow the same procedures to create a new workflow and service for the display resolution lower


UPDATE: On OS Ventura, System Preferences.app is now System Settings.app so all of the code above will not work. However, this following AppleScript code will work.

try
    if application "System Settings" is running then ¬
        do shell script "killall 'System Settings'"
end try

repeat until application "System Settings" is not running
    delay 0.1
end repeat

tell application "System Settings"
    reveal anchor "resolutionSection" of ¬
        pane id "com.apple.Displays-Settings.extension"
end tell

tell application "System Events" to tell process "System Settings"
    repeat until exists of table 1 of scroll area 1 of group 1 of scroll area 2 ¬
        of group 1 of group 2 of splitter group 1 of group 1 of window "Displays"
        delay 0.1
    end repeat
    
    -- row 3 on my MBP is 1440 x 900
    set selected of row 3 of table 1 of scroll area 1 of group 1 of scroll area 2 ¬
        of group 1 of group 2 of splitter group 1 of group 1 of window ¬
        "Displays" to true
end tell

tell application "System Settings" to quit
6
  • 1
    Thanks, this worked as I wanted. I've also found a workflow where you can toggle the resolution change in the same script here
    – david-e
    Commented Dec 3, 2016 at 6:00
  • 1
    This is amazing. I follow most of it. Where can one find details such the name of the anchor being 'displayDisplayTab'? I'd like to develop something similar to set (and unset) the desktop color. All/any details are very welcome. Commented Dec 20, 2019 at 17:03
  • 2
    That script in example is thrown error: error "System Events got an error: Can’t get tab group 1 of window \"Built-in Retina Display\" of process \"System Preferences\". Invalid index. Is it broken by any OSX update? Commented Jan 22, 2020 at 21:08
  • 1
    @JakubBoucek, see my fix posted as a new answer
    – Zade
    Commented Apr 7, 2020 at 4:42
  • Thank you SO MUCH to wch1zpink and @Zade! This is exactly what I was hoping for! I will use this 10+ times/day because whenever I screenshare with coworkers, I need to use a lower resolution.
    – Ryan
    Commented Nov 19, 2020 at 16:39
10

I wrote the free command line tool displayplacer to change resolutions/rotations for single or multi-monitor desktops. You can trigger a "profile" (example below) via a keyboard shortcut with Automator like wch1zpink explained, BetterTouchTool, etc.

displayplacer 'id:69731906 res:1440x900 scaling:on origin:(0,0) degree:0'

3
  • Could you explain the command in the answer (what is id for example, does it change per display)? Is it possible to ask for a higher / lower resolution with it?
    – Sampo
    Commented Aug 25, 2023 at 6:37
  • @sampo Each display has a unique ID, yes you can alter the resolution to be higher or lower. You can alter all of the options shown. There are instructions in the README.md of the displayplacer repo that show how to list all of the options available with the program. Commented Aug 31, 2023 at 14:51
  • Awesome + big thanks! Coming from linux, this is so much easier and concise to use than those apple scripts. Especially this can easily move my external screens position around (which constantly have different random positions after reconnecting with the dock) in the same command <3
    – exic
    Commented Feb 6 at 19:26
8

Broken again with macOS Sequoia, because the UI element is now:

UI element 1 of group 1 of scroll area 2 of group 1 of list 2 of splitter group 1 of list 1 of window "Displays"

My shortcut no longer toggles between resolutions. Instead I have a shortcut for each resolution, so I posted my latest script (working on macOS 15.1.1) in a new answer below (https://apple.stackexchange.com/a/477031/27373)


Proposed Fix for Zade's change for the Browser UI System Preferences in 13.0.1, the Shortcut didn't work anymore for me in Ventura 13.2 because of an error around the value of attribute "AXAttributedDescription" part

What I use in Ventura 13.2 now:

do shell script "open x-apple.systempreferences:com.apple.preference.displays"
tell application "System Events"
    tell application process "System Settings"
        repeat until (exists UI element 1 of group 1 of scroll area 2 of group 1 of group 2 of splitter group 1 of group 1 of window 1)
            delay 0.1
        end repeat
        tell window 1 #"Displays"
            set displayOptions to UI element 1 of group 1 of scroll area 2 of group 1 of group 2 of splitter group 1 of group 1
            set StandardRes to button 4 of displayOptions
            set MoreSpaceRes to button 5 of displayOptions
            
            if focused of StandardRes is false then
                click StandardRes
            else
                click MoreSpaceRes
            end if
        end tell
    end tell
end tell
quit application "System Settings"

This switches between the Standard resolution and the "More Space" one ("Mehr Fläche" in German) and should be system language independent.


Fix for wch1zpink's answer on macOS 13.0.1, thanks to the UI Browser app:

do shell script "open x-apple.systempreferences:com.apple.preference.displays"
tell application "System Events"
    tell application process "System Settings"
        repeat until (exists UI element 1 of group 1 of scroll area 2 of group 1 of group 2 of splitter group 1 of group 1 of window "Displays")
            delay 0.1
        end repeat
        tell window "Displays"
            set displayOptions to UI element 1 of group 1 of scroll area 2 of group 1 of group 2 of splitter group 1 of group 1
            set theButton to (first button of displayOptions whose value of attribute "AXAttributedDescription" contains "Selected")
            if help of theButton is "2560 × 1440" then
                click button 1 of displayOptions
            else
                click button 3 of displayOptions
            end if
        end tell
    end tell
end tell
quit application "System Settings"

Fix on macOS 12.0.1:

tell application "System Preferences"
    reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events"
    tell application process "System Preferences"
        repeat until (exists radio button "Scaled" of radio group 1 of group 1 of window "Displays")
            delay 0.1
        end repeat
        tell window "Displays"
            set isScaled to value of radio button "Scaled" of radio group 1 of group 1
            if isScaled = 0 then
                click radio button "Scaled" of radio group 1 of group 1
                click button 1 of UI element 3 of group 1
            else
                click radio button "Default for display" of radio group 1 of group 1
            end if
        end tell
    end tell
end tell
quit application "System Preferences"

Fix on macOS 10.15.4:

tell application "System Preferences"
    reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "Built-in Retina Display"
    set isScaled to value of radio button "Scaled" of tab group 1
    if isScaled = 0 then
        click radio button "Scaled" of tab group 1
        click radio button 1 of radio group 1 of group 1 of tab group 1
    else
        click radio button "Default for display" of tab group 1
    end if
end tell
quit application "System Preferences"
5
  • I still have the same error. error System Events got an error: Can’t get radio button \"Scaled\" of tab group 1 of window \"Built-in Retina Display\" of process \"System Preferences\"." number -1728 from radio button "Scaled" of tab group 1 of window "Built-in Retina Display" of process "System Preferences" With the prior code, the number is 1719. Just changed the number
    – leon
    Commented Jul 3, 2020 at 17:29
  • @leon use the UI Browser app to get the name of the buttons in your version of macOS.
    – Zade
    Commented Nov 1, 2021 at 18:38
  • It works fantastic (Ventura version); however, how can I modify it to set it for a build-in-display only when I have an external monitor connected? error "System Events got an error: Can’t get button 3 of static text \"Use as\" of group 1 of scroll area 2 of group 1 of group 2 of splitter group 1 of group 1 of window \"Displays\" of application process \"System Settings\". Invalid index." number -1719 from button 3 of static text "Use as" of group 1 of scroll area 2 of group 1 of group 2 of splitter group 1 of group 1 of window "Displays" of application process "System Settings" Thanks! Commented Mar 27, 2023 at 14:31
  • 1
    Your Ventura script changes to MoreSpaceRes for me but not back to StandardRes on Sonoma. Any ideas?
    – oscu0
    Commented Jan 22 at 10:31
  • 1
    The toggling doesn't work on Sonoma but this was the only script that actually changed the resolution. Thank you!
    – cdeutsch
    Commented Jul 8 at 15:20
4

What works for me in 2022 on macOS 12.1 on MacBook Pro

To have a single keyboard shortcut that toggles between 2 resolutions:

  1. Automator > File > New > Quick Action > Choose
  2. Search for "Run AppleScript" and double-click the result.
  3. Replace the default script code with what I provide below.
  4. Try clicking the Run button a couple times to see if the toggling works.
  5. Save as "toggle_display_resolution". (Later, if you ever want to edit it, you'll open /Users/your_username/Library/Services/toggle_display_resolution.workflow in Automator).
  6. Close Automator.
  7. System Preferences > Keyboard > Shortcuts > Services
  8. Assign a keyboard shortcut to the new service that you created (which will probably be at the bottom of the list).

By the way, you may need to edit your "Security & Privacy" > Accessibility. See answer.

on run {input, parameters}
    
    # https://apple.stackexchange.com/a/436069/53510
    tell application "System Preferences"
        reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
    end tell
    tell application "System Events"
        tell application process "System Preferences"
            repeat until (exists radio button "Scaled" of radio group 1 of group 1 of window "Displays")
                delay 0.1
            end repeat
            tell window "Displays"
                set isScaled to value of radio button "Scaled" of radio group 1 of group 1
                if isScaled = 0 then
                    click radio button "Scaled" of radio group 1 of group 1
                    # button '5' means highest resolution (smalled font):
                    click button 5 of UI element 3 of group 1
                else
                    click radio button "Default for display" of radio group 1 of group 1
                end if
            end tell
        end tell
    end tell
    # The next line is optional and could be commented out by prepending with a hash (#).
    quit application "System Preferences"
    
    return input
end run

P.S. Many thanks to wch1zpink and Zade, whose answers led to mine. Upvote theirs too.

P.P.S. I'm curious to learn whether I could more easily share this Quick Action / Service.

1
3

Oct 2022 macOS 12.6 Solution

Adding another solution to the list. Imron Gamidli's solution got me the closest to what I wanted with the toggle behavior.

Here is my script which I've added as a Raycast command so that I can trigger from raycast or assign a keyboard shortcut.

#!/usr/bin/osascript

# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title Toggle Resolution
# @raycast.mode silent

# Optional parameters:
# @raycast.icon 🤖

set monitor to 2
tell application "System Preferences"
    activate
    set the current pane to pane id "com.apple.preference.displays"
    delay 2
    tell application "System Events"
        tell window "Displays" of application process "System Preferences"
            click button "Display Settings…"
            delay 2
            click row monitor of outline 1 of scroll area 1 of sheet 1
            click radio button "Scaled" of radio group 1 of sheet 1
            try
                set selected_button to button "Resolution5, Selected" of UI element 6 of sheet 1
                click button "Resolution1" of UI element 6 of sheet 1
            on error
                click button "Resolution5" of UI element 6 of sheet 1
            end try
            delay 0.5
            click button "Done" of sheet 1
        end tell
    end tell
end tell
# The next line is optional and could be commented out by prepending with a hash (#).
delay 2
quit application "System Preferences"
8
  • Thanks for sharing this since my answer apple.stackexchange.com/a/436069/53510 doesn't work anymore. I can't get your answer working either. Syntax Error: System Events go an error: Can't get button "Resolution5" of UI element 6 of sheet 1 of window "Displays" of application process "System Preferences".
    – Ryan
    Commented Oct 31, 2022 at 14:45
  • @Ryan What os version are you on? This is working for me on 12.6 and the only version I've tested it on. I have noticed some issues occasionally, I think when the machine is under load. You can try playing with the delays and see if a longer delay helps. Commented Nov 2, 2022 at 19:29
  • Thanks. I'm on 12.6. Today I see that I'm eligible to download 13.0, so maybe I'll try upgrading within a week or so. Even with longer delays, I'm still getting the error I mentioned in my previous comment. Out of curiosity, how did you know how to write this script? How can I figure out the names and numbers of each area / element on the screen? Thanks!!
    – Ryan
    Commented Nov 2, 2022 at 20:07
  • 1
    @Ryan Hmm, not sure then. Its still working on my machine. I would guess that 13.0 will break the script as there was a redesign of the System Preferences renaming it to System Settings and redesigning it. As far as how to write the script, I'm super inexperienced in apple script. I tried a bunch of the options here, guessed alot, search the automators forum, and found that you can get some of the element names through the Accessibility Inspector tool. There is some breakpoint and logging support too you can use to print out elements. If anyone else has advice here, I'm also keen to learn. Commented Nov 3, 2022 at 18:53
  • I don't think I've tried the Accessibility Inspector tool yet. Thanks.
    – Ryan
    Commented Nov 4, 2022 at 11:24
2

As of macOS 12.2.1 with the introduction of Shortcuts, you no longer need a keyboard shortcut anymore. Anyway, many thanks to Ryan who provided the basis of my code. Here it goes:

    on run {input, parameters}
        
        # https://apple.stackexchange.com/a/436069/53510
        tell application "System Preferences"
            activate
            reveal anchor "displaysDisplayTab" of pane "com.apple.preference.displays"
            delay 2 #Make longer if needed
            tell application "System Events"
                tell application process "System Preferences"
                    tell window 1
                        click button 1 #Monitor settings
                        delay 0.7 #Make longer if needed
                        select row 2 of outline 1 of scroll area 1 of sheet 1 #Row=monitor number
                        click radio button 2 of radio group 1 of sheet 1 #Select "Scaled"
                        click button 2 of UI element 6 of sheet 1 #Select resolution
                        click button 2 of sheet 1 #Done
                        click button 4 #Close System Preferences
                    end tell
                end tell
            end tell
        end tell
        return input
    end run

Delays are needed because of window opening time, otherwise the indexing breaks. If it still breaks, just extend the delays. For the row number, if you want to influence your e.g. 3rd monitor, write "row 3" instead. If you're making a second one to increase your resolution and scaled is thus already selected, you can get rid of that line.

For MacOS 12.3, change button 4 to button 5

1

This worked for me on Monterey 12.3.1 to change resolution on my 2nd monitor from the list. I will transfer this script to automator to change resolution with keyboard

set res to 3
set monitor to 2
tell application "System Preferences"
    activate
    set the current pane to pane id "com.apple.preference.displays"
    delay 2
    tell application "System Events"
        tell window "Displays" of application process "System Preferences"
            click button "Display Settings…"
            delay 2
            click row monitor of outline 1 of scroll area 1 of sheet 1
            click radio button "Scaled" of radio group 1 of sheet 1
            click button res of UI element 6 of sheet 1
        end tell
    end tell
end tell
1
  • Thanks for sharing this since my answer apple.stackexchange.com/a/436069/53510 doesn't work anymore. I can't get your answer working either. Syntax Error: System Events go an error: Can't get button 3 of UI element 6 of sheet 1 of window "Displays" of application process "System Preferences". Invalid index.
    – Ryan
    Commented Oct 31, 2022 at 14:47
1

I was using the AppleScript version that toggles resolutions for Ventura, and it worked well until the latest Sonoma update (14.2). Apple removed the "focused" property for the display resolution buttons. I altered the toggle switch to look for the display warning text that appears in the Display settings window when not in default resolution to trigger the toggle. This version works for me - toggle between the "Default" and one-notch bigger text resolutions.

This is the code in Shortcuts:

on run {input, parameters}
##This script toggles resolution between "default" and "larger text" on the internal display of MacBook.
##Based upon: https://apple.stackexchange.com/questions/263162/is-it-possible-to-change-display-resolution-with-a-keyboard-shortcut
##Modified on June 16, 2022; Modified on December 18 2024 to work on MacOS 14.2 
##update to 14.2 broke the script. "focused" property no longer working.

do shell script "open x-apple.systempreferences:com.apple.preference.displays"
tell application "System Events"
    tell application process "System Settings"
        repeat until (exists UI element 1 of group 1 of scroll area 2 of group 1 of list 2 of splitter group 1 of list 1 of window 1)
            delay 0.1
        end repeat
        tell window 1 #"Displays"
            set displayOptions to UI element 1 of group 1 of scroll area 2 of group 1 of list 2 of splitter group 1 of list 1
            set StandardRes to button 4 of displayOptions
            set BiggerRes to button 3 of displayOptions
            
            ##In Sonoma 14.2, Apple removed the focussed attribute, so need to look at text warning field instead of button state
            ##if focused of StandardRes is false then
            ##  click StandardRes
            ##else
            ##  click BiggerRes
            ##end if
            
            if exists static text 1 of group 1 of scroll area 2 of group 1 of list 2 of splitter group 1 of list 1 then
                click StandardRes
            else
                click BiggerRes
            end if
        end tell
    end tell
end tell
quit application "System Settings"
return input
end run

Hope this helps you!

1
  • Sadly, this warning text doesn't seem to exist anymore.
    – threed
    Commented Jul 10 at 22:14
0

You can use this app called SwitcherResX (http://www.madrau.com/srx_download/download.html) where they have option to change resolution with Keyboard shortcut or based on application you use. They have a trial to try.enter image description here

1
  • Thanks. I was looking for something at system level without running additional apps. But I will keep your suggestion in consideration as alternative solution!
    – david-e
    Commented Dec 1, 2016 at 18:26
0

The application EasyRes (free on the Mac app store) works for me.

I had spent an hour rebooting and resetting the NVRAM, trying frantically to get my 2006-vintage 30" Apple Cinema display back to full resolution, to no avail.

This fix is not "sticky" -- when I reboot, I'm back to 1280x800 and I have to use EasyRes again, but I reboot only ever couple of months, so this is workable.

1
  • Welcome to Ask Different. How is this used with a key shortcut? Should we get it on another question that’s asking for helper apps if it’s not scriptable to a key press?
    – bmike
    Commented Dec 18, 2023 at 19:25
0

Here's a 2024 update to my original answer that no longer works on macOS Sequoia. Also, instead of a toggle, I now use four separate shortcuts/hotkeys, one for each resolution. This script clicks the fourth resolution in the display thumbnails:

do shell script "open x-apple.systempreferences:com.apple.preference.displays"
tell application "System Events"
    tell application process "System Settings"
        repeat until (exists UI element 1 of group 1 of scroll area 2 of group 1 of list 2 of splitter group 1 of list 1 of window "Displays")
            delay 0.1
        end repeat
        tell window "Displays"
            click button 4 of UI element 1 of group 1 of scroll area 2 of group 1 of list 2 of splitter group 1 of list 1
        end tell
    end tell
end tell
quit application "System Settings"

On my setup, "button 4" refers to "More Space". If you want to select the "Larger Text" option, that'd be "button 1". The UI Browser app is really useful to figure out how to target interface elements via AppleScript.

-2

Note @wch1zpink's answer works great, but Big Sur makes some breaking changes to it and requires revisions. This worked for me with an external display so just replace LG ULTRAWIDE with the title on the window.

compress-screen

on run {input, parameters}
    
    activate application "System Preferences"
    tell application "System Events"
        tell process "System Preferences"
            click button "Displays" of scroll area 1 of window "System Preferences"
            delay 0.5
            
            tell tab group 1 of window "LG ULTRAWIDE"
                click radio button "Scaled"
                delay 0.5
                select row 4 of table 1 of scroll area 1
            end tell
        end tell
        delay 1
        quit application "System Preferences"
    end tell
    
    return input
end run

expand-screen

on run {input, parameters}
    
    activate application "System Preferences"
    tell application "System Events"
        tell process "System Preferences"
            click button "Displays" of scroll area 1 of window "System Preferences"
            delay 0.5
            
            tell tab group 1 of window "LG ULTRAWIDE"
                click radio button "Default for Display"
            end tell
        end tell
        delay 0.5
        quit application "System Preferences"
    end tell
    
    return input
end run
1
  • Please explain why and how this works
    – mmmmmm
    Commented Jan 25, 2021 at 22:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .