配置文件
KeySteer 不要求配置文件。没有配置时直接使用内置默认值,其行为与发布的 keysteer.default.toml 一致。
配置格式是 TOML,发布的完整示例可 直接下载。本文按“先能用、再定制、最后排错”的顺序介绍配置。
配置文件位置
程序会在当前目录中查找 keysteer.<名称>.toml:不存在用户配置时,会尝试读取 keysteer.default.toml。如果连它也不存在,则直接使用内置默认值:
- Windows:可执行文件所在目录。
- macOS
.app:~/Library/Application Support/KeySteer/。
文件名必须是 keysteer.<名称>.toml,例如 keysteer.user.toml。也可以显式指定:
keysteer --config keysteer.user.toml
keysteer --config ./profiles/keysteer.work.toml
keysteer --check --config keysteer.user.toml常用诊断命令:
| 命令 | 用途 |
|---|---|
keysteer --check -c keysteer.user.toml | 解析并校验配置,不启动运行时。 |
keysteer --dump-config | 输出当前生效的完整配置。 |
keysteer --doctor | 检查后端、键盘、显示器、权限和启动键。 |
keysteer --help | 查看 CLI 选项和默认快捷键。 |
最小配置
[normal.bindings]
# 在 Normal 中用空格返回 Idle
space = "idle"所有未写的字段都会保留默认值。建议在默认配置的基础上进行修改。
配置结构
根配置常用 section 如下:
| Section | 作用 |
|---|---|
[general] | 排除应用。 |
[key_aliases] | 自定义键名和跨平台修饰键。 |
[hotkeys] | Idle 中可触发 Mode 的入口。 |
[normal]、[grid]、[recursive_grid]、[ui_hint] | 各 Mode 的继承、绑定和参数。 |
[pointer]、[scroll] | 鼠标速度和滚动距离。 |
[theme]、[mode_indicator] | 颜色和模式提示。 |
[[app_configs]] | 按应用覆盖绑定。 |
[plugin_modes] | 插件设置和插件 Mode 绑定。 |
[debug] | 调试日志类别。 |
按键和别名
按键写法
按键绑定的左侧支持单键、组合键和“多个单键共享动作”:
[normal]
long_press_toggle_ms = 500
[normal.bindings]
h = "move_left"
"primary+shift+s" = "send primary+shift+s"
"v b" = "fast"+表示同一个组合键。空格表示多个独立按键绑定到同一个动作,不是顺序按键。- 发布默认配置中,
primary在 macOS 是Command、Windows 是左Alt。它是别名;若你要在 Windows 使用Ctrl,可以在[key_aliases.windows]注释掉 。 ctrl、alt、shift等通用修饰键匹配左右两侧;left_/right_前缀 只匹配指定一侧。
常用键名包括 a-z、0-9、space、enter、esc、tab、delete、backspace、up、down、left、right、home、end、page_up、page_down、f1-f20 和 numpad_0-numpad_9。
自定义别名
[key_aliases]
Hyper = "right_ctrl"
[key_aliases.windows]
Primary = "left_alt"
[key_aliases.macos]
Primary = "left_cmd"顶层别名在所有平台生效;别名值必须是一个键,不能是组合键;不区分大小写。
Primary 只是一个 可解析 的跨平台别名,不是固定的物理键。发布默认值是 macOS Command、Windows Alt;上例正是把 Windows 的 Primary 显式设为 Alt。大小写不同的 primary/Primary 指向同一个别名。
绑定、数组和继承
右值可以是字符串,也可以是字符串数组:
[normal.bindings]
h = "move_left"
x = ["press shift", "left_click", "release shift"]
"primary+shift+b" = ["exec say start", "wait 300", "exec say done"]数组中的动作从左到右执行。wait 不会阻塞整个事件循环,只暂停该序列;空数组不合法。
一个 Mode 的有效绑定按以下规则合并:
- Mode 自己的
[<mode>.bindings]。 inherits中列出的父 Mode,按书写顺序查找。- 当前应用匹配的
app_configs覆盖合并结果。 - 插件的建议绑定只填补空位,不覆盖用户设置。
这里的“合并”指运行时的有效按键表。程序只会进行覆盖替换。
[grid]
inherits = ["hotkeys", "normal"]
[grid.bindings]
q = "none" # 屏蔽从 normal 继承的 qnone 和 __disabled__ 都表示明确禁用。建议保留至少一个 [hotkeys] 入口,否则程序仍会运行,但无法从 Idle 进入其他 Mode。
动作序列
[normal.bindings]
x = ["press shift", "left_click", "release shift"]
"primary+shift+b" = ["exec say start", "wait 300", "exec say done"]完整动作、参数和 exec 规则见 模式与动作。
Normal 和定位 Mode
Normal
Normal 是控制鼠标直接移动、点击、滚动和进入其他 Mode 的平台:
[normal]
long_press_toggle_ms = 500
[normal.bindings]
h = "move_left"
j = "move_down"
k = "move_up"
l = "move_right"
";" = "left_click"
g = "grid"
f = "recursive_grid"
"primary+f" = "ui_hint"
"primary+s" = "screen next"
# 可选:把 Primary+H/J/K/L 发送为应用的方向键。
# "primary+h" = "left"
# "primary+j" = "down"
# "primary+k" = "up"
# "primary+l" = "right"passthrough_unbound_keys = true 是默认行为:Normal 只吞掉命中完整 KeySteer 绑定的输入,未绑定键及未配置的修饰组合会保持原始 down/up 生命周期并透传。
设为 false 时,Normal 恢复键盘独占,并保留旧的宽松组合匹配;Grid、Recursive Grid 和 UI Hint 始终保持独占。Idle 始终透传未命中的输入,并同样采用完整修饰组合匹配。
long_press_toggle_ms 作用于绑定为 鼠标键 的键和单独按住的无参数 toggle 激活键。鼠标键达到阈值后保持对应按钮按下;无参数 toggle 达到阈值后保持激活键自身按下,松开物理键不会撤销 latch。单独短按无参数 toggle 可释放全部 latch。设为 0 禁用这两种长按行为,允许范围为 0..=60000 毫秒。
Grid
[grid]
grid_cols = 5
grid_rows = 4
keys = "12345qwertasdfgzxcvb"
max_depth = 3
cursor_follow_selection = true
[grid.lifecycle]
after_finish = "normal"
after_click = "finish"keys 必须正好包含 grid_cols × grid_rows 个字符,按从左到右、从上到下填入。max_depth 是确认目标前的最大层数。初始画面会在一级格中央显示大号第一键,并在内部预览小号第二键;[grid.ui] 的 matched_text_color 控制大字,text_color 控制小字的基色,matched_border_color 控制内部细线。这个预览只影响绘制,不提前改变选择深度。
Recursive Grid
[recursive_grid]
grid_cols = 3
grid_rows = 3
keys = "qweasdzxc"
max_depth = 10
min_size_width = 1
min_size_height = 1
[recursive_grid.lifecycle]
after_finish = "keep"
after_click = "keep"max_depth 必须在 1..=20。layers 可以按深度覆盖网格形状;未写的字段继承基础设置:
[recursive_grid]
layers = [
{ depth = 0, grid_cols = 2, grid_rows = 2, keys = "crtn" },
]UI Hint
[ui_hint]
strategy = "vision" # axtree、vision 或 hybrid
hint_characters = "asdfghjkl"
scan_timeout_ms = 2500
scan_retry_count = 1
scan_retry_delay_ms = 200
visible_check_enabled = false
clickable_roles = ["button", "link", "checkbox", "text_field", "menu_item"]
[ui_hint.lifecycle]
after_finish = "normal"
after_click = "normal"macOS 支持 Accessibility tree、Vision 和 Hybrid;Windows 使用 UI Automation,配置为 vision/hybrid 时会安全回退到 UIA。clickable_roles 是跨平台语义角色,也可以用 ax: 或 uia: 指定原生角色。
指针、滚动和主题
[pointer]
initial_speed = 1000.0
max_speed = 2200.0
acceleration = 3000.0
smooth_acceleration = true
tap_distance = 2.5
slow_multiplier = 0.35
precision_multiplier = 0.12
fast_multiplier = 2.0
[scroll]
scroll_step = 50
scroll_step_half = 500
scroll_step_full = 1000000
[platform.macos.scroll]
invert_horizontal = false
invert_vertical = true速度单位是像素/秒,加速度单位是像素/秒²,与显示器刷新率无关。smooth_acceleration = true 使用起步和收尾更柔和的 S 曲线;设为 false 使用线性加速。
主题颜色使用 #RRGGBBAA,可以为浅色和深色外观分别设置:
[theme.dark]
surface = "#0A1338FF"
accent = "#6E82D6FF"
accent_alt = "#8FA2F0FF"
on_accent_alt = "#081022FF"
text = "#E8EEFFFF"
[mode_indicator.cursor]
left_pressed_color = "#00FF00FF"
middle_pressed_color = "#FF00FFFF"
right_pressed_color = "#00FFFFFF"鼠标按钮通过 press 或 toggle 保持按下时,透明圆形指示器使用对应的 *_pressed_color:填充使用配置颜色 20% 的不透明度。
应用覆盖:[[app_configs]]
应用覆盖可以禁用或替换某些程序里的绑定:
[[app_configs]]
bundle_id = "com.apple.Terminal"
bindings = { "primary+shift+e" = "none" }
[[normal.app_configs]]
bundle_id = "Figma"
bindings = { v = "none", "primary+f" = "grid" }根级 [[app_configs]] 对所有 Mode 生效;[[normal.app_configs]] 只在 Normal 生效。匹配值可以是 macOS bundle id、Windows 可执行文件名、或窗口标题的子串。
插件设置
插件 Mode 使用命名空间:
[plugin_modes."plugin:screen-selector".settings]
preserve = true
[plugin_modes."plugin:screen-selector"]
inherits = ["hotkeys", "normal"]自带 Screen Selector 的 preserve = true 会在切屏时保留 Grid/Recursive Grid 的选择路径;设为 false 则从目标显示器重新开始。
运行时修改与调试
set_config 可以修改点号路径,并在解析、校验通过后原子写回配置:
[normal.bindings]
"primary+1" = "set_config pointer.max_speed 800"
"primary+2" = "set_config theme.dark.accent \"#FF8800FF\""无效修改不会替换当前有效配置。状态栏的 Reload Configuration 会重新加载配置。
[debug]
enabled = true
keys = true
actions = true
modes = true
backend = true
pointer = false
motion = false
overlay = true
timers = true建议只在排查问题时开启调试日志;日志会写入数据目录中的 keysteer.log。