Toggling F-Keys

I've been looking for a good shortcut for toggling F-Keys on and off but after scouring the web I haven't found anything useful. Any ideas?

I've done it using a macro executing an AppleScript. I'm running Mac OS 10.11 so I don't know if this needs to be adjusted for newer versions of MacOS.

image

The script code:

tell application "System Preferences"
	reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
end tell
tell application "System Events" to tell process "System Preferences"
	click checkbox 1 of tab group 1 of window 1
end tell
quit application "System Preferences"

Thanks for your help! Unfortunately, using your shortcut with Catalina, I get this error:

2019-12-07 16:39:43 text-script:184:231: execution error: System Events got an error: Can’t get window 1 of process "System Preferences". Invalid index. (-1719)
Macro “Toggle KB F Keys” cancelled (while executing Execute AppleScript).

I have no idea what this means. I'm guessing it's an easy fix for someone that knows AppleScript.

It's possible the script won't work in Catalina without adjustments, but the issue could be the three back ticks at the end of the script I posted (```). That was a formatting error on my part. Best you check those aren't in the script you're testing.

(I have edited my initial post so the unnecessary back ticks are no longer there.)

Intuitively I knew that those should probably be deleted so I already deleted them. Must be something else. Oh well, thanks for trying!!

There are a number of people here who are mighty well-skilled with AppleScript. I am not one of them. I'm sure the script I've been using was procured from somewhere online some time ago. Hopefully, one of the strong AppleScript folks here will see this thread and offer a Catalina-friendly solution, or someone with another approach will show up.

Thanks for your help! Much appreciated. I'm guessing you're right about someone else seeing this. :slight_smile:

This works on my High Sierra's arrangement:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

tell application "System Events"
	set wasRunning to count (processes whose name is "System Preferences")
end tell

tell application "System Preferences"
	reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
	delay 1
end tell
tell application "System Events" to tell process "System Preferences"
	click checkbox 1 of tab group 1 of window 1
end tell

if wasRunning = 0 then
	quit application "System Preferences"
end if
1 Like

That worked! I have it running on my desktop Mac which is running Mojave and it seems to work on my laptop as well which is running Catalina. Thanks so much!!

My pleasure!

Didn't know I needed this. But glad to have it. Works on Catalina. Doesn't always seem to fire. Like the idea of the OP who had the confirming display. If it could display which way it toggled would be great. But I'm not delving into AS.

Thank you

I agree. A confirmation (On or Off) would be very useful! After triggering the macro, I find myself checking to see if it actually engaged.

This revision sends a notification of the function key status. If you still find it works only intermittently, try increasing the delay. Tested on High Sierra without issue:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

tell application "System Events"
	set wasRunning to count (processes whose name is "System Preferences")
end tell

tell application "System Preferences"
	reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
	delay 1
end tell
tell application "System Events" to tell process "System Preferences"
	set theCheckbox to checkbox 1 of tab group 1 of window 1
	click theCheckbox
	set checkboxStatus to value of theCheckbox as boolean
	if checkboxStatus is false then
		display notification "Function Keys Off"
	else
		display notification "Function Keys On"
	end if
end tell

if wasRunning = 0 then
	quit application "System Preferences"
end if
1 Like

Beautiful. I'll watch the delay. But the notification will help figure out if it's working.

Fantastic! Works great with Mojave. I haven't tried it with Catalina yet. Thanks. :slight_smile:

If you want to lose the ugliness of GUI scripting, you have a few options:

  1. FunctionFlip (http://kevingessner.com/software/functionflip/) will do what you want, but it is limited to F1-F12, and frequently only on Apple OEM keyboards; it's hit or miss on third party boards. I have it triggered with KM by double-tapping the FN key. Works great.

  2. FNable (https://fnable.com) customizable and app-based switching

  3. Palua (temporarily discontinued); if you can get your hands on an older copy, it was also very slick and fully customizable.

  4. Fluor (https://github.com/Pyroh/Fluor); also very customizable.

  5. FNToggle (https://github.com/nelsonjchen/fntoggle) one-trick pony that you can call from command line or script, KM, etc...

FWIW, you can get the current state with

defaults read "Apple Global Domain" "com.apple.keyboard.fnState"

you can toggle the state with:

defaults write "Apple Global Domain" "com.apple.keyboard.fnState" "1" ## FKeys

defaults write "Apple Global Domain" "com.apple.keyboard.fnState" "0" ## Media/Special

… but it requires a Logout or Reboot to execute, as the special process that looks for this pref cannot be safely quit/restarted to acknowledge the change (as of macOS Sierra; may no longer be true).

Thanks for sharing. Your script works great as is, but I have optimized it somewhat to run faster:

property ptyScriptName : "Toggle the Mac Function Keys On | Off"
property ptyScriptVer : "1.1"
property ptyScriptDate : "2019-12-11 17:50"
property ptyScriptAuthor : "mrpasini" -- optimized by JMichaelTX

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

--tell application "System Events"
--  set wasRunning to count (processes whose name is "System Preferences")
--end tell

set wasRunning to (application "System Preferences" is running) -- returns true/false

tell application "System Preferences"
  reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
  --delay 1
  set isShowing to false
  repeat until isShowing
    delay 0.1
    set isShowing to exists (anchor "keyboardTab" of pane "com.apple.preference.keyboard")
  end repeat
  
end tell
tell application "System Events" to tell process "System Preferences"
  set theCheckbox to checkbox 1 of tab group 1 of window 1
  click theCheckbox
  set checkboxStatus to value of theCheckbox as boolean
  if checkboxStatus is false then
    display notification "Function Keys Off"
  else
    display notification "Function Keys On" sound name "tink" #ADD sound
    
  end if
end tell

--if wasRunning = 0 then
--  quit application "System Preferences"
--end if

if wasRunning is false then
  quit application "System Preferences"
end if

As always, beauty is in the eye of the beholder. I don't find anything "ugly" about @mrpasini's script. It is well written and performs the assigned task.

Sorry for the mistaken aspersions towards the script author; yes, it works beautifully as is for what it is; my reference was meant generally towards any GUI script which requires opening an application that was otherwise closed, background notwithstanding. This sort of toggle shouldn’t require an app to open at all; nor should it require more than one line of code to accomplish (sans desire for notifications), let alone take more than a split second. That’s why the Fluor project is so popular and expanded to include global and app-specific settings. So, yes, it’s an otherwise elegant solution to an ugly problem that shouldn’t even exist, especially from an Accessibility standpoint.

Happy Holidays, All