# ukui-search **Repository Path**: openkylin/ukui-search ## Basic Information - **Project Name**: ukui-search - **Description**: 请把pr提到real-upstream分支哦 - **Primary Language**: Unknown - **License**: GPL-3.0 - **Default Branch**: real-upstream - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 27 - **Forks**: 30 - **Created**: 2022-01-21 - **Last Updated**: 2026-09-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # UKUI Search UKUI Search 是 UKUI 桌面环境的全局搜索应用及本地搜索服务集合,提供文件、目录、 文本内容、应用、设置项、Web 和 AI 等聚合搜索能力。项目同时提供可复用的 C++ 搜索 库和基于 UKUI Quick widget 的搜索应用扩展机制。 当前默认界面位于 `ukui-search-qml/`。`frontend/` 中保留的是旧 Qt Widgets 界面, 不属于当前默认构建。 ## 主要功能 - 搜索文件名、目录名和文本内容,并按相关性、时间等条件排序或筛选。 - 使用文件索引快速检索,并通过文件系统监听增量更新索引。 - 对配置允许的文档提取文本,对配置允许的图片执行 OCR 后建立内容索引。 - 搜索本地应用和软件商店中的在线应用。 - 搜索控制面板设置项。 - 提供 Web 搜索、AI 搜索和 AI 即时回答等可选能力。 - 文件名、应用名和设置项支持中文、拼音及拼音首字母匹配。 - 通过 C++ 接口和插件接口扩展搜索数据源。 部分功能依赖 UKUI 桌面组件、麒麟软件商店或 AI 服务。依赖不可用时,相应搜索类别 或操作可能不可用,但不影响其他本地搜索功能。 ## 项目结构 | 目录 | 说明 | | --- | --- | | `libsearch/` | 共享搜索库,包含文件搜索、路径搜索、索引、应用数据和插件契约 | | `ukui-search-qml/` | 当前默认的 QML 搜索界面及宿主逻辑 | | `ukui-search-qml/widgets/` | 内置搜索 widget;每个 widget 包含 C++ `plugin/` 和 QML `widget/` | | `ukui-search-service/` | 文件名、内容、OCR 和 AI 索引服务 | | `ukui-search-service-dir-manager/` | 搜索目录、黑名单和可移动设备管理服务 | | `ukui-search-app-data-service/` | 本地应用信息数据库服务 | | `ukuisearch-systemdbus/` | 按需加载的 system D-Bus 模块,用于受限的系统配置操作 | | `search-ukcc-plugin/` | 控制面板中的搜索配置插件 | | `libchinese-segmentation/` | 中文分词子模块 | | `data/`、`translations/` | 桌面文件、GSettings schema、资源和翻译 | | `libsearch/autotest/`、`ukui-search-qml/autotest/`、`tests/` | 自动化测试 | 主要运行组件如下: | 组件 | 作用 | | --- | --- | | `ukui-search` | 全局搜索界面 | | `ukui-search-service` | 文件索引服务和索引监视窗口 | | `ukui-search-service-dir-manager` | 索引目录与存储设备管理 | | `ukui-search-app-data-service` | 应用数据采集和查询服务 | | `libinotify-config-service.so` | 由 system D-Bus 按需加载的系统服务模块,不是独立常驻进程 | 安装后的用户态组件通常由 UKUI 会话通过 XDG Autostart 或 D-Bus 激活启动。 ## 构建 ### 构建要求 完整构建至少需要: - CMake 3.16 或更高版本,以及支持 C++20 的编译器; - Qt 5 或 Qt 6,包含 Core、DBus、Gui、Qml、Quick、Widgets、Network、Sql、 Concurrent、Xml 和 RemoteObjects 等模块; - Boost 1.70 或更高版本; - GLib/GIO、GSettings Qt、Xapian 和 pkg-config; - `ukui-quick`、`ukui-file-metadata` 及工程所使用的 Kylin SDK/AI 开发组件。 不同发行版的开发包名称并不相同。CMake 会报告缺失的组件,发行包构建应以对应的 packaging 分支为准。 ### 初始化源码 仓库包含 `libchinese-segmentation` 子模块。首次构建前执行: ```shell git submodule update --init --recursive ``` ### 配置与编译 ```shell cmake -S . -B build -DBUILD_TEST=ON cmake --build build -j"$(nproc)" ``` 主要构建产物包括: | 产物 | 默认位置 | | --- | --- | | `ukui-search` | `build/ukui-search-qml/ukui-search` | | `ukui-search-service` | `build/ukui-search-service/ukui-search-service` | | `ukui-search-service-dir-manager` | `build/ukui-search-service-dir-manager/ukui-search-service-dir-manager` | | `ukui-search-app-data-service` | `build/ukui-search-app-data-service/ukui-search-app-data-service` | | `libukui-search.so` | `build/libsearch/` | | `libchinese-segmentation.so` | `build/libchinese-segmentation/` | | `libsearch-ukcc-plugin.so` | `build/search-ukcc-plugin/` | | `libinotify-config-service.so` | `build/ukuisearch-systemdbus/` | 完整界面依赖已安装的 UKUI Quick 运行环境、widget 元数据和桌面服务。在具备相应环境 时,可以从构建目录启动: ```shell ./build/ukui-search-qml/ukui-search --show ``` 如需安装全部组件,可执行: ```shell sudo cmake --install build ``` 安装路径中包含 `/usr`、`/etc` 等系统目录,建议在专用开发环境或打包环境中执行, 不要覆盖正在使用的发行版软件包。 ## 测试 `BUILD_TEST=ON` 额外需要 Python 3 和 `dbus-run-session`。Search 的 CTest 入口会在 测试进程启动前创建独立的临时 HOME、XDG 目录和无桌面服务的 D-Bus 总线,使用 内存 GSettings。不要直接运行会删除索引或配置的测试二进制;需要传入 QtTest 用例名等参数时,使用同一个启动器: ```shell python3 tests/run-isolated-test.py /usr/bin/dbus-run-session \ build/ukui-search-service-dir-manager/autotest/configTest \ testSaveHandlesConfigDirCreationFailure ``` 这类测试会在静态初始化期间缓存 HOME 路径,因此在测试的 `main()` 或 `initTestCase()` 中才修改 HOME 无法保护真实用户数据。 新增 Search 测试使用 `add_isolated_test(...)` 注册;`testIsolationTest` 会检查注册入口。 启动器统一覆盖 HOME/XDG 路径(包括 CTest 的 ENVIRONMENT 属性),测试不要另外声明这些 属性,需要专用子目录时从 `UKUI_SEARCH_TEST_ROOT` 派生。会删除数据的测试还必须在进入 测试用例前调用 `requireSearchTestIsolation()`,拒绝绕过启动器直接运行。该检查只保护主动 接入的测试;临时目录和私有总线也不等同于文件系统沙箱,测试不能操作约定目录以外的数据。 运行完整测试套件: ```shell ctest --test-dir build --output-on-failure ``` 运行需要图形环境的 Qt 测试时,可以使用无界面平台插件: ```shell QT_QPA_PLATFORM=offscreen ctest --test-dir build --output-on-failure ``` 迭代时可运行指定测试: ```shell ctest --test-dir build --output-on-failure \ -R 'search-session-test|fileSearchCoreTest' ``` ## 使用 ### 快捷键和命令行 UKUI 默认使用 `Super+S` 呼出搜索界面,快捷键由桌面会话配置管理。 `ukui-search` 支持: | 选项 | 说明 | | --- | --- | | `-h, --help` | 显示帮助 | | `-v, --version` | 显示版本 | | `-q, --quit` | 退出正在运行的搜索应用 | | `-s, --show` | 显示搜索主窗口 | `ukui-search-service` 支持: | 选项 | 说明 | | --- | --- | | `-h, --help` | 显示帮助 | | `-v, --version` | 显示版本 | | `-q, --quit` | 停止服务 | | `-m, --monitor` | 显示索引监视窗口 | | `-s, --status` | 显示文件索引服务状态 | | `-u, --update ` | 中止当前索引任务并执行增量更新 | `--update` 的 `indexType` 可取 `all`、`basic`、`content`、`ocr` 或 `ai`。 `ukui-search-service-dir-manager` 和 `ukui-search-app-data-service` 也支持 `--help`、`--version` 和 `--quit`。 ### D-Bus 接口 `ukui-search` 在 session bus 上提供以下接口: | 属性 | 值 | | --- | --- | | Service | `com.ukui.search.service` | | Object path | `/` | | Interface | `org.ukui.search.service` | | 方法 | 说明 | | --- | --- | | `showWindow()` | 显示搜索主窗口 | | `mainWindowSwitch()` | 切换搜索主窗口的显示状态 | | `searchKeyword(String keyword)` | 显示主窗口并搜索指定关键词 | 例如: ```shell dbus-send --session --type=method_call \ --dest=com.ukui.search.service / org.ukui.search.service.showWindow dbus-send --session --type=method_call \ --dest=com.ukui.search.service / org.ukui.search.service.searchKeyword \ string:'搜索关键词' ``` ### 桌面组件集成 - 设置项搜索使用 `org.ukui.ukcc.search` 提供的数据。 - 在线应用搜索和安装操作依赖麒麟软件商店。 - 应用启动、快捷方式和卸载操作会使用 UKUI 进程管理、任务栏等桌面服务。 - 文件操作优先复用 Peony 兼容菜单和文件管理能力。 - AI 搜索和即时回答依赖对应的 Kylin SDK、数据服务或本地 KylinBot gateway。 ## 文件索引 文件和目录名称搜索会根据当前索引状态选择索引搜索或直接搜索: - 直接搜索遍历指定目录,不依赖预建数据库;适合索引未开启或尚未就绪的情况。 - 索引搜索读取预建数据库,响应更快。首次启用时需要遍历文件,期间结果可能不完整。 基础索引、文本内容索引和 OCR 内容索引相互独立。索引完成后,服务通过文件系统监听 增量更新;服务重启或数据库异常时会校验或重建索引。实际耗时取决于文件数量、大小、 类型和机器性能。 内容搜索基于文本提取、分词和倒排索引,不保证任意子字符串都能命中。停用词、加密 文件和无法解析的格式通常不会产生内容结果。支持的文档和图片格式由索引配置决定, 以 [GSettings schema](data/org.ukui.search.data.gschema.xml) 和运行时配置为准,避免在 文档中维护容易过期的固定格式清单。 搜索目录、排除目录和外接设备索引范围可由控制面板配置。 ## 配置、用户数据和日志 主要文件型配置和用户数据位于: ```text ~/.config/org.ukui/ukui-search/ ``` 常见内容如下;文件或目录仅在对应功能使用后创建: | 路径 | 说明 | | --- | --- | | `ukui-search.conf` | 搜索界面配置 | | `ukui-search-service.conf` | 索引目标类型等服务配置 | | `ukui-search-dirs.json` | 当前搜索目录、排除目录和外接目录配置 | | `ukui-search-index-status.conf` | 各类索引状态和数据库版本记录 | | `ukui-search-history.json` | 最近搜索和操作历史 | | `appdata/app-info.db` | 本地应用信息数据库 | | `index_data/` | 文件名基础索引 | | `content_index_data/` | 文本内容索引 | | `ocr_content_index_data/` | OCR 内容索引 | | `kylinbot-instant-answer.json` | KylinBot gateway 配置和认证状态 | `ukui-search-block-dirs.conf` 和 `ukui-search-current-indexable-dir.conf` 是旧版本配置, 当前目录管理服务只在兼容迁移时读取它们。部分开关保存在 GSettings schema `org.ukui.search.settings` 中。 索引数据库包含从本地文件提取的可搜索信息,KylinBot 配置可能包含认证数据。不要将 这些目录、配置或日志提交到代码仓库,也不要在未经检查的情况下对外分享。删除索引 数据库后,索引服务会在功能再次启用时重建数据。 日志由各组件自动创建在: ```text ~/.log/ukui-search/ ``` 常见日志名为 `ukui-search-{0,1}.log`、`ukui-search-service-{0,1}.log`、 `ukui-search-service-dir-manager-{0,1}.log` 和 `ukui-search-app-data-service-{0,1}.log`。每个组件使用两个日志文件,每个文件上限约 4 MiB,无需预先创建空日志文件。 ## 开发接口 ### 使用 libukui-search 安装开发文件后,可以通过 CMake package 使用共享库: ```cmake find_package(ukui-search CONFIG REQUIRED) target_link_libraries(your-target PRIVATE ukui-search) ``` 也可以通过 pkg-config 的 imported target 使用: ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(UKUI_SEARCH REQUIRED IMPORTED_TARGET ukui-search) target_link_libraries(your-target PRIVATE PkgConfig::UKUI_SEARCH) ``` `UkuiSearchTask` 当前内置的任务类型是 `File`、`FileContent` 和 `Application`。 下面是文件名搜索的最小使用片段;搜索是异步的,`UkuiSearchTask` 必须在搜索结束前保持 存活,调用方还需要运行 Qt 事件循环: ```cpp #include #include #include #include void startFileSearch(UkuiSearch::UkuiSearchTask &task) { auto *results = task.init(); task.initSearchPlugin(UkuiSearch::SearchProperty::SearchType::File); task.addSearchDir(QDir::homePath()); task.addKeyword(QStringLiteral("报告")); task.setOnlySearchFile(true); task.setResultProperties( UkuiSearch::SearchProperty::SearchType::File, {UkuiSearch::SearchProperty::FilePath, UkuiSearch::SearchProperty::FileName}); QObject::connect( &task, &UkuiSearch::UkuiSearchTask::searchFinished, &task, [results](size_t searchId) { while (!results->isEmpty()) { const auto result = results->dequeue(); if (result.getSearchId() == searchId) { qDebug() << result.getValue(UkuiSearch::SearchProperty::FilePath); } } }); task.startSearch(UkuiSearch::SearchProperty::SearchType::File); } ``` 完整接口以 [ukui-search-task.h](libsearch/searchinterface/ukui-search-task.h)、 [search-result-property.h](libsearch/searchinterface/search-result-property.h) 和对应测试为准。 ### 搜索任务插件 自定义后端搜索任务实现 `UkuiSearch::SearchTaskPluginIface`。当前接口版本为 `2.0.0`, 实现类需要: - 提供 `Q_INVOKABLE` 无参构造函数; - 实现 `PluginInterface` 和 `SearchTaskPluginIface` 的全部纯虚函数; - 通过 `setController()` 接收每个 `UkuiSearchTask` 独立的搜索上下文; - 正确实现 `startSearch()`、`stop()` 和 `isSearching()`; - 在完成、失败或达到通知数量时发送相应信号; - 在插件元数据中使用 `SEARCH_TASK_PLUGIN` 类型和 `2.0.0` 版本。 调用自定义任务时必须同时传入自定义类型名称: ```cpp using SearchType = UkuiSearch::SearchProperty::SearchType; task.initSearchPlugin(SearchType::Custom, QStringLiteral("example-task")); task.startSearch(SearchType::Custom, QStringLiteral("example-task")); ``` 接口定义见 [search-task-plugin-iface.h](libsearch/plugininterface/search-task-plugin-iface.h);可工作的 最小实现可参考 [valid-task-plugin.cpp](libsearch/autotest/plugin-manager-fixtures/valid-task-plugin.cpp)。 ### 搜索应用 widget 当前搜索应用使用 UKUI Quick widget 扩展机制。一个搜索 widget 通常包含: - `widget/metadata.json`:widget ID、QML 入口和 C++ 插件路径; - `widget/ui/`:结果详情页或分类页的 QML 界面; - `plugin/`:继承 `UkuiQuick::WidgetInterface` 的 C++ 插件; - `UkuiSearch::SearchExecutionInterface`:启动搜索、停止搜索和执行结果动作; - 可选的排序、筛选、分类页、可见结果和缩放适配接口。 搜索结果通过 `SearchResultQueue` 传递 `Upsert`、`Remove` 和 `Finished` 事件。插件必须为 每次搜索生成并校验唯一的 search ID,避免快速连续搜索时把旧结果写入新会话。 推荐从以下内置 widget 中选择最接近的实现作为模板: - [文件搜索 widget](ukui-search-qml/widgets/org.ukui.search.fileSearch/) - [应用搜索 widget](ukui-search-qml/widgets/org.ukui.search.appSearch/) - [设置项搜索 widget](ukui-search-qml/widgets/org.ukui.search.settingsSearch/) - [Web 搜索 widget](ukui-search-qml/widgets/org.ukui.search.webSearch/) > **废弃接口:** [search-plugin-iface.h](libsearch/plugininterface/search-plugin-iface.h) > 中的 `SearchPluginIface` 属于旧版搜索界面插件接口,已经废弃。新插件不得依赖该 > 接口,应使用 UKUI Quick widget 和 `SearchExecutionInterface`。 ## 贡献 - 使用仓库根目录的 `.clang-format` 格式化 C/C++ 代码。 - 行为变更应在最近的 `autotest/` 目录中补充测试,并使用 `-DBUILD_TEST=ON` 验证。 - 提交信息建议遵循 Conventional Commits,例如 `feat(scope): ...`、 `fix(scope): ...` 或 `refactor: ...`。 - UI 变更请在合并请求中附上截图,并列出实际运行过的构建和测试命令。 问题和合并请求请提交到 [openKylin/ukui-search](https://gitee.com/openkylin/ukui-search)。 ## 许可证 本项目依据 [GNU General Public License v3.0](LICENSE) 发布。第三方组件和子模块可能 使用各自的许可证,请同时查看对应目录中的许可证文件。