[AI Development Lab] deepin插件开发活动+剪贴板历史助手 Clipboard Helper
Tofloor
poster avatar
182******29
deepin
9 hours ago
Author

源码仓库链接

  • https://github.com/helloworldpxy/clipboard-helper
  • https://gitee.com/helloworldpxy/clipboard-helper

项目文档

功能特性

自动记录

  • 监听系统剪贴板,自动保存 文本、图片、文件路径、富文本 四类内容
  • 记录优先级:图片 > 文件路径 > 富文本 > 纯文本(浏览器复制图片时常见同时带 HTML 与图片,优先保留图片)
  • 支持从任意应用复制,无需手动操作

历史管理

  • 历史列表按时间倒序展示,最近复制内容在最前
  • 固定收藏的条目永远置顶,不受淘汰规则影响
  • 关键词实时搜索过滤历史记录
  • 双击(或回车)将历史内容重新复制回剪贴板
  • 右键菜单:复制 / 固定 / 取消固定 / 删除 / 清空全部
  • 历史上限自动淘汰:超过上限自动清理最旧的未固定记录(默认 500 条,可配置 50–5000)

数据安全

  • 本地 SQLite 存储,参数化查询防止 SQL 注入
  • 单条大小上限:文本/文件路径/富文本 512KB,图片 8MB,超大内容直接忽略
  • 数据库总量上限 512MB,防止磁盘被撑满
  • 所有数据仅保存在本机,不会上传任何服务器
  • 数据位置:~/.local/share/deepin/clipboard-helper/history.db

便捷交互

  • 托盘图标(SNI 协议,deepin 25 兼容):单击唤出悬浮窗,右键菜单含主界面 / 设置 / 退出
  • 悬浮窗:毛玻璃(DBlurEffectWidget)迷你历史窗口,可置顶、可拖动,靠近光标弹出
  • 全局热键:任意应用中按下组合键唤出/隐藏悬浮窗
    • 默认 Ctrl+Shift+V可在设置中自定义(如 Ctrl+Alt+VSuper+V),留空即禁用
    • 仅 X11 会话支持;Wayland 会话下自动跳过
  • 开机自启动:设置中一键开启

配置项(DConfig)

配置文件:org.deepin.clipboardhelper.settings

类型 默认值 说明
maxHistoryCount int 500 历史上限(50–5000)
recordImages bool true 记录图片
recordHtml bool true 记录富文本
showTrayIcon bool true 显示托盘图标
autoStart bool false 开机自启动
globalHotkey string Ctrl+Shift+V 全局热键,留空禁用

所有配置均可在「设置」对话框可视化修改。

界面

  • 主界面:历史列表 + 搜索框 + 内容预览(文本预览 / 图片缩略图 / 文件路径 / 富文本),顶部为固定条目
  • 悬浮窗:紧凑布局的迷你历史列表,点击即复制,适合快速粘贴
  • 设置:行为(自启动/托盘)、记录(图片/富文本)、历史上限、全局热键

构建

依赖:

sudo apt install cmake g++ \
  qt6-base-dev libqt6sql6-sqlite \
  libdtk6core-dev libdtk6gui-dev libdtk6widget-dev \
  xclip

全局热键需要 X11 与 xcb 开发库(libx11-devlibxcb1-dev)。

编译安装:

mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install

安装内容:

  • /usr/local/bin/clipboard-helper:可执行程序
  • /usr/local/share/applications/clipboard-helper.desktop:桌面入口
  • /usr/local/share/icons/clipboard-helper.svg:应用图标
  • /usr/local/share/dsg/configs/org.deepin.clipboardhelper/:DConfig 配置元信息

运行

从应用启动器运行「剪贴板历史」,或命令行执行:

clipboard-helper
  • 首次启动即开始监听剪贴板,托盘图标出现
  • 已运行实例不会重复启动(单实例)
  • 卸载清理:删除 ~/.local/share/deepin/clipboard-helper/ 即清除全部历史数据

命令行参数

参数 说明
--show 启动时直接显示主窗口
--settings 启动时打开设置对话框
--search <关键词> 启动时在搜索框预填关键词并实时过滤历史列表

示例:

clipboard-helper --show --search deepin

开发过程说明

一、项目概述

  • 作品名称:剪贴板历史助手 Clipboard Helper
  • 开发方向:DTK 创新原生应用(dtk-development Skill)
  • 技术栈:DTK6 / Qt6 / C++17 / SQLite3
  • 版本:v0.8.0-7
  • 许可:GPL-3.0
  • 核心功能:自动记录、搜索、管理剪贴板内容(文本 / 图片 / 文件路径 / 富文本),提供托盘常驻、毛玻璃悬浮窗、全局热键、开机自启动

二、需求来源

日常使用电脑时经常遇到以下痛点:

  1. 复制了内容又被覆盖,想找回刚才复制的东西
  2. 跨应用粘贴时反复切换窗口复制粘贴
  3. deepin 自带剪贴板功能单一,无法按关键词搜索历史

于是决定做一个面向 deepin 25 的剪贴板历史管理工具,作为本次 deepin 插件开发活动的参赛作品。

三、开发流程(AI + deepin Skills)

