11 KiB
Kindle Dashboard 双翻页键主题菜单方案
0. 当前状态
本文是评审方案,不是实机结论。
补充说明:当前仓库默认已经不启用这套运行态菜单,主题切换入口只保留在 KUAL。 本文保留为备选方案与历史设计记录,不代表当前默认交互。
当前 Kindle 已掉出 Wi-Fi,SSH 中断,因此这份文档的目标是:
- 先把“左右同时按下翻页键,呼出主题选择页面”的方案固定下来
- 明确交互、进程模型、文件落点和风险
- 等 SSH 恢复后,再按这份方案做实机联调和裁剪
本文默认设备为:
- Kindle Voyage
- 固件 5.13.6
- 当前默认实现为“保留 framework / webreader 的 overlay 模式”
补充:
- 本文很多菜单设计最初建立在“dashboard 会停掉原生 UI 栈”的旧架构上
- 截至
2026-03-17,默认实现已经切到“保留原生 UI 栈” - 因此文中提到的
Return Home,应以stop.sh的当前行为为准:- overlay 模式下:停掉 dashboard,并在底层是 KUAL 时把它正常退回首页
- 旧架构兼容模式下:保守恢复
framework / cvm / webreader
1. 已确认事实
1.1 左右翻页键在内核里是两个独立键
实机上已经确认:
- 输入设备名为
fsr_keypad - 设备节点为
/dev/input/event2 evtest /dev/input/event2可识别:Event code 104 (PageUp)Event code 109 (PageDown)
这意味着:
- 左右翻页键不是一个“翻页动作”
- 而是两个可以分别监听的
EV_KEY - 软件层可以把它们组合成一个“组合键”
1.2 组合键不可能在同一时刻上报
Linux 输入事件一定是串行上报的。
所以“左右同时按下”在实现上必须解释为:
- 两个键在一个很短的时间窗口内先后进入 pressed
而不能解释为:
- 两个键共享同一个内核时间戳
推荐窗口:
300ms到350ms
1.3 真正系统挂起时,用户态监听器不会继续工作
当前 dashboard 会在休眠路径里进入:
echo "mem" >/sys/power/state
一旦进入这个状态:
- 用户态 shell / Lua / evtest 监听器都会停掉
- 无法继续等待双键输入
因此本方案的有效范围是:
- dashboard 正在运行
- Kindle 尚未进入真正的
mem挂起
这也是为什么本方案先聚焦:
- 运行态主题菜单
而不把目标直接扩展为:
- 真休眠态唤醒菜单
2. 目标
目标能力如下:
- 用户在 dashboard 运行态下,同时按下左右翻页键
- 屏幕弹出一个 KUAL 风格的主题选择页面
- 用户通过翻页键在主题列表中移动选中项
- 用户再次同时按下左右翻页键,确认并切换主题
- 切换完成后,立即刷新背景和时钟
- 菜单列表末尾可附带一个“返回首页”动作项,安全退出 dashboard 并恢复 Kindle 首页
本阶段非目标:
- 不做真正休眠态下的按键唤醒菜单
- 不在 Kindle 上实现复杂触摸手势
- 不做缩略图式主题画廊
- 不做 theme + orientation 同时编辑的完整设置页
3. 推荐交互
3.1 触发方式
触发手势:
- 左右翻页键在
350ms内同时按下
解释规则:
- 先按左,再按右,且间隔不超过
350ms,视为组合键 - 先按右,再按左,且间隔不超过
350ms,也视为组合键 - 单独按左或单独按右,不触发菜单
3.2 菜单打开后的操作
推荐第一版交互保持纯物理键可用:
PageUp:向上移动PageDown:向下移动- 再次双键同时按下:确认当前项
同时保留一个触摸兜底入口:
- 右下角长按:直接呼出同一份运行态主题菜单
其中当前项可以是:
- 某个主题:执行主题切换
Return Home:退出 dashboard,恢复 framework / webreader,回到 Kindle 首页
这样做的原因:
- 不依赖 framework
- 不依赖系统触摸 UI
- 行为闭环简单,便于在无 SSH 时本机恢复
3.3 方向处理
推荐第一版只切换 theme id,保持当前方向不变。
例如:
- 当前是
simple / landscape - 菜单里选中
paper - 最终切到
paper / landscape
如果目标主题不支持当前方向,再回退到:
- 该主题可用的默认方向
这样能避免菜单第一版就把交互复杂度拉高到二维。
4. 菜单布局
4.1 布局风格
菜单布局可以模拟 KUAL,但不追求逐像素复刻。
推荐视觉结构:
- 全屏白底
- 顶部两行标题
Kindle DashboardTheme Menu
- 中部竖向列表
- 当前选中项前用
>标识 - 底部两行提示文案
示意:
Kindle Dashboard
Theme Menu
Orientation: landscape
Selected: Simple
--------------------------------
> Default (default)
Paper (paper)
Classic (classic)
Simple (simple)
PageUp/PageDown: move
Press both keys: apply
4.2 为什么不做缩略图页
在当前阶段,不建议直接做缩略图式主题预览页。
原因:
- 需要更多图形绘制和排版能力
- 需要解决选中态、滚动和点击区域映射
- 在 SSH 不稳定时,调试成本显著上升
所以推荐第一版先做:
- 纯文本 KUAL 风格列表
确认流程稳定后,再考虑升级到:
- 缩略图 + 文本说明
5. 进程模型
5.1 推荐采用独立监听服务
推荐新增一个独立后台服务,例如:
dash/src/local/theme-menu-service.sh
职责:
- 独立监听
/dev/input/event2 - 识别组合键
- 维护菜单状态
- 在确认后调用现有主题切换链路
不建议把这套逻辑直接塞进 dash.sh 主循环。
原因:
- 主循环核心职责已经是拉图、刷屏、休眠
- 组合键菜单属于输入状态机
- 两者耦合后,调试和排错都会变差
5.2 与现有链路的关系
推荐关系如下:
dash.sh启动时拉起theme-menu-service.shtheme-menu-service.sh常驻监听event2- 识别到组合键后,本机绘制菜单
- 用户确认后,调用现有:
/mnt/us/dashboard/switch-theme.sh <theme-id> [orientation]- 或
/mnt/us/dashboard/stop.sh
switch-theme.sh继续负责:- 同步主题配置
- 拉最新背景
- 刷新屏幕
- 重绘时钟
如果选中的是 Return Home,则不走主题切换,而是调用 stop.sh:
- 停掉 dashboard 和菜单监听器
- 恢复
framework / cvm / webreader - 回到 Kindle 首页
也就是说,菜单服务只负责:
- 触发
- 选择
- 调用已有切换入口
而不是重新实现一套主题切换。
6. 事件状态机
6.1 空闲态
空闲态只关注组合键触发。
状态变量:
pending_keypending_timecombo_window_seconds
逻辑:
- 收到
PageUp down- 记录
pending_key=up
- 记录
- 收到
PageDown down- 如果此前
pending_key=up且时间差小于窗口,判定为组合键
- 如果此前
- 反向顺序同理
- 组合键成立后,打开菜单
6.2 菜单态
菜单态下,状态机切成另一套规则:
PageUprelease:选中项上移PageDownrelease:选中项下移- 组合键:确认当前项
推荐选中项循环:
- 第一项再上移 -> 跳到最后一项
- 最后一项再下移 -> 跳到第一项
这样可以减少边界判断和失败反馈。
7. 文件落点
推荐新增或修改这些文件。
7.1 新增
dash/src/local/theme-menu-service.sh- 常驻监听器和菜单状态机
7.2 修改
-
dash/src/local/theme-json.lua- 新增
list子命令 - 输出主题列表给菜单服务消费
- 新增
-
dash/src/local/env.sh- 新增菜单相关开关,例如:
THEME_MENU_ENABLEDTHEME_MENU_EVENT_DEVICETHEME_MENU_COMBO_WINDOW_SECONDS
- 新增菜单相关开关,例如:
-
dash/src/dash.sh- 在初始化阶段拉起菜单监听服务
-
dash/src/stop.sh- 停止 dashboard 时顺手停止菜单服务
-
scripts/sync-layered-clock-to-kindle.sh- 把新增服务脚本同步到设备
8. 推荐配置
建议新增这些环境变量:
export THEME_MENU_ENABLED=true
export THEME_MENU_EVENT_DEVICE="/dev/input/event2"
export THEME_MENU_COMBO_WINDOW_SECONDS=0.35
export THEME_MENU_RUNTIME_DIR="/tmp/kindle-dash-theme-menu"
说明:
THEME_MENU_ENABLED- 总开关
THEME_MENU_EVENT_DEVICE- Voyage 上通常是
event2 - 后续换机型时可以只改这个
- Voyage 上通常是
THEME_MENU_COMBO_WINDOW_SECONDS- 组合键判定窗口
THEME_MENU_RUNTIME_DIR- 菜单服务的临时运行目录
- 需要放在支持 FIFO 的文件系统上,Voyage 上应使用
/tmp
9. 风险与限制
9.1 真休眠态不可用
这是本方案最重要的限制。
只要系统真的进入:
echo "mem" >/sys/power/state
那么:
- 监听器就不会继续运行
- 双键菜单也不会再响应
因此第一版推荐配套策略是:
- 调试阶段
DISABLE_SYSTEM_SUSPEND=true - 菜单只保证运行态可用
后续如果要支持“近似待机但仍可双键唤出菜单”,再单独设计:
- sleeping 页面但不进真 suspend
9.2 菜单样式是 KUAL 风格,不是 KUAL 组件
本方案里的“KUAL 风格”是指:
- 白底
- 列表
- 简洁标题
- 文本选中态
并不是:
- 真的把 KUAL 的 Java/UI 组件拉起来
原因是当前 dashboard 已经停掉 framework,直接复用 KUAL UI 的成本会更高。
9.3 第一版不依赖触摸
从评审角度看,第一版最好不要把选择动作建立在触摸上。
原因:
- 触摸设备事件会更复杂
- 点选区域映射也更容易出错
- 无 SSH 时问题更难恢复
所以第一版推荐:
- 只用翻页键完成整个菜单闭环
10. 后续验证路径
等 SSH 恢复后,建议按这个顺序验证:
- 确认
evtest /dev/input/event2仍能看到:PageUpPageDown
- 先同步本地最新 dashboard 代码到 Kindle
- 本轮已在本地加入一个“短按
power提前唤醒后,额外保持 60 秒”的改动 - 相关配置在
dash/src/local/env.sh:MANUAL_WAKE_KEEP_AWAKE_SECONDS=60MANUAL_WAKE_EARLY_TOLERANCE_SECONDS=5
- 相关运行逻辑在
dash/src/dash.sh
- 本轮已在本地加入一个“短按
- 重启 dashboard,先单独验证短按
power:- 从休眠态短按
power - 预期不再只亮约 3 秒
- 预期应保持约 60 秒再回到下一轮休眠
- 从休眠态短按
- 让 dashboard 保持运行态,不进真 suspend
- 手动启动菜单服务
- 验证:
- 双键能否稳定打开菜单
- 单键移动是否会误触组合键
- 再次双键能否稳定确认
- 验证主题切换后:
- 背景立即更新
- 时钟位置和方向保持正确
11. 结论
在当前仓库和 Kindle Voyage 的约束下,推荐采用下面这条路线:
- 监听
/dev/input/event2 - 用短时间窗口识别
PageUp + PageDown组合键 - 在运行态下绘制一个 KUAL 风格的文本主题菜单
- 右下角长按也复用同一份菜单,而不是另起一套触摸 UI
- 用
PageUp / PageDown导航 - 再次双键确认
- 最终复用现有
switch-theme.sh完成主题切换
这是当前成本最低、最容易恢复、也最适合在 SSH 不稳定阶段先落地评审的方案。
如果菜单需要提供稳定退出入口,也可以在列表末尾追加一个 Return Home 动作项。
实现上应复用 stop.sh 的保守恢复链路,而不要直接强拉 booklet.home。