# Qt Screen Lock Detection Demo 一个基于 Qt5 + CMake 的跨平台应用程序,用于检测系统的锁屏状态,并在锁屏时自动停止所有 Paint 事件。 **支持平台:** - ✅ **Linux** (Ubuntu, Deepin, Fedora 等) - ✅ **macOS** (10.12 及以上版本) ## 功能特性 - ✅ **自动检测锁屏状态**: - Linux: 通过 DBus 监听系统的锁屏/解锁事件 - macOS: 通过 NSDistributedNotificationCenter 监听系统通知 - ✅ **自动停止绘制**:屏幕锁定时自动停止所有 Paint 事件,节省系统资源 - ✅ **实时动画演示**:持续的动画效果,直观展示绘制的启用/禁用状态 - ✅ **手动控制**:提供手动启用/禁用绘制的按钮 - ✅ **状态监控**:实时显示锁屏状态、绘制状态和帧数统计 - ✅ **多平台支持**: - Linux: 支持 GNOME、KDE、XFCE、Deepin DDE 等主流桌面环境 - macOS: 原生系统通知支持 ## 技术架构 ### 核心组件 1. **ScreenLockDetector** - 跨平台锁屏检测器 - **Linux**: 通过 Qt DBus 监听系统锁屏信号 - 支持 GNOME ScreenSaver、systemd-logind 和 Deepin DDE 接口 - **macOS**: 通过 NSDistributedNotificationCenter 监听系统通知 - 监听 com.apple.screenIsLocked/Unlocked 通知 - 发出锁屏/解锁信号供其他组件订阅 2. **CustomWidget** - 自定义绘制组件 - 实现了动态动画效果(旋转圆圈、波浪效果等) - 60 FPS 刷新率 - 可控制的绘制启用/禁用状态 - 帧数统计功能 3. **MainWindow** - 主窗口 - 整合各个组件 - 提供用户界面和控制面板 - 实时状态显示 ### 技术栈 - **语言**:C++11 / Objective-C++ (macOS) - **GUI 框架**:Qt 5.15.2 (或更高版本) - **构建系统**:CMake 3.10+ - **系统接口**: - Linux: Qt DBus - macOS: Foundation Framework (NSDistributedNotificationCenter) - **平台**:Linux Ubuntu / macOS 10.12+ ## 系统要求 ### Linux - Linux Ubuntu 18.04 或更高版本(也支持 Deepin OS、Fedora 等) - Qt 5.15.2 或更高版本 - CMake 3.10 或更高版本 - GCC/G++ 编译器(支持 C++11) - DBus 系统服务 ### macOS - macOS 10.12 (Sierra) 或更高版本 - Qt 5.15.2 或更高版本(可通过 Homebrew 安装) - CMake 3.10 或更高版本 - Xcode Command Line Tools - Foundation 和 Cocoa 框架(系统自带) ## 安装与编译 ### macOS 平台 #### 1. 安装依赖 使用 Homebrew 安装 Qt5: ```bash # 安装 Homebrew(如果尚未安装) /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # 安装 Qt5 brew install qt@5 # 安装 CMake(如果尚未安装) brew install cmake ``` 或者从 Qt 官网下载安装器:https://www.qt.io/download #### 2. 编译项目 ```bash # 赋予脚本执行权限 chmod +x build_mac.sh run_mac.sh # 编译 ./build_mac.sh ``` 脚本会自动搜索 Qt 安装路径。如果需要手动指定,可以设置环境变量: ```bash export Qt5_DIR=/path/to/qt/lib/cmake/Qt5 ./build_mac.sh ``` ### Linux 平台 #### 1. 确保 Qt5 已安装 ```bash # Ubuntu/Debian sudo apt-get install qt5-default qtbase5-dev libqt5dbus5 # Fedora sudo dnf install qt5-qtbase-devel qt5-qtbase-gui # 或使用自定义安装的 Qt ls $HOME/sdk/qt-5.15.2 ``` 如果 Qt5 安装在其他位置,请修改 `CMakeLists.txt` 中的 Qt5_DIR 路径或设置环境变量。 #### 2. 赋予脚本执行权限 ```bash chmod +x build.sh run.sh ``` #### 3. 编译项目 ```bash ./build.sh ``` 编译成功后,可执行文件将生成在 `build/bin/ScreenLockDetector` ## 运行应用 ### macOS 平台 #### 方法 1:使用运行脚本(推荐) ```bash ./run_mac.sh ``` #### 方法 2:直接运行可执行文件 ```bash ./build/bin/ScreenLockDetector ``` #### 方法 3:手动设置环境变量并运行 ```bash export DYLD_LIBRARY_PATH=/path/to/qt/lib:$DYLD_LIBRARY_PATH ./build/bin/ScreenLockDetector ``` ### Linux 平台 #### 方法 1:使用运行脚本(推荐) ```bash ./run.sh ``` #### 方法 2:直接运行可执行文件 ```bash cd build/bin ./ScreenLockDetector ``` #### 方法 3:手动设置环境变量并运行 ```bash export LD_LIBRARY_PATH=$HOME/sdk/qt-5.15.2/lib:$LD_LIBRARY_PATH ./build/bin/ScreenLockDetector ``` ## 使用说明 1. **启动应用**:运行应用后,会看到一个带有动态动画的窗口 2. **测试锁屏检测**: - **macOS**: 使用快捷键 `Ctrl + Cmd + Q` 或从菜单栏选择"锁定屏幕" - **Linux**: 使用快捷键 `Ctrl + Alt + L` 或 `Super + L` - 观察动画是否停止 - 解锁后动画应自动恢复 3. **查看状态信息**: - **Detector Status**:检测器是否正常工作 - **Screen Lock Status**:当前屏幕锁定状态(🔒 LOCKED / 🔓 UNLOCKED) - **Painting Status**:绘制是否启用(✓ ENABLED / ✗ DISABLED) - **Frame Count**:已绘制的总帧数 4. **手动控制**(可选): - **Enable Painting**:手动启用绘制 - **Disable Painting**:手动禁用绘制 - **Reset Frame Count**:重置帧数计数器 ## 工作原理 ### Linux: DBus 监听机制 应用程序通过 Qt DBus 连接到 Linux 系统的锁屏服务: 1. **Deepin DDE 接口**(Deepin OS) ``` Service: com.deepin.dde.lockFront Path: /com/deepin/dde/lockFront Interface: com.deepin.dde.lockFront Signals: Visible(bool) ``` 2. **GNOME ScreenSaver 接口** ``` Service: org.gnome.ScreenSaver Path: /org/gnome/ScreenSaver Interface: org.gnome.ScreenSaver Signal: ActiveChanged(bool) ``` 3. **KylinOS UKUI接口** ``` Service: org.ukui.ScreenSaver Path: / Interface: org.ukui.ScreenSaver Signals: lock(), unlock() ``` ### macOS: 分布式通知中心 应用程序通过 NSDistributedNotificationCenter 监听 macOS 系统通知: 1. **屏幕锁定通知** ``` Notification: com.apple.screenIsLocked 当用户锁定屏幕时发送 ``` 2. **屏幕解锁通知** ``` Notification: com.apple.screenIsUnlocked 当用户解锁屏幕时发送 ``` 3. **屏幕保护程序通知**(辅助检测) ``` Notifications: - com.apple.screensaver.didstart - com.apple.screensaver.didstop ``` ### Paint 事件控制 当检测到锁屏时: 1. `ScreenLockDetector` 发出 `screenLocked()` 信号 2. `MainWindow` 接收信号并调用 `CustomWidget::setPaintingEnabled(false)` 3. `CustomWidget` 停止动画定时器 4. `paintEvent()` 检查启用状态,不再绘制动画内容 当检测到解锁时: 1. `ScreenLockDetector` 发出 `screenUnlocked()` 信号 2. `MainWindow` 调用 `CustomWidget::setPaintingEnabled(true)` 3. `CustomWidget` 重启动画定时器 4. 动画恢复正常绘制 ## 项目结构 ``` ScreenLockDetector/ ├── CMakeLists.txt # CMake 构建配置(跨平台) ├── README.md # 项目文档 ├── build.sh # Linux 编译脚本 ├── run.sh # Linux 运行脚本 ├── build_mac.sh # macOS 编译脚本 ├── run_mac.sh # macOS 运行脚本 └── src/ ├── main.cpp # 程序入口 ├── mainwindow.h # 主窗口头文件 ├── mainwindow.cpp # 主窗口实现 ├── screenlockdetector.h # 跨平台锁屏检测器头文件 ├── screenlockdetector.cpp # 跨平台锁屏检测器实现 ├── screenlockdetector_mac.h # macOS 特定实现头文件 ├── screenlockdetector_mac.mm # macOS 特定实现(Objective-C++) ├── customwidget.h # 自定义组件头文件 └── customwidget.cpp # 自定义组件实现 ``` ## 故障排除 ### macOS 平台 #### 问题 1:应用无法检测到锁屏 **可能原因**: - 权限问题 - 系统通知未正常工作 **解决方案**: ```bash # 查看应用日志 ./run_mac.sh 2>&1 | grep "ScreenLock" # 检查系统完整性保护(SIP)状态 csrutil status # 确保应用有必要的权限 ``` #### 问题 2:编译错误 - Qt5 not found **解决方案**: ```bash # 使用 Homebrew 安装 Qt5 brew install qt@5 # 设置 Qt5_DIR 环境变量 export Qt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5 ./build_mac.sh ``` #### 问题 3:运行时找不到 Qt 库 **解决方案**: ```bash # 设置 DYLD_LIBRARY_PATH export DYLD_LIBRARY_PATH=$(brew --prefix qt@5)/lib:$DYLD_LIBRARY_PATH # 或使用 run_mac.sh 脚本(已包含此配置) ./run_mac.sh ``` ### Linux 平台 #### 问题 1:锁屏检测不工作 **可能原因**: - DBus 服务未运行 - 桌面环境不支持标准 DBus 接口 - 权限不足 **解决方案**: ```bash # 检查 DBus 服务 ps aux | grep dbus # 检查 GNOME ScreenSaver 是否可用 qdbus org.gnome.ScreenSaver # 查看应用日志输出,确认连接状态 ``` ### 问题 2:编译错误 - Qt5 not found **解决方案**: 1. 确认 Qt5 安装路径:`ls $HOME/sdk/qt-5.15.2` 2. 修改 `CMakeLists.txt` 中的 Qt5_DIR 路径 3. 或设置环境变量:`export Qt5_DIR=$HOME/sdk/qt-5.15.2/lib/cmake/Qt5` ### 问题 3:运行时找不到 Qt 库 **解决方案**: ```bash # 设置 LD_LIBRARY_PATH export LD_LIBRARY_PATH=$HOME/sdk/qt-5.15.2/lib:$LD_LIBRARY_PATH # 或使用 run.sh 脚本(已包含此配置) ./run.sh ``` ### 问题 4:警告 - Failed to connect to screen lock detection service **说明**:这是正常的,表示某些 DBus 接口在当前桌面环境中不可用。只要至少有一个接口连接成功,应用就能正常工作。 ## 调试模式 应用程序会在控制台输出详细的调试信息: ```bash # 运行并查看详细日志 ./run.sh 2>&1 | tee app.log # 查看特定类别的日志 ./run.sh 2>&1 | grep "ScreenLockDetector" ``` ## 扩展与定制 ### 添加更多动画效果 在 `customwidget.cpp` 中的 `drawBackground()`, `drawRotatingCircles()`, `drawWaveEffect()` 等方法中添加自定义绘制代码。 ### 支持其他桌面环境 在 `screenlockdetector.cpp` 中添加更多 DBus 接口连接: ```cpp bool ScreenLockDetector::connectToKDEScreenSaver() { // 添加 KDE Plasma 锁屏检测支持 // Service: org.kde.screensaver // ... } ``` ### 性能优化 调整动画刷新率(当前为 60 FPS): ```cpp // 在 customwidget.cpp 构造函数中 m_animationTimer->start(33); // 30 FPS (1000/30 ≈ 33ms) ``` ## 许可证 本项目仅用于学习和演示目的。 ## 作者 Qt Screen Lock Detection Demo ## 更新日志 ### v2.0.0 (2024) - ✅ **重大更新**: 新增 macOS 平台支持 - ✅ 实现跨平台架构(Linux + macOS) - ✅ macOS: 使用 NSDistributedNotificationCenter 监听系统通知 - ✅ 创建平台特定的构建和运行脚本 - ✅ 更新文档,包含 macOS 使用说明 ### v1.1.0 (2024) - ✅ 新增 Deepin OS (DDE) 锁屏检测支持 - ✅ 优化多桌面环境兼容性 ### v1.0.0 (2024) - ✅ 初始版本发布 - ✅ 支持 GNOME 和 systemd-logind 锁屏检测 - ✅ 实现自动 Paint 事件控制 - ✅ 提供丰富的动画演示效果 - ✅ 完整的状态监控和手动控制界面 ## 反馈与贡献 如有问题或建议,欢迎提出!