Skip to content

feat(macos): release keyboard grab on lock screen and user switch#2016

Merged
jtroo merged 1 commit intojtroo:mainfrom
FlameFlag:flameflag/push-nrkkrwxxqmnz
Apr 11, 2026
Merged

feat(macos): release keyboard grab on lock screen and user switch#2016
jtroo merged 1 commit intojtroo:mainfrom
FlameFlag:flameflag/push-nrkkrwxxqmnz

Conversation

@FlameFlag
Copy link
Copy Markdown
Contributor

@FlameFlag FlameFlag commented Apr 9, 2026

Address #1743

Poll CGSession state from a small background thread and pause kanata's
global IOKit grab whenever the screen locks or kanata's session loses
the console. Resume the grab once the session recovers

Key the fast-user-switching check on kCGSSessionOnConsoleKey, since
CGSessionCopyCurrentDictionary returns the caller's session — a
username comparison against a launch-time snapshot would never trip.
Read the undocumented CGSSessionScreenIsLocked boolean for the lock
signal. Fall back to "do not pause" on a NULL dict so root LaunchDaemon
installs (no Quartz GUI session) keep working

Re-check the pause flag right after kb.read() returns, not just at the
top of the loop. wait_key blocks on a read(2), so the typical lock
path catches kanata mid-read with the new user's first keystroke already
seized by IOKit. Drop that event without remapping or emitting it —
trade one lost keystroke for never producing a wrong one

Checklist

  • Add documentation to docs/config.adoc
    • N/A
  • Add example and basic docs to cfg_samples/kanata.kbd
    • N/A
  • Update error messages
    • N/A
  • Added tests, or did manual testing
    • Yes, Manual
image

@FlameFlag FlameFlag force-pushed the flameflag/push-nrkkrwxxqmnz branch 2 times, most recently from f69f44e to 604c10f Compare April 11, 2026 08:21
@FlameFlag
Copy link
Copy Markdown
Contributor Author

@jtroo I resolved the conflict

@FlameFlag FlameFlag force-pushed the flameflag/push-nrkkrwxxqmnz branch from 604c10f to f6dc3d1 Compare April 11, 2026 08:53
@FlameFlag
Copy link
Copy Markdown
Contributor Author

FlameFlag commented Apr 11, 2026

Resolved again

@jtroo
Copy link
Copy Markdown
Owner

jtroo commented Apr 11, 2026

The approach looks sensible to me.

I think this needs to be configurable though. I presume there are users who are the sole users of their machines that prefer the current always-grab even on lockscreen behaviour - without configurability this change would break their workflows. The default should IMO preserve the current behaviour.

With respect to implementation, a CLI argument seems more fitting for this type of functionality as opposed to a config item, but that is a weakly held opinion.

@FlameFlag
Copy link
Copy Markdown
Contributor Author

Yea, I was thinking the same some time after I made the PR, does --release-grab-on-lock sound good?

@jtroo
Copy link
Copy Markdown
Owner

jtroo commented Apr 11, 2026

Name sounds good!

Address jtroo#1743

Poll CGSession state from a small background thread and pause kanata's
global IOKit grab whenever the screen locks or kanata's session loses
the console. Resume the grab once the session recovers

Key the fast-user-switching check on `kCGSSessionOnConsoleKey`, since
`CGSessionCopyCurrentDictionary` returns the *caller's* session — a
username comparison against a launch-time snapshot would never trip.
Read the undocumented `CGSSessionScreenIsLocked` boolean for the lock
signal. Fall back to "do not pause" on a NULL dict so root LaunchDaemon
installs (no Quartz GUI session) keep working

Re-check the pause flag right after `kb.read()` returns, not just at the
top of the loop. `wait_key` blocks on a `read(2)`, so the typical lock
path catches kanata mid-read with the new user's first keystroke already
seized by IOKit. Drop that event without remapping or emitting it —
trade one lost keystroke for never producing a wrong one
@FlameFlag FlameFlag force-pushed the flameflag/push-nrkkrwxxqmnz branch from f6dc3d1 to 8a213d9 Compare April 11, 2026 21:18
@jtroo
Copy link
Copy Markdown
Owner

jtroo commented Apr 11, 2026

Thanks!

@jtroo jtroo merged commit 2a8d2d5 into jtroo:main Apr 11, 2026
5 checks passed
@FlameFlag FlameFlag deleted the flameflag/push-nrkkrwxxqmnz branch April 11, 2026 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants