文章总结:我的鼠标滚轮坏了,然后把数据过滤一下就能用了

今天收拾宿舍,发现了我的小笨鼠标

已经两年了,没想到这么经用

用蓝牙连接上,发现依旧好用

唯一美中不足的是——

d575313377646d3027de98912257ba67.png

虽然不知道是硬件还是软件的锅,但是先看看电脑收到的数据是不是对的

先安装工具

1
sudo pacman -S libinput libinput-tools

然后监听数据(鼠标通过蓝牙传给电脑)

1
sudo libinput debug-events | grep -i scroll

得到这样一组数据流

ab75a9f82fa2622c0eaef14022b6264b.png

可以看出绝大多数都挺正常的,只不过有几个突变

感觉大概率是消息阻塞了,怎么办啊

欸,我把全部数据都变为 120(或者-120)不就好了嘛。下面是代码

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
import evdev
import sys
import time

TARGET_NAME = "BT5.2 Mouse"

def find_mouse():
# 遍历系统所有输入设备
devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
for dev in devices:
if TARGET_NAME in dev.name:
caps = dev.capabilities()
# 确保该设备具有滚轮 (REL_WHEEL) 功能,排除同名的纯键盘虚拟设备
if evdev.ecodes.EV_REL in caps and evdev.ecodes.REL_WHEEL in caps[evdev.ecodes.EV_REL]:
return dev
return None

mouse_dev = find_mouse()

if not mouse_dev:
print(f"未找到名为 '{TARGET_NAME}' 的鼠标,请确认已连接。")
sys.exit(1)

print(f"成功锁定设备: {mouse_dev.name} ({mouse_dev.path})")

# 根据真实鼠标的参数,克隆一个名为 "Fixed Mouse" 的虚拟鼠标
ui = evdev.UInput.from_device(mouse_dev, name="Fixed BT5.2 Mouse")

try:
# 独占真实鼠标,防止系统接收到两份信号
mouse_dev.grab()
print("开始拦截并过滤滚轮信号... (按 Ctrl+C 退出)")

for event in mouse_dev.read_loop():
# 如果是相对坐标事件 (移动或滚轮)
if event.type == evdev.ecodes.EV_REL:
# 过滤标准滚轮信号 (限制为 1 或 -1)
if event.code == evdev.ecodes.REL_WHEEL:
if event.value > 0:
event.value = 1
elif event.value < 0:
event.value = -1
# 过滤高精度滚轮信号 (限制为 120 或 -120)
elif event.code == evdev.ecodes.REL_WHEEL_HI_RES:
if event.value > 0:
event.value = 120
elif event.value < 0:
event.value = -120

# 将过滤后的事件写入虚拟鼠标,欺骗系统
ui.write_event(event)
ui.syn()

except IOError:
print("权限不足!请使用 sudo python mouse_fix.py 运行此脚本。")
except KeyboardInterrupt:
print("\n停止拦截,恢复正常状态。")
finally:
# 退出时释放设备
try:
mouse_dev.ungrab()
except:
pass
ui.close()

直接运行代码,测试一波

bcec900545fc782797a972aedf9c70dc.png

可以发现正常的不得了,反方向也能用

加进 SystemD 就可以了(类似于自启动)

先把脚本放进 /usr/local/bin/ 目录下,然后创建 /etc/systemd/system/mouse-fix.service 并写入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=BT5.2 Mouse Scroll Fix Service
# 确保在蓝牙服务启动后再运行
After=bluetooth.target

[Service]
Type=simple
# 使用 root 权限执行我们的 Python 脚本
ExecStart=/usr/bin/python /usr/local/bin/mouse_fix.py
# 核心设置:如果脚本崩溃(比如鼠标断开连接),系统会自动重启该服务
Restart=always
# 每次重启前等待 3 秒,防止疯狂消耗 CPU
RestartSec=3

[Install]
WantedBy=multi-user.target

重新加载就可以用了

1
2
3
4
5
# 刷新 systemd 配置
sudo systemctl daemon-reload

# 启用并立即启动服务
sudo systemctl enable --now mouse-fix.service

检查运行状态

1
systemctl status mouse-fix.service

有绿色的就说明没问题

5a2c51b1a62753e60a97577cb14c1311.png

然后就没有然后了,修好了,可以愉快使用了