Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
keyboard: turn down key repeat before going to lock screen
As mentioned here:

    https://twitter.com/wincent/status/1068234903811223552

Going to see if this can cure my lock screen woes. You can turn off key
repeat with:

    defaults write -g KeyRepeat 300000

But you have to log out for it to take effect. I did some reverse
engineering and header-file searching to figure out how:

    /System/Library/PreferencePanes/Keyboard.prefPane/Contents/MacOS/Keyboard

Is forcing the changes to take effect immediately, and discovered some
deprecated (sigh) APIs that hopefully will continue to exist for a
while:

    NXSetKeyRepeatInterval()
    NXKeyRepeatInterval()
    NXOpenEventStatus()

I bundled these up in a `dry` executable (short for "Don't Repeat
Yourself") that can be used to set the key repeat delay in seconds. Not
building or installing this automatically yet so that I can test it.

Calling `dry` from the `karabiner-kill` and `karabiner-boot` scripts,
and also switched to from running on systemWillSleep to screensDidLock,
which allows us to cover both normal screen saver and sleep events with
a single branch.
  • Loading branch information
wincent committed Nov 30, 2018
1 parent 2c9c491 commit 46835b2
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 1 deletion.
2 changes: 1 addition & 1 deletion roles/dotfiles/files/.hammerspoon/karabiner.lua
Expand Up @@ -19,7 +19,7 @@ return {
init = (function()
local watcher = hs.caffeinate.watcher.new(
function(event)
if event == hs.caffeinate.watcher.systemWillSleep then
if event == hs.caffeinate.watcher.screensDidLock then
disable()
elseif event == hs.caffeinate.watcher.screensDidUnlock then
enable()
Expand Down
9 changes: 9 additions & 0 deletions roles/dotfiles/files/.zsh/bin/karabiner-boot
Expand Up @@ -6,6 +6,10 @@ if [ -z "$UID" ]; then
UID=$(id -u)
fi

# In Hammerspoon, $PATH will be too minimal(/usr/bin:/bin:/usr/sbin:/sbin)
# to find the `dry` executable.
PATH=$PATH:$HOME/bin

# Depends on /private/etc/sudoers.d/karabiner-sudoers:
sudo launchctl load /Library/LaunchDaemons/org.pqrs.karabiner.karabiner_grabber.plist
sudo launchctl load /Library/LaunchDaemons/org.pqrs.karabiner.karabiner_observer.plist
Expand All @@ -14,4 +18,9 @@ launchctl enable gui/"$UID"/org.pqrs.karabiner.karabiner_console_user_server
launchctl bootstrap gui/"$UID" /Library/LaunchAgents/org.pqrs.karabiner.karabiner_console_user_server.plist
launchctl enable gui/"$UID"/org.pqrs.karabiner.karabiner_console_user_server

# Turn key repeat back on:
if command -v dry &> /dev/null; then
dry 0.033333 > /dev/null
fi

echo "🐣 Karabiner-Elements bootstrapped"
9 changes: 9 additions & 0 deletions roles/dotfiles/files/.zsh/bin/karabiner-kill
Expand Up @@ -6,6 +6,15 @@ if [ -z "$UID" ]; then
UID=$(id -u)
fi

# In Hammerspoon, $PATH will be too minimal(/usr/bin:/bin:/usr/sbin:/sbin)
# to find the `dry` executable.
PATH=$PATH:$HOME/bin

# For good measure, turn off key repeat:
if command -v dry &> /dev/null; then
dry 300 > /dev/null
fi

launchctl bootout gui/"$UID" /Library/LaunchAgents/org.pqrs.karabiner.karabiner_console_user_server.plist
launchctl disable gui/"$UID"/org.pqrs.karabiner.karabiner_console_user_server

Expand Down
1 change: 1 addition & 0 deletions roles/dotfiles/support/dry/.gitignore
@@ -0,0 +1 @@
/dry
12 changes: 12 additions & 0 deletions roles/dotfiles/support/dry/Makefile
@@ -0,0 +1,12 @@
PREFIX ?= $(HOME)
CFLAGS := -ansi -pedantic -Wall -Wextra ${CFLAGS}

dry: main.c
${CC} ${CFLAGS} \
-framework CoreFoundation \
-framework CoreServices \
-framework IOKit \
-o dry main.c

install:
install -m755 dry ${PREFIX}/bin
36 changes: 36 additions & 0 deletions roles/dotfiles/support/dry/main.c
@@ -0,0 +1,36 @@
/*
* dry (Don't Repeat Yourself)
*
* Usage: `dry 300`
*
* Sets the key repeat interval without requiring a logout.
*/

#include <stdio.h>
#include <stdlib.h>
#include <IOKit/hidsystem/event_status_driver.h>

int main(int argc, const char * argv[]) {
NXEventHandle handle;
double interval;

if (argc != 2) {
printf("Expected 1 argument (key repeat in seconds); got %d\n", argc - 1);
return EXIT_FAILURE;
}

handle = NXOpenEventStatus();
if (!handle) {
perror("NXOpenEventStatus");
return EXIT_FAILURE;
}

interval = NXKeyRepeatInterval(handle);
printf("Old interval: %lf\n", interval);

sscanf(argv[1], "%lf", &interval);
printf("New interval: %lf\n", interval);

NXSetKeyRepeatInterval(handle, interval);
return 0;
}

0 comments on commit 46835b2

Please sign in to comment.