Mac 解决16版MBP键盘B+N键重复点击的问题

  |  
阅读次数
  |  
字数 849
  |  
时长 ≈ 4 分钟

在16版MBP中的蝶式键盘有可能出现某个按钮重复点击的问题,就是按一次响应两次,重灾区是BN键,
偶然发现网上除了返修之外,还有一个折中方法,就是通过编写程序,在开机后自启动,在程序里面判断相应按钮的两次点击的间隔时间,
如果太短则忽略,从而达到避免重复点击的问题。

1.源码(本文章使用以下代码来自网络):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// alterkeys.c
// http://osxbook.com
//
// You need superuser privileges to create the event tap, unless accessibility
// is enabled. To do so, select the "Enable access for assistive devices"
// checkbox in the Universal Access system preference pane.

// modified by SF-Zhou
// To: Kill Double Typing on MacBook
// Complile: g++ -O2 -Wall -o kill_double_typing kill_double_typing.cpp -framework ApplicationServices
// Run: ./kill_double_typing

#include <ApplicationServices/ApplicationServices.h>
#include <iostream>
#include <chrono>
#include <unordered_map>
using namespace std;

typedef chrono::time_point<std::chrono::high_resolution_clock> Time;
typedef long long ll;

unordered_map<CGKeyCode, Time> last_time;

Time time_now() {
return chrono::high_resolution_clock::now();
}

// This callback will be invoked every time there is a keystroke.
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
// Paranoid sanity check.
if ((type != kCGEventKeyDown) && (type != kCGEventKeyUp)) {
return event;
}

// The incoming keycode.
CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);

if (keycode == 11 /* b */ || keycode == 45 /* n */) {
//if (keycode == 11 /* b */) {
if (type == kCGEventKeyUp) {
last_time[keycode] = time_now();
} else {
if (last_time.count(keycode)) {
ll microseconds = chrono::duration_cast<chrono::microseconds>(
time_now() - last_time[keycode]
).count();

// ignore if time less than 30ms
if (microseconds < 30000) {
return NULL;
}
}
}
}

// Set the modified keycode field in the event.
CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, (int64_t)keycode);

// We must return the event for it to be useful.
return event;
}

int main(void) {
CFMachPortRef eventTap;
CGEventMask eventMask;
CFRunLoopSourceRef runLoopSource;

// Create an event tap. We are interested in key presses.
eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp));
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, myCGEventCallback, NULL);
if (!eventTap) {
fprintf(stderr, "failed to create event tap\n");
exit(1);
}

// Create a run loop source.
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);

// Add to the current run loop.
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);

// Enable the event tap.
CGEventTapEnable(eventTap, true);

// Set it all running.
CFRunLoopRun();

// In a real program, one would have arranged for cleaning up.

exit(0);
}

2.操作

1.修改kill_double_typing.cpp逻辑39行,改为出错的键盘值
2.编译

1
sudo g++ -O2 -Wall -o kill_double_typing kill_double_typing.cpp -framework ApplicationServices

3.添加可执行权限
依次进入系统设置偏好-安全性与隐私-辅助功能
点击+号,选择编译后所在文件夹位置,选择kill_double_typing二进制文件进行添加
4.

1
cd ~/library/launchagents

5.

1
vim local.localhost.doubletyping.plist

6.输入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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>local.localhost.doubletyping</string>
<!-- <key>Disabled</key>
<false/> -->
<key>RunAtLoad</key>
<true/>
<!-- <key>KeepAlive</key>
<true/> -->
<!-- <key>LaunchOnlyOnce</key>
<true/> -->
<key>ProgramArguments</key>
<array>
<!-- <string>/usr/bin/nohup</string> -->
<string>/Users/tidy/Dropbox/sublimetext/mac/kill_double_typing/kill_double_typing</string>
</array>
</dict>
</plist>

7.保存:

1
wq

8.加载:

1
launchctl load -w local.localhost.doubletyping.plist

9.启动:

1
launchctl start local.localhost.doubletyping

10.停止:

1
launchctl stop local.localhost.doubletyping

11.查看:

1
launchctl list | grep doubletyping

3.注意

如果重新编译过可执行文件,需要依次进入系统设置偏好-安全性与隐私-辅助功能,
然后把之前授权过的kill_double_typing可执行文件删除,然后保存之后,重新运行start命令,
然后重新进入辅助功能,将新的kill_double_typing可执行文件赋予权限。