update at 2026-03-17 10:37:27

This commit is contained in:
douboer@gmail.com
2026-03-17 10:37:27 +08:00
parent e5becf63cf
commit 192eb1b8d1
44 changed files with 5208 additions and 403 deletions

View File

@@ -0,0 +1,415 @@
# Kindle Dashboard 双翻页键主题菜单方案
## 0. 当前状态
本文是评审方案,不是实机结论。
当前 Kindle 已掉出 Wi-FiSSH 中断,因此这份文档的目标是:
- 先把“左右同时按下翻页键,呼出主题选择页面”的方案固定下来
- 明确交互、进程模型、文件落点和风险
- 等 SSH 恢复后,再按这份方案做实机联调和裁剪
本文默认设备为:
- Kindle Voyage
- 固件 5.13.6
- dashboard 运行时会停掉 framework / 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 会在休眠路径里进入:
```sh
echo "mem" >/sys/power/state
```
一旦进入这个状态:
- 用户态 shell / Lua / evtest 监听器都会停掉
- 无法继续等待双键输入
因此本方案的有效范围是:
- dashboard 正在运行
- Kindle 尚未进入真正的 `mem` 挂起
这也是为什么本方案先聚焦:
- 运行态主题菜单
而不把目标直接扩展为:
- 真休眠态唤醒菜单
## 2. 目标
目标能力如下:
1. 用户在 dashboard 运行态下,同时按下左右翻页键
2. 屏幕弹出一个 KUAL 风格的主题选择页面
3. 用户通过翻页键在主题列表中移动选中项
4. 用户再次同时按下左右翻页键,确认并切换主题
5. 切换完成后,立即刷新背景和时钟
本阶段非目标:
- 不做真正休眠态下的按键唤醒菜单
- 不在 Kindle 上实现复杂触摸手势
- 不做缩略图式主题画廊
- 不做 theme + orientation 同时编辑的完整设置页
## 3. 推荐交互
### 3.1 触发方式
触发手势:
- 左右翻页键在 `350ms` 内同时按下
解释规则:
- 先按左,再按右,且间隔不超过 `350ms`,视为组合键
- 先按右,再按左,且间隔不超过 `350ms`,也视为组合键
- 单独按左或单独按右,不触发菜单
### 3.2 菜单打开后的操作
推荐第一版交互保持纯物理键可用:
- `PageUp`:向上移动
- `PageDown`:向下移动
- 再次双键同时按下:确认当前主题
这样做的原因:
- 不依赖 framework
- 不依赖系统触摸 UI
- 行为闭环简单,便于在无 SSH 时本机恢复
### 3.3 方向处理
推荐第一版只切换 `theme id`,保持当前方向不变。
例如:
- 当前是 `simple / landscape`
- 菜单里选中 `paper`
- 最终切到 `paper / landscape`
如果目标主题不支持当前方向,再回退到:
- 该主题可用的默认方向
这样能避免菜单第一版就把交互复杂度拉高到二维。
## 4. 菜单布局
### 4.1 布局风格
菜单布局可以模拟 KUAL但不追求逐像素复刻。
推荐视觉结构:
- 全屏白底
- 顶部两行标题
- `Kindle Dashboard`
- `Theme Menu`
- 中部竖向列表
- 当前选中项前用 `>` 标识
- 底部两行提示文案
示意:
```text
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 与现有链路的关系
推荐关系如下:
1. `dash.sh` 启动时拉起 `theme-menu-service.sh`
2. `theme-menu-service.sh` 常驻监听 `event2`
3. 识别到组合键后,本机绘制菜单
4. 用户确认后,调用现有:
- `/mnt/us/dashboard/switch-theme.sh <theme-id> [orientation]`
5. `switch-theme.sh` 继续负责:
- 同步主题配置
- 拉最新背景
- 刷新屏幕
- 重绘时钟
也就是说,菜单服务只负责:
- 触发
- 选择
- 调用已有切换入口
而不是重新实现一套主题切换。
## 6. 事件状态机
### 6.1 空闲态
空闲态只关注组合键触发。
状态变量:
- `pending_key`
- `pending_time`
- `combo_window_seconds`
逻辑:
1. 收到 `PageUp down`
- 记录 `pending_key=up`
2. 收到 `PageDown down`
- 如果此前 `pending_key=up` 且时间差小于窗口,判定为组合键
3. 反向顺序同理
4. 组合键成立后,打开菜单
### 6.2 菜单态
菜单态下,状态机切成另一套规则:
- `PageUp` release选中项上移
- `PageDown` release选中项下移
- 组合键:确认当前项
推荐选中项循环:
- 第一项再上移 -> 跳到最后一项
- 最后一项再下移 -> 跳到第一项
这样可以减少边界判断和失败反馈。
## 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_ENABLED`
- `THEME_MENU_EVENT_DEVICE`
- `THEME_MENU_COMBO_WINDOW_SECONDS`
- `dash/src/dash.sh`
- 在初始化阶段拉起菜单监听服务
- `dash/src/stop.sh`
- 停止 dashboard 时顺手停止菜单服务
- `scripts/sync-layered-clock-to-kindle.sh`
- 把新增服务脚本同步到设备
## 8. 推荐配置
建议新增这些环境变量:
```sh
export THEME_MENU_ENABLED=true
export THEME_MENU_EVENT_DEVICE="/dev/input/event2"
export THEME_MENU_COMBO_WINDOW_SECONDS=0.35
```
说明:
- `THEME_MENU_ENABLED`
- 总开关
- `THEME_MENU_EVENT_DEVICE`
- Voyage 上通常是 `event2`
- 后续换机型时可以只改这个
- `THEME_MENU_COMBO_WINDOW_SECONDS`
- 组合键判定窗口
## 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 恢复后,建议按这个顺序验证:
1. 确认 `evtest /dev/input/event2` 仍能看到:
- `PageUp`
- `PageDown`
2. 先同步本地最新 dashboard 代码到 Kindle
- 本轮已在本地加入一个“短按 `power` 提前唤醒后,额外保持 60 秒”的改动
- 相关配置在 `dash/src/local/env.sh`
- `MANUAL_WAKE_KEEP_AWAKE_SECONDS=60`
- `MANUAL_WAKE_EARLY_TOLERANCE_SECONDS=5`
- 相关运行逻辑在 `dash/src/dash.sh`
3. 重启 dashboard先单独验证短按 `power`
- 从休眠态短按 `power`
- 预期不再只亮约 3 秒
- 预期应保持约 60 秒再回到下一轮休眠
4. 让 dashboard 保持运行态,不进真 suspend
5. 手动启动菜单服务
6. 验证:
- 双键能否稳定打开菜单
- 单键移动是否会误触组合键
- 再次双键能否稳定确认
7. 验证主题切换后:
- 背景立即更新
- 时钟位置和方向保持正确
## 11. 结论
在当前仓库和 Kindle Voyage 的约束下,推荐采用下面这条路线:
- 监听 `/dev/input/event2`
- 用短时间窗口识别 `PageUp + PageDown` 组合键
- 在运行态下绘制一个 KUAL 风格的文本主题菜单
-`PageUp / PageDown` 导航
- 再次双键确认
- 最终复用现有 `switch-theme.sh` 完成主题切换
这是当前成本最低、最容易恢复、也最适合在 SSH 不稳定阶段先落地评审的方案。