4

I have a weird setup for my home office that allows me to switch from a standing desk to a sitting desk. The only problem is that when I alternate positions, my laptop's external monitor switches sides. (When standing it is off to the left of my laptop, when sitting it is on the right). At the moment, every time I go from sitting to standing, or vise-versa I have to go into System Preferences -> Displays -> Arrangement and rearrange them. What I would love is some sort of terminal command that moves the 2nd monitor relative to first one. Doesn't matter how long the command is since I can just alias it.

1
  • It might be possible to use an Applescript GUI script and then call it from the command line using osascript
    – JMY1000
    Commented May 11, 2016 at 18:04

2 Answers 2

4
+50

I wrote a small C program to accomplish this, as this cannot be done any other way effectively.

You'll need Xcode installed to compile it.

https://github.com/stnvh/cgorigin


#import <Foundation/Foundation.h>
#import <ApplicationServices/ApplicationServices.h>

#define MAX_DISPLAYS 10

static CGDisplayCount dispCount = MAX_DISPLAYS;
static CGDirectDisplayID dispOnline[MAX_DISPLAYS];

int main(int argc, const char * argv[]) {
    CGDisplayCount dispOnlineCount;
    CGDisplayErr errActive = CGGetOnlineDisplayList(dispCount, dispOnline, &dispOnlineCount);

    CGDisplayConfigRef configRef;
    CGError err = CGBeginDisplayConfiguration(&configRef);

    if(!argv[1]) {
        printf("usage: [-l | --list] [[-o | --origin] x y index] \n");
        return 1;
    }

    for(int i = 0; i < dispOnlineCount; i++) {
        if(dispOnline[i]) {
            int dispWidth = CGDisplayPixelsWide(dispOnline[i]);
            int dispHeight = CGDisplayPixelsHigh(dispOnline[i]);
            CGPoint dispOrigin = CGDisplayBounds(dispOnline[i]).origin;

            if(strcmp(argv[1], "--list") == 0 || strcmp(argv[1], "-l") == 0) {
                printf("display %d: %dx%d %ldx%ld\n", i, dispWidth, dispHeight, (long)dispOrigin.x, (long)dispOrigin.y);
            }

            if(strcmp(argv[1], "--origin") == 0 || strcmp(argv[1], "-o") == 0) {
                int posX = dispOrigin.x;
                int posY = dispOrigin.y;
                int dispInd = 1;

                if(argv[2]) {
                    posX = strtol(argv[2], NULL, 0);
                }
                if(argv[3]) {
                    posY = strtol(argv[3], NULL, 0);
                }
                if(argv[4]) {
                    long _dispInd = strtol(argv[4], NULL, 0);

                    if(_dispInd < dispOnlineCount) {
                        dispInd = _dispInd;
                    }
                }

                if(dispInd == i) {
                    err = CGConfigureDisplayOrigin(configRef, dispOnline[i], posX, posY);
                }
            }
        }
    }

    err = CGCompleteDisplayConfiguration(configRef, kCGConfigurePermanently);
    if(err != 0) NSLog(@"Error with applying configuration: %d\n", err);

    return 1;
} 

Save to a file called main.m, then run:

clang -Wall -framework Foundation -framework ApplicationServices main.m -o cgorigin

Example (from Github):

assuming we have two monitors connected, both at 1920x1080

cgorigin --origin -1920 0 # positions the second monitor to the left of the main display

cgorigin --origin 0 0 # positions the second monitor to the right of the main display

cgorigin --origin -1920 1080 0 # positions the first monitor below the second display

1
  • Impressive! Looking into this...
    – Zack
    Commented May 12, 2016 at 23:21
1

I wrote a free terminal tool called displayplacer that let's you describe your layout and re-apply that same layout. It will let you set up profiles for changing the resolution, rotation, and positioning of your monitors.

For example, he's my 4 monitor setup profile. I have this command tied to a hotkey using BetterTouchTool. displayplacer "id:A46D2F5E-487B-CC69-C588-ECFD519016E5 res:3840x2160 hz:60 color_depth:8 scaling:off origin:(0,0) degree:0" "id:F466F621-B5FA-04A0-0800-CFA6C258DECD res:1440x900 color_depth:4 scaling:on origin:(-1440,1437) degree:0" "id:4C405A05-8798-553B-3550-F93E7A7722BB res:1440x2560 color_depth:8 scaling:off origin:(3840,-363) degree:270" "id:18173D22-3EC6-E735-EEB4-B003BF681F30 res:1920x1200 color_depth:8 scaling:off origin:(960,-1200) degree:0"

It's also available via Homebrew brew tap jakehilborn/jakehilborn && brew install displayplacer

You must log in to answer this question.

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