# ScreenLockDetector 重构说明 ## 概述 本次重构将 ScreenLockDetector 项目从平台条件编译的单一类结构重构为面向对象的继承体系,使用抽象基类和平台特定的子类实现。 ## 重构目标 1. **提高代码可维护性**: 将平台特定代码分离到独立的类中 2. **改善代码结构**: 使用面向对象设计模式(工厂模式 + 模板方法模式) 3. **增强可扩展性**: 便于添加新平台支持 4. **减少代码耦合**: 消除大量的 `#ifdef` 条件编译 ## 架构设计 ### 类层次结构 ``` ScreenLockDetectorBase (抽象基类) ├── ScreenLockDetectorLinux (Linux 实现) └── ScreenLockDetectorMacOS (macOS 实现) ScreenLockDetector (工厂类) ``` ### 设计模式 1. **工厂模式**: `ScreenLockDetector` 根据平台创建相应的检测器实例 2. **模板方法模式**: `ScreenLockDetectorBase` 定义通用接口,子类实现特定逻辑 3. **策略模式**: 不同平台的检测策略封装在各自的类中 ## 文件结构 ### 新增文件 | 文件名 | 说明 | |--------|------| | `screenlockdetector_base.h` | 抽象基类头文件 | | `screenlockdetector_base.cpp` | 抽象基类实现 | | `screenlockdetector_linux.h` | Linux 子类头文件 | | `screenlockdetector_linux.cpp` | Linux 子类实现 | | `screenlockdetector_macos.h` | macOS 子类头文件 | | `screenlockdetector_macos.mm` | macOS 子类实现 (Objective-C++) | ### 修改文件 | 文件名 | 变更说明 | |--------|----------| | `screenlockdetector.h` | 从平台特定类改为工厂类 | | `screenlockdetector.cpp` | 实现工厂方法,创建平台特定实例 | | `CMakeLists.txt` | 更新源文件列表 | ### 弃用文件 | 文件名 | 说明 | |--------|------| | `screenlockdetector_mac.h` | 已重命名为 `screenlockdetector_macos.h` | | `screenlockdetector_mac.mm` | 已重命名为 `screenlockdetector_macos.mm` | ## 类详细说明 ### 1. ScreenLockDetectorBase (抽象基类) **职责**: 定义跨平台的公共接口和共享逻辑 **主要成员**: - `bool isScreenLocked() const` - 获取锁屏状态 - `virtual bool initialize() = 0` - 纯虚函数,由子类实现初始化 - `void setLockState(bool locked)` - 受保护方法,供子类更新状态 **信号**: - `void screenLocked()` - 屏幕锁定信号 - `void screenUnlocked()` - 屏幕解锁信号 - `void lockStateChanged(bool locked)` - 状态变化信号 ### 2. ScreenLockDetectorLinux (Linux 实现) **职责**: 处理 Linux 平台的 DBus 信号监听 **支持的桌面环境**: - Deepin DDE - GNOME - KDE - XFCE - UKUI/KylinOS **实现细节**: - 通过 `QDBusInterface` 连接到不同桌面环境的 DBus 服务 - 监听 `ActiveChanged`、`Visible`、`lock`、`unlock` 等信号 - 查询初始锁屏状态 ### 3. ScreenLockDetectorMacOS (macOS 实现) **职责**: 处理 macOS 平台的系统通知监听 **实现细节**: - 使用 `NSDistributedNotificationCenter` 监听系统通知 - 监听的通知: - `com.apple.screenIsLocked` - 屏幕锁定 - `com.apple.screenIsUnlocked` - 屏幕解锁 - `com.apple.screensaver.didstart` - 屏保启动(可选) - `com.apple.screensaver.didstop` - 屏保停止(可选) - 使用 Objective-C 观察者模式 ### 4. ScreenLockDetector (工厂类) **职责**: 提供统一的接口,自动创建平台特定的检测器 **实现方式**: ```cpp ScreenLockDetectorBase* ScreenLockDetector::createPlatformDetector() { #ifdef Q_OS_MAC return new ScreenLockDetectorMacOS(this); #elif defined(Q_OS_LINUX) return new ScreenLockDetectorLinux(this); #else return nullptr; #endif } ``` **使用方式**: ```cpp // 创建检测器 ScreenLockDetector *detector = new ScreenLockDetector(this); // 连接信号 connect(detector, &ScreenLockDetector::screenLocked, this, &YourClass::onScreenLocked); connect(detector, &ScreenLockDetector::screenUnlocked, this, &YourClass::onScreenUnlocked); // 初始化 if (!detector->initialize()) { qWarning() << "Failed to initialize screen lock detector"; } ``` ## 重构优势 ### 1. 代码分离 - **之前**: 所有平台代码混杂在一个文件中,充斥大量 `#ifdef` - **之后**: 每个平台的代码独立成文件,清晰明了 ### 2. 易于测试 - 可以为每个平台创建独立的测试用例 - 基类的通用逻辑可以单独测试 ### 3. 便于扩展 添加新平台只需要: 1. 创建继承自 `ScreenLockDetectorBase` 的新类 2. 实现 `initialize()` 方法 3. 在工厂方法中添加平台判断 4. 更新 `CMakeLists.txt` ### 4. 降低耦合 - 平台特定的头文件(如 `QDBus`、`NSDistributedNotificationCenter`)只在对应的实现文件中引用 - 主接口类不需要知道平台细节 ### 5. 符合设计原则 - **单一职责原则**: 每个类只负责一个平台的实现 - **开闭原则**: 对扩展开放,对修改关闭 - **依赖倒置原则**: 依赖抽象而非具体实现 ## 兼容性 本次重构完全兼容现有的外部接口: - `ScreenLockDetector` 类的公共接口保持不变 - 信号定义保持不变 - 使用方式保持不变 现有代码无需修改即可使用重构后的版本。 ## 构建说明 ### Linux ```bash mkdir build && cd build cmake .. make ``` ### macOS ```bash mkdir build && cd build cmake .. make ``` CMake 会自动根据平台选择正确的源文件进行编译。 ## 未来改进方向 1. **添加 Windows 支持** - 创建 `ScreenLockDetectorWindows` 类 - 使用 `WTSRegisterSessionNotification` API 2. **添加 Android/iOS 支持** - 适用于 Qt for Mobile 应用 3. **添加配置选项** - 允许用户选择检测方式 - 添加超时和重试机制 4. **改进错误处理** - 添加详细的错误码 - 提供错误恢复机制 5. **性能优化** - 减少轮询(如果有) - 优化信号连接 ## 测试建议 ### Linux 测试 1. 在不同桌面环境下测试(GNOME、KDE、Deepin、UKUI) 2. 测试锁屏/解锁事件 3. 测试应用启动时的初始状态检测 ### macOS 测试 1. 测试 Command+Control+Q 锁屏 2. 测试屏保激活后的锁屏 3. 测试从休眠恢复时的通知 ## 作者 ScreenLockDetector 开发团队 ## 版本历史 - **v2.0.0** (2025): 面向对象重构 - **v1.0.0** (2025): 初始版本