# DeepSeek 桌面版 **Repository Path**: windowsuninstaller/dsh-float ## Basic Information - **Project Name**: DeepSeek 桌面版 - **Description**: DeepSeek Harness 悬浮窗 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2026-09-29 - **Last Updated**: 2026-10-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: dsh-plugin ## README # dsh-float 一个用 Python + tkinter + [tkwry](https://pypi.org/project/tkwry/)(WebView2)写的 **DeepSeek 桌面客户端**(Windows)。 它把 [chat.deepseek.com](https://chat.deepseek.com) 和 DeepSeek Harness(DSH)本地工作台装进同一个窗口,用一条可拖动的悬浮栏在两种模式之间切换;不想看的时候按 `Alt+Space` 整个收走,或者缩成置顶小窗挂在屏幕角落。 当前版本:`0.6-alpha`(见 [main.py](main.py) 里的 `VERSION`)。各版本变更见 [CHANGELOG.md](CHANGELOG.md),本次发布的说明见 [RELEASE_v0.6-alpha.md](RELEASE_v0.6-alpha.md)。 ## 快速开始 ```powershell git clone https://gitee.com/windowsuninstaller/dsh-float.git cd dsh-float python -m venv .venv .venv\Scripts\activate pip install -r requirements.txt python main.py ``` > 第一次切到 `💻任务` 时,如果 DSH 服务还没起来,程序会立刻挂出一个本地的**等待页**:页面每秒自查一次,服务好了自己跳过去。 > > **主线程全程不阻塞**,窗口、悬浮栏、热键照常能用,不需要干等。DSH 首次启动要下载依赖,等几十秒属正常。 ## 操作一览 | 操作 | 效果 | | --- | --- | | 拖动悬浮栏(`\|\|` 或空白处) | 移动悬浮栏,位置会被限制在窗口范围内 | | 在悬浮栏上滚滚轮 | 放大 / 缩小悬浮栏字号 | | 点 `🐋聊天` | 切到 chat.deepseek.com | | 点 `💻任务` | 切到 DSH 本地工作台 | | 点 `🪟` | 大窗 ⇄ 小窗(500×740 置顶小窗) | | 点工具栏的 `🎨` / `🎬` / `🎵` | 弹出输入窗写下需求,包装成提示词发给 DeepSeek,产出存到 `outputs\` | | 点工具栏的 `📁` / `⚙️` | 打开图库 / 设置窗口 | | **右键悬浮栏** | 打开「关于」窗口 | | **Alt+Space** | 隐藏 / 唤回整个程序(系统级热键,窗口没焦点时也有效) | | 关主窗(大窗模式) | 退出程序 | | 关主窗(小窗模式) | 只是隐藏,等 `Alt+Space` 唤回 | | 关于窗里 `Esc` 或「关闭」 | 隐藏关于窗(内容留着,下次打开秒回) | | 关于窗里 `Ctrl+Shift+C` 或「复制」 | 复制当前 DSH 的 token | ## 功能 - **双模式同窗**:`🐋聊天` 加载 chat.deepseek.com,`💻任务` 加载 DSH 本地服务,两个 WebView 同时存在,切换只是 `lift()`,所以来回切不会重新加载页面。 - **共享会话**:两个 WebView 用同一个 `WebSession`,共用 `%TEMP%\deepseek-chromium_cache` 目录(v0.4-alpha 起从程序目录挪到临时目录,避开权限问题),一个 profile 只起一份 Chromium 家族。注意两个页面的域名不同(`chat.deepseek.com` 与本地 DSH 服务),所以**登录状态不互通,需要分别登录**。 - **悬浮切换器**:可拖到窗口任意位置,滚轮缩放字号,窗口缩放时会自动重新贴合、不会被挤出边界。 - **小窗模式**:切成 500×740 的置顶小窗并去掉任务栏条目;切回来时精确还原原来的尺寸、位置,连"进来之前是最大化"这件事都记得。 - **隐藏与唤回**:`Alt+Space` 通过 `RegisterHotKey` 注册成系统级热键,窗口没有焦点也能唤回。如果热键没注册成功(比如被别的程序占了),程序会**拒绝隐藏**——藏起来又没有唤回途径,窗口就真找不回来了。 - **关于窗口**:右键悬浮栏打开,实际是 [about.html](about.html) 渲染在共享会话的 WebView 里。显示版本号、当前 DSH token(可一键复制)、各站点入口和仓库地址,另外还埋了 4 个彩蛋(清单见 [egglist.html](egglist.html))。关闭只是隐藏,窗口和视图都留着,再次打开是瞬时唤醒,不用等 Chromium 重新加载。 - **开屏动画**:启动时用 `splash.png` 淡出,主窗从透明淡入。 - **对话模式生成引擎**([gen.py](gen.py)):工具栏是一条普通的 tkinter 控件(`🎨 🎬 🎵 | 📁 ⚙️`),只在对话模式显示。点生成按钮会弹窗问你想要什么,然后把需求包装成约定格式的提示词发给模型,再从回复里识别代码块、落地成文件: - **图片**:模型输出 `photocode` 里的 SVG,**在浏览器里用 canvas 转成 PNG**(Python 侧不依赖任何 SVG 渲染库),存 `outputs\image_*.png`。 - **视频**:模型输出 `videocode`,用 `---FRAME---` 分隔的多帧 SVG 逐帧渲染后交给 `imageio`(ffmpeg) 编成 H.264 MP4,存 `outputs\video_*.mp4`;若已有音乐,会自动混音生成 `*_with_music.mp4`。 - **音乐**:模型输出 `musiccode` 里的 JSON 乐谱,由 [gen.py](gen.py) 用 numpy 合成波形、`wave` 落盘成 `outputs\music_*.wav`,支持 `piano/sine/square/saw/triangle/strings/pad/pluck/bell/organ/flute/bass` 等音色。 - 需求**可以留空**,那就让模型自由发挥。回复被截断时自动点「继续生成」;检测到**深度思考**开着会先提示(会拖慢响应、也可能把代码块拆散)。 - 工具栏上的 `📁` 打开图库(浏览 `outputs\` 里生成的东西,双击用系统默认程序打开)、`⚙️` 打开设置(是否提示深度思考、是否自动给视频配乐、是否自动点继续)。 - 工具栏本身**不注入网页**——它和悬浮栏一样是本地控件,所以不受 `chat.deepseek.com` 改版影响。仍然依赖网页结构的只有「填输入框、找发送键、抓代码块」这几个动作。 - **高 DPI**:启动时 `SetProcessDPIAware()`。这是较老的 system-DPI-aware 方案,多显示器不同缩放比例时仍可能偏糊。 ## 环境要求 - Windows 10 / 11 - Python 3.10+(开发环境 3.13.7) - [WebView2 Runtime](https://developer.microsoft.com/microsoft-edge/webview2/)(Windows 11 一般已内置) - [Node.js](https://nodejs.org/)(`npx` 可用,`💻任务` 模式需要它拉起 DSH 服务) ## 依赖 运行依赖见 [requirements.txt](requirements.txt): ```text tkwry==0.1.9 # 对话模式生成引擎(gen.py):音乐合成、视频编码 numpy imageio imageio-ffmpeg Pillow ``` `numpy` 只在合成音乐时用,`imageio` + `imageio-ffmpeg` + `Pillow` 只在合成视频时用——图片生成全程在浏览器里完成,不需要它们。`imageio-ffmpeg` 自带一份 ffmpeg 二进制(约 31 MB),不需要另外装 ffmpeg。 打包依赖见 [requirements-dev.txt](requirements-dev.txt): ```text -r requirements.txt pyinstaller==6.22.3 ``` ## 打包 ```powershell make.cmd ``` [make.cmd](make.cmd) 做了四件事: 1. 激活 `.venv` 2. `pyinstaller --icon=favicon.ico --noupx main.py` 3. 把 `favicon.ico`、`splash.png`、`about.html`、`wait.html` 复制到 `dist\main\` 4. 产物在 `dist\main\`,双击 `main.exe` 即可运行 打包出的 `main.spec` 是 PyInstaller 自动生成的中间文件,已被 `.gitignore` 忽略。 ## 项目结构 ```text dsh-float/ ├── main.py # 主程序:窗口、悬浮栏、双 WebView、热键、关于窗 ├── gen.py # 对话模式生成引擎:tkinter 工具栏、图片/视频/音乐落地、图库、设置 ├── dsh.py # 探测 3080 端口、冷启动 DSH 服务、解析带 token 的地址、托管等待页 ├── wait.html # 冷启动等待页,由 dsh.py 起的本地临时服务托管 ├── about.html # 「关于」窗口的页面(含 4 个彩蛋) ├── egglist.html # 彩蛋清单,嵌在 about.html 的 iframe 里 ├── splash.png # 开屏动画图片 ├── favicon.ico # 程序图标 ├── logo.svg # Logo ├── make.cmd # 一键打包脚本 ├── requirements.txt # 运行依赖 ├── requirements-dev.txt # 开发 / 打包依赖 ├── LICENSE # MIT 许可证 └── .gitignore # Git 忽略规则 ``` 生成的东西统一放在程序目录下的 `outputs\`(首次生成时自动创建,已被 `.gitignore` 忽略)。 ## 已知限制 这些都是当前实现真实存在的取舍,不是"以后可能会": - **内存占用偏高**:两个模式的 WebView 同时常驻,等于两份渲染进程,通常几百 MB 起。换模式不用重新加载,代价就在这里。 - **冷启动要等**:DSH 服务由 `npx` 拉起,包已缓存时从进程创建到端口可监听约 5~6 秒,首次还要下载依赖、会更久。但等待期间界面**不阻塞**——程序立刻返回一个本地等待页,页面每秒轮询 `/now`,服务就绪后自动跳转;`Alt+Space`、切模式、缩窗这些操作全程可用。 - **`Alt+Space` 是系统级热键**:注册成功之后它在本机是全局独占的,其他程序的窗口系统菜单用这个组合键就用不了了。这是换"窗口没焦点也能唤回"必须付的账。 - **退出程序不会结束 DSH 服务**:`npx @deepseek-ai/dsh web` 是子进程起的,主程序退出不会带走它,3080 端口和那份内存会继续留着,需要手动结束进程。下次启动如果发现 3080 已在监听,会跳过启动、直接复用。 - **关于窗隐藏后定时器还在跑**:关掉关于窗只是 `withdraw()`,`winfo_exists()` 对隐藏窗口仍然返回 `True`,所以那个每 120ms 取一次页面指令的轮询不会自己停。功能无影响,属于白耗电。 - **打包是控制台版**:[make.cmd](make.cmd) 没有 `--windowed`,运行时会带一个命令行黑框。想改成无控制台,得先把代码里的 `print()` 都处理掉——`--windowed` 下 `sys.stdout` 是 `None`。 - **打包漏了 `egglist.html`**:[about.html](about.html) 用 iframe 嵌了 [egglist.html](egglist.html),但 [make.cmd](make.cmd) 没有把它复制进 `dist\main\`,打包版里那份彩蛋清单是空的(源码运行不受影响)。 - **图标缺失会崩**:启动时 `root.iconbitmap("favicon.ico")` 没有做异常保护,如果打包时漏拷图标,程序会直接起不来。 - **token 是明文显示的**:关于窗里的令牌就是 DSH 的真实访问凭证,截图分享前记得注意。 - **缓存目录含登录数据**:WebView2 的缓存与登录态现在放在 `%TEMP%\deepseek-chromium_cache`,别随手打包发人。`.gitignore` 里那条 `chromium_cache` 保留着,用来兜住旧版本遗留在项目目录里的同名文件夹。 - **生成功能部分依赖网页结构**:[gen.py](gen.py) 里下发给页面的脚本仍要去 `chat.deepseek.com` 的 DOM 里找输入框、发送键、思考状态、代码块,**这些选择器会随 DeepSeek 改版失效**。发送键那条尤其脆——它现在不是 `