14

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
    Jun 3, 2020 at 1:04

11 Answers 11

14

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

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
    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. 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? Jan 22, 2020 at 21:08
  • 1
    @JakubBoucek, see my fix posted as a new answer
    – Zade
    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
    Nov 19, 2020 at 16:39
4

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'

4

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

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 for wch1zpink's answer 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"
2
  • 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
    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
    Nov 1, 2021 at 18:38
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"
7
  • 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
    Oct 31 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. Nov 2 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
    Nov 2 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. Nov 3 at 18:53
  • I don't think I've tried the Accessibility Inspector tool yet. Thanks.
    – Ryan
    Nov 4 at 11:24
2

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
1

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.

EDIT: 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
    Oct 31 at 14:47
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
    Dec 1, 2016 at 18:26
0

The application EasyRes (free in the Apple app store) did it for me. I had spent an hour resetting the NVRAM, trying frantically to get my 2006-vintage 30" Apple Cinema display back to full resolution, to no avail. I must have rebooted 25 times. EasyRes took care of it. Thank you EasyRes, I was going nuts!

Update: this 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

Anyone have an AppleScript for Ventura? Tried to use Keyboard Maestro and somehow can't get this going. Have a few apps that don't have font resize as an option and I'd love a quick way to do this and set it back to default fast.

1
-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
    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 .