3.1 准备阶段

  • 按活动指引安装 deepin Skills:bash <(curl -fsSL https://raw.githubusercontent.com/linuxdeepin/deepin-skills/master/scripts/install.sh)
  • 选定方向为「DTK 创新原生应用」,加载 dtk-development Skill

3.2 使用 Skill 的过程

开发全程由 AI 编程工具(opencode)配合 dtk-development Skill 完成:

环节 Skill 提供的指导 实际应用
应用骨架 DTK6 CMake 模板、DApplication 用法 CMakeLists.txtmain.cpp 入口
托盘常驻 DApplication 单实例、托盘应用规范 trayicon.cpp(SNI 协议)
悬浮窗 DBlurEffectWidget 毛玻璃规范 floatingwindow.cpp
配置管理 DConfig 路径规范({appId}/{configId}.json assets/config/*.json、设置对话框
主题适配 DIconTheme 图标查找规范 应用图标、托盘图标
打包 deb 构建流程(debuild/dh) debian/ 打包

3.3 功能实现

剪贴板监听(ClipboardManager)

  • 监听系统剪贴板变化,自动保存四类内容
  • 记录优先级:图片 > 文件路径 > 富文本 > 纯文本(处理浏览器复制图片同时携带 HTML 的场景)

数据存储(HistoryDb)

  • SQLite 本地存储,参数化查询防注入
  • 单条大小上限(文本 512KB / 图片 8MB)、总量上限 512MB 防磁盘撑满
  • 固定条目置顶、历史上限自动淘汰

交互界面

  • 主窗口:历史列表 + 实时搜索 + 内容预览
  • 悬浮窗:DBlurEffectWidget 毛玻璃、点击即复制、靠近光标弹出
  • 托盘:左键悬浮窗、中键粘贴最近一条、右键菜单

全局热键(GlobalHotkey)

  • XGrabKey + 原生事件过滤器实现(X11)
  • 设置中可自定义组合键,留空禁用,Wayland 下自动跳过

四、开发中遇到的问题与解决

4.1 DConfig 配置读不到(安装后)

  • 现象Can't load resource: /org.deepin.clipboardhelper.settings, for the appid:[clipboard-helper],设置无法持久化
  • 排查:按 dtk-development
  • 根因​:安装到了 /usr/share/dsg/configs/org.deepin.clipboardhelper/(用了 configId 当目录名)
  • 解决:改为 /usr/share/dsg/configs/clipboard-helper/org.deepin.clipboardhelper.settings.json

4.2 依赖版本过严导致 apt 卸载

  • 现象:朋友安装后 apt -f install 提示卸载包
  • 根因​:自动生成的 libdtk6core (>= 6.7.47.1)libqt6core6 (>= 6.8.0) 版本下限过高
  • 解决debian/control 手写宽松依赖(DTK/Qt >= 6.5.0),兼容 deepin 25 各版本

4.3 关闭终端杀死进程

  • 现象:从终端启动后关终端,进程和托盘被杀死
  • 解决:main 入口忽略 SIGHUP

4.4 关闭主窗口后托盘被杀

  • 现象:点关闭按钮,整个应用退出、托盘消失
  • 解决:重写 MainWindow::closeEvent 隐藏到托盘 + setQuitOnLastWindowClosed(false),退出统一走托盘菜单

4.5 关于对话框英文 / deepin.org

  • 现象:关于页显示英文(Version/Website/License)且链接指向 deepin.org
  • 解决:恢复 loadTranslator() 加载 DTK 内置中文翻译;setApplicationHomePage() 指向作者 GitHub;自定义中文 DAboutDialog

4.6 标题栏英文菜单

  • 现象:标题栏菜单有重复的「关于 / About」「Exit」
  • 解决:隐藏 titlebar 菜单按钮,功能统一收敛到托盘中文菜单

4.7 无合成器环境渲染兼容

  • 现象:Xvfb / 远程桌面下 XRecord 监听线程干扰 Qt 渲染
  • 解决:全局热键由 XRecord 线程改为 XGrabKey + 原生事件过滤器

五、测试与打包

5.1 功能测试

用例 方法 结果
文本记录 `echo "hello" xclip -selection clipboard`
图片记录 xclip -i -t image/png 通过
文件路径 复制文件路径 通过
全局热键 任意应用按 Ctrl+Shift+V 通过(X11)
托盘保活 关闭主窗口后进程保持 通过
配置持久化 修改设置后重启应用 通过

5.2 打包

  • 使用 debuild 生成 deb 包,安装到 /usr/bin/usr/share
  • lintian 检查通过(仅无警告级 no-manual-page)

六、AI 使用情况(附对话截图)

本次开发全程使用 AI 编程工具(opencode),加载 deepin Skills 完成:

  • Skill 使用dtk-development(主)、参照 DConfig / DTitlebar / DAboutDialog 等规范文档
  • 对话截图:见参赛材料中的 AI 对话截图(开发过程截图)
  • AI 承担工作:代码编写、CMake/deb 打包配置、DConfig 路径修正、托盘保活、界面中文化、问题排查

说明:AI 生成的代码均在 deepin 25 真实环境编译、安装、运行验证通过,并交付给独立测试者验证安装与使用。

七、作品亮点

  1. 实用主义:从真实需求出发(找回被覆盖的复制内容),非炫技
  2. 四类内容:文本/图片/文件路径/富文本全支持,优先级智能处理
  3. 数据安全:纯本地存储、参数化防注入、大小上限保护
  4. 交互顺手:托盘 + 悬浮窗 + 全局热键,多入口零打扰
  5. 工程规范:DConfig 规范路径、deb 打包、GPL-3.0 开源

截图

01-主窗口.png

02-悬浮窗.png

03-设置对话框.png

04-搜索过滤.png

Reply Favorite View the author
All Replies
avatar
𰻞𰻝面
deepin
9 hours ago
#1

好东西啊,给你点赞👍

kissing_heart

Reply View the author
avatar
骑🐖追帅哥bot
Moderator
9 hours ago
#2
It has been deleted!
avatar
骑🐖追帅哥bot
Moderator
9 hours ago
#3

Reply View the author
avatar
鲜衣怒马
deepin
9 hours ago
#4

有两把梳子-嘻嘻

Reply View the author