Creating a custom touchbar button to toggle iGPU and dGPU

https://community.folivora.ai/t/latest-version-cannot-run-on-macos-10-15-6/18203Hello, I would like to create a custom touchbar button where a single push can toggle between graphics switching and discrete graphics on the dual graphics macs. I was first playing around with the 'sudo pmset -a gpuswitch 1' in Terminal, but it looks like a root command isn't the ideal way to go and it would not be a toggle switch. Then I was thinking about possibly just recording mouse actions from the keyboard. Does anyone have the thought on the best practice to achieve my desired outcome? Please go easy...I am still new to this app! :smile:

And thank you for your time and help

You could do it by using GUI-scripting with AppleScript and automatically clicking the "Automatic graphics switching" button in Energy Saver. This in fact has been done before, see https://discussions.apple.com/thread/5446761. Here's an AppleScript script I took from there and modified slightly:

tell application "System Preferences"
quit
set current pane to pane id "com.apple.preference.energysaver"
end tell
tell application "System Events"
tell process "System Preferences"
tell window 1
tell group 1 -- automatic graphics switching
tell checkbox 1 -- automatic graphics switching
click
end tell
end tell
end tell
end tell
end tell
tell application "System Preferences"
quit
end tell

You can create a touchbar button, that when pressed runs AppleScript (async in background), and paste the code above. The button will do what you want it to do.

However, this isn't an ideal solution, since it annoyingly messes with System Preferences. It's also possibly brittle against changes to System Preferences.

A better way would be to find a program that can do what you want through shell/AppleScript scripting, then you could create a touchbar button that executes a script when pressed to run the program and accomplish your goal.

A program that sort of can do this is gSwitch, at https://codyschrank.github.io/gSwitch/. After putting that in applications, the line "open -a /Applications/gSwitch.app/Contents/MacOS/gSwitch --args --discrete" launches it with the discrete graphics setting, and "open -a /Applications/gSwitch.app/Contents/MacOS/gSwitch --args --dynamic" launches it with the dynamic switching setting. The thing is, this app is a menubar app, it doesn't close after being launched. You have to plan around that, either by closing the app after a set time period whenever you press the button (implemented via sleeping ~5 seconds), or keeping it open, but closing it first when you press the button again before launching it again.

Here's an AppleScript script that I wrote that seems to implement what you want:

tell application "BetterTouchTool"
set myVar to get_string_variable "GPUSETTING"
end tell
if myVar = "Discrete" then
tell application "BetterTouchTool"
set_persistent_string_variable "GPUSETTING" to "Dynamic"
end tell
try
do shell script "killall gSwitch"
end try
do shell script "open -a /Applications/gSwitch.app/Contents/MacOS/gSwitch --args --dynamic"
else
tell application "BetterTouchTool"
set_persistent_string_variable "GPUSETTING" to "Discrete"
end tell
try
do shell script "killall gSwitch"
end try
do shell script "open -a /Applications/gSwitch.app/Contents/MacOS/gSwitch --args --discrete"
end if

You can create a touchbar button, that when pressed runs AppleScript (async in background), and paste the code above. The button will do what you want it to do. You will also be able to see the state of the GPU in the menubar; gSwitch has a different appearance depending on the setting.

As a bonus, for myself I created a trigger with an AppleScript script that runs every 10 seconds, and whenever it runs, it switches me to the discrete GPU when on AC Power, and to the iGPU when on battery. It uses gSwitch to work. Here's the script:

set myVar to do shell script "pmset -g batt | head -n 1 | cut -d \\' -f2"
tell application "BetterTouchTool"
set myVar2 to get_string_variable "ENERGYSOURCE"
end tell
if myVar ≠ myVar2 then
tell application "BetterTouchTool"
set_persistent_string_variable "ENERGYSOURCE" to myVar
end tell
try
do shell script "killall gSwitch"
end try
if myVar = "AC Power" then
do shell script "open -a /Applications/gSwitch.app/Contents/MacOS/gSwitch --args --discrete"
else
do shell script "open -a /Applications/gSwitch.app/Contents/MacOS/gSwitch --args --dynamic"
end if
end if