Files
kindle-calendar/dash/docs/pagepress-theme-menu-plan.zh.md
2026-03-18 13:35:19 +08:00

452 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Kindle Dashboard 双翻页键主题菜单方案
## 0. 当前状态
本文是评审方案,不是实机结论。
补充说明:当前仓库默认已经不启用这套运行态菜单,主题切换入口只保留在 KUAL。
本文保留为备选方案与历史设计记录,不代表当前默认交互。
当前 Kindle 已掉出 Wi-FiSSH 中断,因此这份文档的目标是:
- 先把“左右同时按下翻页键,呼出主题选择页面”的方案固定下来
- 明确交互、进程模型、文件落点和风险
- 等 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 会在休眠路径里进入:
```sh
echo "mem" >/sys/power/state
```
一旦进入这个状态:
- 用户态 shell / Lua / evtest 监听器都会停掉
- 无法继续等待双键输入
因此本方案的有效范围是:
- dashboard 正在运行
- Kindle 尚未进入真正的 `mem` 挂起
这也是为什么本方案先聚焦:
- 运行态主题菜单
而不把目标直接扩展为:
- 真休眠态唤醒菜单
## 2. 目标
目标能力如下:
1. 用户在 dashboard 运行态下,同时按下左右翻页键
2. 屏幕弹出一个 KUAL 风格的主题选择页面
3. 用户通过翻页键在主题列表中移动选中项
4. 用户再次同时按下左右翻页键,确认并切换主题
5. 切换完成后,立即刷新背景和时钟
6. 菜单列表末尾可附带一个“返回首页”动作项,安全退出 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 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]`
-`/mnt/us/dashboard/stop.sh`
5. `switch-theme.sh` 继续负责:
- 同步主题配置
- 拉最新背景
- 刷新屏幕
- 重绘时钟
如果选中的是 `Return Home`,则不走主题切换,而是调用 `stop.sh`
- 停掉 dashboard 和菜单监听器
- 恢复 `framework / cvm / webreader`
- 回到 Kindle 首页
也就是说,菜单服务只负责:
- 触发
- 选择
- 调用已有切换入口
而不是重新实现一套主题切换。
## 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
export THEME_MENU_RUNTIME_DIR="/tmp/kindle-dash-theme-menu"
```
说明:
- `THEME_MENU_ENABLED`
- 总开关
- `THEME_MENU_EVENT_DEVICE`
- Voyage 上通常是 `event2`
- 后续换机型时可以只改这个
- `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 恢复后,建议按这个顺序验证:
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 风格的文本主题菜单
- 右下角长按也复用同一份菜单,而不是另起一套触摸 UI
-`PageUp / PageDown` 导航
- 再次双键确认
- 最终复用现有 `switch-theme.sh` 完成主题切换
这是当前成本最低、最容易恢复、也最适合在 SSH 不稳定阶段先落地评审的方案。
如果菜单需要提供稳定退出入口,也可以在列表末尾追加一个 `Return Home` 动作项。
实现上应复用 `stop.sh` 的保守恢复链路,而不要直接强拉 `booklet.home`