[提案] 接续 #716:修好桌面端并做 macOS 适配

Author: leanderfortune-archCreated Jul 27, 2026Updated Jul 27, 2026

[提案] 接续 #716:修好桌面端并做 macOS 适配

背景

@litongjava 在 #716 贡献了 Tauri 客户端并被合入,当时讨论里提到「很期待你分享下一步计划,我们可以一起讨论合适的方案」。此后 src-tauri/ 没有再更新过(最后一次实质改动是 2023-11-29)。

我想把桌面端用起来,于是先在本地做了一版,现在能跑了,想按 CONTRIBUTING 的要求开 issue 对齐一下方向,再决定怎么拆 PR 提过来。

可以直接试

桌面端为什么跑不起来

src-tauri/ 是随 #716 一次性加入的,那次改动只涉及该目录下的 22 个文件,没有触及 package.json。核实历史后确认 @tauri-apps/cli 从未进入过依赖,也没有 tauri 相关的 npm script,因此桌面端从一开始就没有接进项目自己的工具链,需要开发者自行全局安装 tauri-cli,README 里也没有说明。

除此之外还有几处:

问题 说明
dev 模式端口错配 devUrl 指向 3000,而 Vite 监听 5173,tauri dev 连不上
Tauri 版本 停留在 1.4,配置格式与 2.x 不兼容
Cargo.toml 仍是脚手架默认值:name = "app"authors = ["you"]、license / repository 为空
bundle identifier 指向贡献者个人域名而非项目
图标 是贡献者自己的 logo,不是 Qwerty Learner 的
无 CI 没有桌面端构建或产物发布流程

一个顺带发现的仓库级问题

.gitattributes* text eol=lf 会对所有未声明为 binary 的文件做换行符转换。*.icns 不在声明列表中,导致 src-tauri/icons/icon.icns 入库时被改写:仓库里的 blob 比工作区文件少 10 字节,iconutil 无法解析,macOS 也就取不到小尺寸图标,Dock 里显示为空白。

同样未被声明的还有 *.jpg*.jpeg 声明了但 *.jpg 漏了)和 13 个 *.mp3 按键音效。这两类目前没有损坏——它们恰好不含 CRLF 字节对——但只要哪天替换素材就可能中招。

已经做完的部分

分支上共 12 个提交,都能单独 review。除桌面端本身外,过程中修掉了几个 Web 端同样存在的问题:

缩放窗口会丢失练习进度src/index.tsx)。resize 处理里只要视口宽于移动端断点就执行 window.location.href = '/',而这在每一次 resize 事件上都会触发,不只是跨越断点时。结果是桌面视口下任何一次缩放都会重载整个应用:当前单词、章节位置、本次统计全部丢失,并且会被从所在页面弹回打字页。浏览器里不容易遇到,桌面窗口则是频繁操作。

发音请求未转义src/hooks/usePronunciation.ts)。词条被原样拼进查询串,含 &# 的词会产生非法 URL。另外把下划线换成空格能救回一部分词条(Machine_LearningNeural_NetworkData_Mining 由 500 变 200),但不是完整修复——dictvoice 是词典查询而非语音合成,它未收录的条目(Computer_Vision、编程词库的 __init__(self, args) 一类)两种写法都返回 500。

词典选择器裁掉自己的内容src/pages/Gallery-N/)。内容列按最宽子元素撑开,父级又是居中对齐,于是标签行一旦宽于视口,整列会向两侧同时溢出,左边那截既被裁掉又滚不到——前几个语言标签和第一张卡片的左半边都点不到。顺带把固定宽卡片配等分列造成的大片空隙也调了。

macOS 适配:Command 快捷键(⌘J 重听、⌘⇧←/→ 切词,经由 react-hotkeys-hookmod 修饰键,Ctrl 继续有效)、深色模式跟随系统直到用户手动切换、窗口默认与最小尺寸、菜单栏显示产品名。

发音本地缓存:桌面端经由自定义 scheme 在 Rust 侧下载并落盘,命中缓存不再走网络,离线可用。放在 Rust 是因为 dict.youdao.com 不返回 Access-Control-Allow-Origin,webview 里读不到响应体。只缓存 200 且 Content-Type: audio/* 的响应——接口对查不到的词返回 500 加一段 JSON,不能当音频存下来。

通用二进制与 CIuniversal-apple-darwin 构建,workflow 在打 tag 或手动触发时产出 .app.dmg

关于「不影响现有代码」

#716 当时确认过的前提是不影响既有代码,我想把现在的实际情况说清楚:桌面端相关改动确实收敛在 src-tauri/ 与少量按平台分支的代码里,Web 构建产物与行为不变。但上面那几个 bug 修复确实修改了 src/,因为它们在 Web 端同样存在。这些改动我都放在独立提交里,与桌面端改动分开,方便单独取舍——如果希望它们走独立 PR、或者干脆不要,都可以。

想确认的问题

  1. 项目是否仍希望保留并维护仓库内的桌面端?如果倾向于让社区的 Pake 打包版继续承担这个角色,我就不占用大家的 review 精力了。
  2. 若保留,是否接受升级到 Tauri 2?这会改变现有配置格式。
  3. bundle identifier 用什么?我暂时按官网域名反写填了 cool.kaiyi.qwerty-learner,这个应该由你定。
  4. 是否需要兼顾 Windows / Linux?我只有 macOS 环境,可以保证不破坏其构建配置,但无法实机验证,需要其他同学帮忙测。
  5. 上面那几个 Web 端 bug 修复,希望合在这一系列里,还是单独提 PR?
  6. 分发环节:项目有 Apple Developer 证书吗?没有的话 CI 只能产未签名产物,用户需要在「系统设置 → 隐私与安全性」手动放行;我在 workflow 里留了注释说明证书就位后要配哪些 secret。

方向没问题的话,我按上面的拆分开 draft PR,从「修好构建」那部分开始,方便早期收反馈。

另外 @litongjava,桌面端最初是你贡献的,如果你还想继续推进,我很乐意配合而不是另起炉灶。

Source: RealKai42/qwerty-learner