Eun / DisableMonitor

Easily disable or enable a monitor on your Mac.
1.36k stars 149 forks source link

Quickly disable/enable primary monitor #47

Open benmorrow opened 9 years ago

benmorrow commented 9 years ago

Here's how I use this app:

I have a Macbook and a big external monitor. When I connect the Macbook to the external monitor, I disable the Macbook screen. That way:

Most of the time while using the app, I just want to enable or disable the laptop monitor. I suspect this is a majority use case. Right now the user experience has a few tedious steps:

  1. Click the tray icon
  2. Hover over primary monitor name
  3. Move mouse to the side without moving off of monitor name
  4. Click Disable

    Perhaps this could be simplified.

A keyboard shortcut to enable/disable would be a nice touch. It would make this process one step. The other keyboard shortcuts that I use all the time are:

accessibility keyboard shortcuts

So I propose enable/disable monitor (Shift-Command-8). This would look nice as a top level item in the tray:

tray option disable monitor

arkdelkaos commented 8 years ago

This app can be controlled with a terminal command. There must be a way to assign a terminal command to a keyboard shortcut. Right now I don't have much time, but I'll try it soon :)

brettinternet commented 8 years ago

Were you ever able to figure out assigning a shortcut?

benmorrow commented 7 years ago

I figured out how to use a keyboard shortcut to disable the primary monitor. Follow this quick tutorial to try it yourself.

You will create a Service using the Automator app. The service will execute AppleScript to open the Terminal app and run commands for DisableMonitor. Once you're ready to proceed, let's get started!

Note: I'm writing this in January 2017, running macOS Sierra 10.12.2 and DisableMonitor 1.92. If you've arrived here in the future, please know that commands might have changed. 😁

Open the Automator app.

Create a new Service.

In the Actions Library select Utilities. Drag Run AppleScript into the workflow:

screen shot 2017-01-08 at 9 37 02 pm

Change the Service receives selected dropdown to no input:

screen shot 2017-01-08 at 9 40 57 pm

Replace the current AppleScript code with this:

tell application "Terminal"
    set currentTab to do script "/Applications/DisableMonitor.app/Contents/MacOS/DisableMonitor --list"
    delay 0.4
    set tabText to contents of contents of currentTab
    # display dialog "tabText: " & tabText
    set row1 to paragraph 5 of tabText
    # display dialog "row1: " & row1
    set primaryId to word 1 of row1
    # display dialog "primaryId: " & primaryId
    do script "/Applications/DisableMonitor.app/Contents/MacOS/DisableMonitor --disable " & primaryId in window 1
    delay 4
    close window 1
end tell

Here's what's happening in this code:

  1. The AppleScript instructs the Terminal app to open a new window and run the DisableMonitor --list command. You set the return value of the script to a new variable, currentTab, which represents the current tab or window in Terminal.
  2. You add a delay so that the computer has time to execute that step.
  3. You get the text from the Terminal tab and set the value as a new variable, tabText.

Note: One way to make a single line comment in AppleScript is to prepend "# ". In this code, I've added a few debugging sanity checks to show an alert window with newly set variables. Right now, they are commented out, but you may choose to run them by removing the "# " at the beginning of the line.

  1. The list command for DisableMonitor outputs a nicely formatted block of text (see below). You want to get the ID of the primary monitor. The first step is to retrieve the line of text you're interested in. In AppleScript, each line is called a paragraph. Because of the extra formatting lines, you want to isolate the the fifth paragraph in the text and set that to a new variable, row1.
Last login: Sun Jan  8 21:32:37 on ttys000
Jarvis:~ Ironman$ /Applications/DisableMonitor.app/Contents/MacOS/DisableMonitor --list
 ID         Name
----------- -----------------
 69680128   Color LCD
 441100157  ASUS XV564
----------- -----------------
  1. You isolate the first word in the fifth line and save that as a new variable, primaryId.
  2. You instruct the same Terminal window to run the DisableMonitor --disable command with the ID of your primary monitor.
  3. Finally to clean up, you wait for four seconds to give the computer time to switch display settings and then instruct the Terminal app to close the window.

To test it out, first ensure you have a secondary monitor connected to your Mac and that DisableMonitor is running. Then, Run the script by clicking the button in the top right of the Automator window:

screen shot 2017-01-08 at 10 10 29 pm

You will see the Terminal window pop up, run the code, your monitors will turn off and back on again, and if all goes well, you'll end up with only the external monitor enabled and Terminal window successfully closed.

Note: If Terminal gives you a warning that you're interrupting the DisableMonitor process when it tries to close, you'll just need to add a few more seconds to the final delay in your AppleScript code.

Now that you've verified that the script works, you can set up a global keyboard shortcut.

Navigate to File \ Save in Automator and name your service, "Disable Primary Monitor".

Open the System Preferences app. Navigate to Keyboard \ Shortcuts. In the left pane, select Services. Scroll all the way to the bottom and select Disable Primary Monitor. Click the Add Shortcut button that appears when you select the service. Press your preferred keyboard combination. I use Command-Shift-8.

Note: You want to try to choose a key combination that will not conflict with keyboard shortcuts in your other apps. I chose Command-Shift-8 because it seems related to two other handy shortcuts in macOS: zoom in/out (Option-Command-8) and invert/regular colors (Control-Option-Command-8).

After you've completed the keyboard shortcut, you'll see it added into the table next to Disable Primary Monitor.

Now to test it out, you'll first need to re-enable your primary monitor if it is still disabled from the trial run in Automator. Use the tray icon for DisableMonitor, and select Color LCD > Enable:

screen shot 2017-01-08 at 10 26 33 pm

After you've ensured that the primary monitor is currently enabled, go ahead and try out your keyboard shortcut.

Where to go from here?

I'm excited to finally have this working for my own daily use. If you try it out let me know. I would also be especially keen to hear any optimizations you might have since I am an AppleScript novice.

You might want to also make another service for a keyboard shortcut to enable the primary monitor. To do that, you'd follow all the steps from this tutorial with the minor differences of changing "--disable" to "--enable" in your AppleScript and selecting a different keyboard shortcut in System Preferences.

/cc @arkdelkaos @brettinternet

benmorrow commented 7 years ago

UPDATE: The keyboard shortcuts I detailed in the previous post, did not work reliably for me over time. I think the terminal commands sometimes simply fail to actually disable or enable the monitors. Because of this, I sought out an alternative app. I have now switched to SwitchResX which offers native support for keyboard shortcuts. SwichResX is working flawlessly for me. Here are my keyboard preferences:

screen shot 2017-03-23 at 5 16 51 pm