pqrs-org / Karabiner-Elements

Karabiner-Elements is a powerful utility for keyboard customization on macOS Sierra (10.12) or later.
https://pqrs.org/osx/karabiner/
The Unlicense
18.87k stars 838 forks source link

Fn and Left Ctrl swap doesn't apply to touch bar after locking/turning off screen #2095

Open Jont828 opened 4 years ago

Jont828 commented 4 years ago

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.

bealex commented 4 years ago

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)

IanEdington commented 4 years ago

could this be related to #1972

lding-code commented 4 years ago

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.

Shingyx commented 4 years ago

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:

jZhangTk commented 4 years ago

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
stale[bot] commented 4 years ago

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.

Nowaker commented 4 years ago

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

lecodeski commented 4 years ago

… … …

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

Shingyx commented 4 years ago

@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.

lecodeski commented 4 years ago

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? 🤷‍♂️

stale[bot] commented 4 years ago

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.

Nowaker commented 4 years ago

no

stale[bot] commented 4 years ago

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.

lecodeski commented 4 years ago

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

stale[bot] commented 3 years ago

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.

Nowaker commented 3 years ago

No

patrikturi commented 3 years ago

For me on Catalina this works to restart Karabiner and fix the issue:

launchctl stop org.pqrs.karabiner.karabiner_console_user_server
launchctl start org.pqrs.karabiner.karabiner_console_user_server
Valentin-N commented 2 years ago

More details in https://github.com/pqrs-org/Karabiner-Elements/issues/1641, but I believe this issue shares the same root cause with https://github.com/pqrs-org/Karabiner-Elements/issues/2898, which is much simpler to replicate and harder to dispute as a bug. I suggest to anyone still interested in a fix to 👍 on https://github.com/pqrs-org/Karabiner-Elements/issues/2898