Karabiner-elements: Fn and Left Ctrl swap doesn't apply to touch bar after locking/turning off screen

Created on 17 Dec 2019  ·  16Comments  ·  Source: pqrs-org/Karabiner-Elements

This is a pretty subtle problem that is hard to describe in the title, so I'll describe what I did and what resulted. I swapped Fn and Left Ctrl using Karabiner Elements so Left Ctrl will be the bottom leftmost key. Originally Fn toggles the F1-F12, and after swapping the keys, now the old Left Ctrl key toggles the Fn row and the old Fn key doesn't affect the touch bar. However, after I lock the screen and log back in, now _both_ keys toggle the function row. Restarting Karabiner Elements restores the original behavior I intended. It's a bit annoying since every time I do Ctrl+Tab or Ctrl+Shift+Tab in Chrome or whatever, the touch bar changes.

Most helpful comment

Looks like this is the same issue as #1641. Yeah, a simple restart would fix the problem, but it is really annoying.

Today, I just found this in Karabiner-MultitouchExtension by accident. If we can port in the same relaunch option, it should help the problem.
Screen Shot 2020-03-21 at 20 50 30

All 16 comments

I've got the same (I think) problem right now.

  1. Go to System Preferences → Keyboard → Shortcuts.
  2. Try to assign, for example, "Option F2" to an action.
  3. Expected behavior (and it works on external keyboard correctly): shortcut is assigned
  4. Current behavior: "F2" shortcut is assigned instead (I press Fn+Option+F2 on internal keyboard).

I tried to use EventViewer to find out what is happening, and it works like this:

  1. Press Option, it shows "Option"
  2. Press Fn, it shows "Fn+Option"
  3. Press F2 on Touch Bar, it shows "F2" (without modifiers).

Can't use Karabiner Elements because of that right now. :-(

(MacBook Pro 16", macOS 10.15.2 and 10.15.3 beta 1, tried it in desperation, latest Karabiner Elements build)

could this be related to #1972

I have the same problem. I tried to bind Command key or Ctrl key to Fn key. Every time the screen is unlocked from sleep, the touchbar will still respond to the physical Fn key no matter what modifier is actually bound to it. Restarting the Karabiner Element app will solve the issue until next sleep.

The EventViewer doesn't show anything different though. The physical Fn key will send correct key value of the modifier key bound to it with or without the issue.

System: macOS Catalina Version 10.15.3
Machine: MacBook Pro (16-inch, 2019)
Karabiner Element Version: 12.9.0

How to reproduce:

  1. Start karabiner element
  2. Bind any key (Ctrl, Command) to Fn key
  3. Make sure pressing physical Fn key does not trigger touch bar
  4. Let system enter sleep mode / close the lid
  5. Wake the system and unlock
  6. Press physical Fn key again. It should trigger touch bar

Current solution:
Quit karabiner element and start it again.

So... I worked around this by writing a small console app to run in the background which would kill the necessary Karabiner processes every time my MacBook unlocks, then trust Karabiner to restart them on its own...

import Cocoa
import Foundation

func restartKarabiner() {
    let task = Process()
    let username = NSUserName()
    task.launchPath = "/usr/bin/pkill"
    task.arguments = ["-u", username, "-f", "/Library/Application Support/org.pqrs/Karabiner-Elements/bin/*"]
    task.launch()
    task.waitUntilExit()
    print("\(Date()) restartKarabiner result: \(task.terminationStatus)")
}

let dnc = DistributedNotificationCenter.default()

dnc.addObserver(forName: .init("com.apple.screenIsUnlocked"), object: nil, queue: .main) { _ in
    restartKarabiner()
}

print("restart-karabiner-on-wake initialized")
RunLoop.current.run()
print("restart-karabiner-on-wake exiting")

Then I made this launch on login with launchd by creating the file ~/Library/LaunchAgents/com.user.loginscript.plist...

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
   <key>Label</key>
   <string>com.user.loginscript</string>
   <key>ProgramArguments</key>
   <array><string>/full/path/to/restart-karabiner-on-wake</string></array>
   <key>RunAtLoad</key>
   <true/>
</dict>
</plist>

It's not great, but it works :joy:

Looks like this is the same issue as #1641. Yeah, a simple restart would fix the problem, but it is really annoying.

Today, I just found this in Karabiner-MultitouchExtension by accident. If we can port in the same relaunch option, it should help the problem.
Screen Shot 2020-03-21 at 20 50 30

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Can anyone from here upvote #1641 please? This ticket is a duplicate of #1641 so let's aggregate our voteups in there.

… … …

It's not great, but it works 😂

@Shingyx, how did you set it up? I tried to install you solution too but it does not work.
And whereto are the prints written? When doing the first setup steps I noticed permission denied outputs in the Console-App because I was missing the run permission on the file. After modding the file with +x this output is not reappearing. But the desired effect is still missing…

I think there is just a small step wrong, just a little hint needed … and appreciated 🙂 Thanks in advance

@blanorama Did you compile the Swift file before trying to run it? I _think_ that might've been the issue.

Anyway, I've released my workaround as a GitHub repository here https://github.com/Shingyx/restart-karabiner-on-wake. Hopefully the README should be enough detail to get you started. Let me know if you still need help.

The output should appear in the terminal context which started the application, just like any other console application. Though I'm not really sure where they go once it's configured to start up using launchd.

funkylicious! 🤩 thanks for your quick answer – works like a charm 👏
as guessed, indeed, your little hint to compile already resolves it; more precise, I found the shortcut to use your snippet as a script with the swift bang #!/usr/bin/swift – so no compilation needed

but such a README and a precompiled binary is of course luxury; thanks again for the code! 🙂

PS: but I couldn’t figure out where the print() is going; I guess since the plist is missing the StandardOutPath it is dropped? 🤷‍♂️

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

no

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Not stale, this problem still exists and suggestions to fix it correctly exist too.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

No

Was this page helpful?
0 / 5 - 0 ratings