Improve DBus screen lock detection and debugging
This commit is contained in:
parent
778a697336
commit
fa4514d4eb
|
|
@ -0,0 +1,331 @@
|
|||
# 锁屏信号未触发问题修复指南
|
||||
|
||||
## 问题描述
|
||||
|
||||
程序已成功连接到目标系统的 DBus 服务,但是系统锁屏时 `onSessionLocked()` 没有被调用。
|
||||
此问题在 Ubuntu 和 Deepin 系统上都存在。
|
||||
|
||||
## 问题原因
|
||||
|
||||
### 1. Session 路径问题
|
||||
原代码使用了固定路径 `/org/freedesktop/login1/session/auto`,但这个路径在大多数 Linux 系统上不起作用。需要使用实际的会话 ID 路径,例如:
|
||||
- `/org/freedesktop/login1/session/c1`
|
||||
- `/org/freedesktop/login1/session/2`
|
||||
|
||||
### 2. 信号监听范围太窄
|
||||
原代码只监听特定路径的信号,如果实际信号从其他路径发出,就无法接收到。
|
||||
|
||||
### 3. 缺少详细调试信息
|
||||
无法判断到底是哪个环节出了问题:连接失败、信号未发出、还是信号发送者不匹配。
|
||||
|
||||
## 修复方案
|
||||
|
||||
### 主要改进
|
||||
|
||||
#### 1. 动态获取 Session 路径
|
||||
新增 `getCurrentSessionPath()` 方法,通过以下方式获取正确的会话路径:
|
||||
|
||||
```cpp
|
||||
QString ScreenLockDetector::getCurrentSessionPath()
|
||||
{
|
||||
// 方法1: 从环境变量获取
|
||||
QString xdgSessionId = qgetenv("XDG_SESSION_ID");
|
||||
if (!xdgSessionId.isEmpty()) {
|
||||
return QString("/org/freedesktop/login1/session/%1").arg(xdgSessionId);
|
||||
}
|
||||
|
||||
// 方法2: 通过 DBus 调用获取
|
||||
QDBusInterface managerIface(
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
QDBusConnection::systemBus()
|
||||
);
|
||||
|
||||
if (managerIface.isValid()) {
|
||||
QDBusReply<QDBusObjectPath> reply =
|
||||
managerIface.call("GetSessionByPID",
|
||||
(quint32)QCoreApplication::applicationPid());
|
||||
if (reply.isValid()) {
|
||||
return reply.value().path();
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 双重信号连接策略
|
||||
先尝试连接到特定会话路径,如果失败则连接到通用信号(空路径):
|
||||
|
||||
```cpp
|
||||
// 方法1: 连接到特定会话
|
||||
QDBusConnection::systemBus().connect(
|
||||
"org.freedesktop.login1",
|
||||
sessionPath, // 具体路径
|
||||
"org.freedesktop.login1.Session",
|
||||
"Lock",
|
||||
this,
|
||||
SLOT(onSessionLocked())
|
||||
);
|
||||
|
||||
// 方法2: 连接到所有会话(备用方案)
|
||||
QDBusConnection::systemBus().connect(
|
||||
"org.freedesktop.login1",
|
||||
"", // 空路径 = 监听所有对象
|
||||
"org.freedesktop.login1.Session",
|
||||
"Lock",
|
||||
this,
|
||||
SLOT(onSessionLocked())
|
||||
);
|
||||
```
|
||||
|
||||
#### 3. 增强的调试信息
|
||||
- 继承 `QDBusContext` 以获取信号发送者详细信息
|
||||
- 在所有关键点添加详细日志输出
|
||||
- 显示信号的 service、path、interface 和 member
|
||||
|
||||
```cpp
|
||||
void ScreenLockDetector::onSessionLocked()
|
||||
{
|
||||
qDebug() << "##################################################";
|
||||
qDebug() << "## LOCK SIGNAL RECEIVED";
|
||||
|
||||
QDBusMessage msg = QDBusContext::message();
|
||||
if (msg.type() != QDBusMessage::InvalidMessage) {
|
||||
qDebug() << "## DBus Message Details:";
|
||||
qDebug() << "## Service:" << msg.service();
|
||||
qDebug() << "## Path:" << msg.path();
|
||||
qDebug() << "## Interface:" << msg.interface();
|
||||
qDebug() << "## Member:" << msg.member();
|
||||
}
|
||||
|
||||
qDebug() << "##################################################";
|
||||
setLockState(true);
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 改进的状态查询
|
||||
增强 `queryCurrentLockState()` 方法,正确读取 systemd-logind 的 `LockedHint` 属性:
|
||||
|
||||
```cpp
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(
|
||||
"org.freedesktop.login1",
|
||||
m_loginInterface->path(),
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"Get"
|
||||
);
|
||||
msg << "org.freedesktop.login1.Session" << "LockedHint";
|
||||
|
||||
QDBusReply<QVariant> reply = QDBusConnection::systemBus().call(msg);
|
||||
if (reply.isValid()) {
|
||||
bool locked = reply.value().toBool();
|
||||
setLockState(locked);
|
||||
}
|
||||
```
|
||||
|
||||
## 使用修复后的代码
|
||||
|
||||
### 1. 重新编译
|
||||
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
### 2. 运行程序并观察日志
|
||||
|
||||
```bash
|
||||
./run.sh
|
||||
```
|
||||
|
||||
程序启动时会输出详细的连接信息:
|
||||
|
||||
```
|
||||
=================================================
|
||||
Initializing ScreenLockDetector...
|
||||
=================================================
|
||||
|
||||
--- Connecting to Deepin DDE ---
|
||||
Trying Deepin service: com.deepin.dde.lockFront
|
||||
...
|
||||
|
||||
--- Connecting to GNOME ScreenSaver ---
|
||||
GNOME ScreenSaver interface is valid
|
||||
GNOME ActiveChanged signal connected: true
|
||||
...
|
||||
|
||||
--- Connecting to Login Manager (systemd-logind) ---
|
||||
Session path from XDG_SESSION_ID: /org/freedesktop/login1/session/c1
|
||||
Current session path: /org/freedesktop/login1/session/c1
|
||||
Login Manager interface is valid for session: /org/freedesktop/login1/session/c1
|
||||
Session Lock signal connected: true
|
||||
Session Unlock signal connected: true
|
||||
...
|
||||
```
|
||||
|
||||
### 3. 测试锁屏
|
||||
|
||||
锁定屏幕后,应该能看到:
|
||||
|
||||
```
|
||||
##################################################
|
||||
## LOCK SIGNAL RECEIVED
|
||||
## Screen is now LOCKED
|
||||
## DBus Message Details:
|
||||
## Service: :1.43
|
||||
## Path: /org/freedesktop/login1/session/c1
|
||||
## Interface: org.freedesktop.login1.Session
|
||||
## Member: Lock
|
||||
##################################################
|
||||
```
|
||||
|
||||
## 调试工具
|
||||
|
||||
### 工具 1: test_lock_signals.sh
|
||||
|
||||
这是一个全面的 DBus 信号监听脚本,用于诊断问题:
|
||||
|
||||
```bash
|
||||
./test_lock_signals.sh
|
||||
```
|
||||
|
||||
功能:
|
||||
1. 显示当前会话信息(XDG_SESSION_ID 等)
|
||||
2. 检查可用的锁屏服务
|
||||
3. 列出会话支持的所有信号
|
||||
4. 实时监听 session bus 和 system bus 的锁屏信号
|
||||
5. 保存日志供后续分析
|
||||
|
||||
使用方法:
|
||||
1. 运行脚本
|
||||
2. 按照提示锁定/解锁屏幕
|
||||
3. 观察输出的信号
|
||||
4. 按 Ctrl+C 停止
|
||||
|
||||
### 工具 2: debug_deepin_dbus.sh
|
||||
|
||||
专门用于 Deepin 系统的调试脚本:
|
||||
|
||||
```bash
|
||||
./debug_deepin_dbus.sh
|
||||
```
|
||||
|
||||
## 验证修复
|
||||
|
||||
### 检查列表
|
||||
|
||||
- [ ] 程序启动时显示"ScreenLockDetector initialized successfully"
|
||||
- [ ] 至少有一个接口显示"connected: true"
|
||||
- [ ] 显示了正确的 session 路径(不是 "auto")
|
||||
- [ ] 锁屏时看到 "LOCK SIGNAL RECEIVED" 消息
|
||||
- [ ] 解锁时看到 "UNLOCK SIGNAL RECEIVED" 消息
|
||||
- [ ] 主窗口状态正确更新
|
||||
|
||||
### 如果仍然无法接收信号
|
||||
|
||||
1. **运行 test_lock_signals.sh**
|
||||
```bash
|
||||
./test_lock_signals.sh
|
||||
```
|
||||
观察系统实际发出了什么信号
|
||||
|
||||
2. **检查会话路径**
|
||||
```bash
|
||||
echo $XDG_SESSION_ID
|
||||
loginctl show-session $XDG_SESSION_ID
|
||||
```
|
||||
|
||||
3. **手动测试 DBus 连接**
|
||||
```bash
|
||||
# 监听 system bus 的 Lock 信号
|
||||
dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Session',member='Lock'"
|
||||
|
||||
# 在另一个终端锁屏
|
||||
loginctl lock-session
|
||||
```
|
||||
|
||||
4. **检查权限**
|
||||
确保用户有权限访问 system bus:
|
||||
```bash
|
||||
groups $USER
|
||||
```
|
||||
用户应该在 `sudo` 或 `wheel` 组中
|
||||
|
||||
5. **对于 Deepin 系统**
|
||||
```bash
|
||||
# 列出所有 Deepin 相关服务
|
||||
dbus-send --session --print-reply --dest=org.freedesktop.DBus \
|
||||
/org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep deepin
|
||||
|
||||
# 查看 lockFront 的接口
|
||||
dbus-send --session --print-reply --dest=com.deepin.dde.lockFront \
|
||||
/com/deepin/dde/lockFront org.freedesktop.DBus.Introspectable.Introspect
|
||||
```
|
||||
|
||||
## 不同系统的特殊情况
|
||||
|
||||
### Ubuntu / GNOME
|
||||
- 主要通过 `org.gnome.ScreenSaver` 的 `ActiveChanged` 信号
|
||||
- 或通过 systemd-logind 的 `Lock/Unlock` 信号
|
||||
|
||||
### Deepin DDE
|
||||
- 服务名可能是 `com.deepin.dde.lockFront` 或 `org.deepin.dde.lockFront`
|
||||
- 信号名可能是 `Locked/Unlocked` 或 `Lock/Unlock`
|
||||
- 需要通过 session bus 连接
|
||||
|
||||
### KDE Plasma
|
||||
- 使用 `org.freedesktop.ScreenSaver`
|
||||
- 也支持 systemd-logind
|
||||
|
||||
### XFCE
|
||||
- 主要依赖 systemd-logind
|
||||
- 或 `org.xfce.ScreenSaver`
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 为什么连接显示成功但没有收到信号?
|
||||
|
||||
A: 可能的原因:
|
||||
1. 连接到了错误的会话路径
|
||||
2. 桌面环境使用了不同的锁屏机制
|
||||
3. 信号签名不匹配(参数类型不对)
|
||||
|
||||
解决方法:使用 `test_lock_signals.sh` 查看实际信号。
|
||||
|
||||
### Q: 在虚拟机中测试是否会有问题?
|
||||
|
||||
A: 可能会。某些虚拟机可能没有完整的 session 管理。建议:
|
||||
- 确保虚拟机安装了完整的桌面环境
|
||||
- 使用 GUI 登录而不是 SSH
|
||||
- 检查 `loginctl list-sessions` 是否显示你的会话
|
||||
|
||||
### Q: Deepin 系统上还是不工作怎么办?
|
||||
|
||||
A: Deepin 不同版本的接口可能不同:
|
||||
1. 运行 `debug_deepin_dbus.sh` 找到正确的服务名
|
||||
2. 修改 `connectToDeepinDDE()` 中的服务列表
|
||||
3. 添加找到的服务配置
|
||||
4. 重新编译测试
|
||||
|
||||
## 技术参考
|
||||
|
||||
### DBus 接口文档
|
||||
- systemd-logind Session: https://www.freedesktop.org/wiki/Software/systemd/logind/
|
||||
- GNOME ScreenSaver: https://wiki.gnome.org/Projects/GnomeScreensaver
|
||||
|
||||
### Qt DBus 文档
|
||||
- QDBusConnection: https://doc.qt.io/qt-5/qdbusconnection.html
|
||||
- QDBusContext: https://doc.qt.io/qt-5/qdbuscontext.html
|
||||
- QDBusInterface: https://doc.qt.io/qt-5/qdbusinterface.html
|
||||
|
||||
## 总结
|
||||
|
||||
修复的核心要点:
|
||||
|
||||
1. ✅ **动态获取会话路径** - 不要硬编码 "auto"
|
||||
2. ✅ **多重连接策略** - 特定路径 + 通用监听
|
||||
3. ✅ **详细调试日志** - 便于诊断问题
|
||||
4. ✅ **正确读取属性** - 使用 Properties 接口
|
||||
5. ✅ **支持多种桌面环境** - Deepin/GNOME/KDE 等
|
||||
|
||||
这些修复应该能解决大多数 Linux 系统上的锁屏信号接收问题。
|
||||
|
|
@ -0,0 +1,355 @@
|
|||
# 锁屏信号问题快速修复指南
|
||||
|
||||
## 问题症状
|
||||
|
||||
✗ 程序显示"已成功连接到目标系统的服务"
|
||||
✗ 但锁屏时 `onSessionLocked()` 没有被调用
|
||||
✗ Ubuntu 和 Deepin 系统都有此问题
|
||||
|
||||
## 快速解决方案
|
||||
|
||||
### 🚀 一键验证修复
|
||||
|
||||
已经重新编译,直接运行验证脚本:
|
||||
|
||||
```bash
|
||||
./verify_fix.sh
|
||||
```
|
||||
|
||||
这个脚本会:
|
||||
1. 检查编译状态
|
||||
2. 显示系统环境信息
|
||||
3. 检测可用的 DBus 服务
|
||||
4. 启动程序并提示如何测试
|
||||
|
||||
### 📋 核心修复内容
|
||||
|
||||
#### 修复 1: 动态获取会话路径
|
||||
|
||||
**问题**: 原代码使用固定路径 `/org/freedesktop/login1/session/auto`,在大多数系统上不工作
|
||||
|
||||
**修复**: 新增方法动态获取实际会话路径
|
||||
|
||||
```cpp
|
||||
QString getCurrentSessionPath() {
|
||||
// 从环境变量 XDG_SESSION_ID 获取
|
||||
// 或通过 DBus 调用 GetSessionByPID 获取
|
||||
}
|
||||
```
|
||||
|
||||
#### 修复 2: 广播式信号监听
|
||||
|
||||
**问题**: 只监听特定路径的信号
|
||||
|
||||
**修复**: 添加空路径监听(监听所有会话)
|
||||
|
||||
```cpp
|
||||
// 监听所有 session 的 Lock/Unlock 信号
|
||||
QDBusConnection::systemBus().connect(
|
||||
"org.freedesktop.login1",
|
||||
"", // 空路径 = 监听所有对象
|
||||
"org.freedesktop.login1.Session",
|
||||
"Lock",
|
||||
this,
|
||||
SLOT(onSessionLocked())
|
||||
);
|
||||
```
|
||||
|
||||
#### 修复 3: 增强调试信息
|
||||
|
||||
**问题**: 无法判断问题出在哪个环节
|
||||
|
||||
**修复**:
|
||||
- 继承 `QDBusContext` 获取信号详情
|
||||
- 在关键点添加详细日志
|
||||
- 显示信号的来源路径和接口
|
||||
|
||||
## 验证修复是否生效
|
||||
|
||||
### 预期的启动日志
|
||||
|
||||
```
|
||||
=================================================
|
||||
Initializing ScreenLockDetector...
|
||||
=================================================
|
||||
|
||||
--- Connecting to Login Manager (systemd-logind) ---
|
||||
Session path from XDG_SESSION_ID: /org/freedesktop/login1/session/c1
|
||||
Current session path: /org/freedesktop/login1/session/c1
|
||||
Login Manager interface is valid for session: ...
|
||||
Session Lock signal connected: true ← ✓ 应该是 true
|
||||
Session Unlock signal connected: true ← ✓ 应该是 true
|
||||
|
||||
=================================================
|
||||
ScreenLockDetector initialized successfully
|
||||
Login Manager connected: true ← ✓ 至少一个为 true
|
||||
=================================================
|
||||
```
|
||||
|
||||
### 预期的锁屏日志
|
||||
|
||||
当你按 `Super+L` 或 `Ctrl+Alt+L` 锁屏后:
|
||||
|
||||
```
|
||||
##################################################
|
||||
## LOCK SIGNAL RECEIVED
|
||||
## Screen is now LOCKED
|
||||
## DBus Message Details:
|
||||
## Service: :1.43
|
||||
## Path: /org/freedesktop/login1/session/c1
|
||||
## Interface: org.freedesktop.login1.Session
|
||||
## Member: Lock
|
||||
##################################################
|
||||
```
|
||||
|
||||
## 如果还是不工作
|
||||
|
||||
### 🔍 调试步骤
|
||||
|
||||
#### 步骤 1: 检查实际发送的信号
|
||||
|
||||
运行监听脚本:
|
||||
|
||||
```bash
|
||||
./test_lock_signals.sh
|
||||
```
|
||||
|
||||
按提示锁屏/解锁,观察哪些信号被发出。
|
||||
|
||||
#### 步骤 2: 手动测试 DBus
|
||||
|
||||
在一个终端运行:
|
||||
|
||||
```bash
|
||||
dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Session'"
|
||||
```
|
||||
|
||||
在另一个终端锁屏:
|
||||
|
||||
```bash
|
||||
# GNOME/Ubuntu
|
||||
gnome-screensaver-command -l
|
||||
|
||||
# 或通用方法
|
||||
loginctl lock-session
|
||||
|
||||
# Deepin
|
||||
dde-lock
|
||||
```
|
||||
|
||||
观察是否有 `Lock` 信号出现。
|
||||
|
||||
#### 步骤 3: 检查会话状态
|
||||
|
||||
```bash
|
||||
# 查看会话 ID
|
||||
echo $XDG_SESSION_ID
|
||||
|
||||
# 查看会话详情
|
||||
loginctl show-session $XDG_SESSION_ID
|
||||
|
||||
# 列出所有会话
|
||||
loginctl list-sessions
|
||||
```
|
||||
|
||||
确保你的会话是活动的,类型是 `x11` 或 `wayland`。
|
||||
|
||||
#### 步骤 4: 检查权限
|
||||
|
||||
```bash
|
||||
# 当前用户的组
|
||||
groups
|
||||
|
||||
# 测试是否能访问 systemd-logind
|
||||
dbus-send --system --print-reply \
|
||||
--dest=org.freedesktop.login1 \
|
||||
/org/freedesktop/login1 \
|
||||
org.freedesktop.DBus.Introspectable.Introspect
|
||||
```
|
||||
|
||||
### 🔧 特定系统的额外步骤
|
||||
|
||||
#### Ubuntu / GNOME 系统
|
||||
|
||||
如果 systemd-logind 不工作,检查 GNOME ScreenSaver:
|
||||
|
||||
```bash
|
||||
# 检查服务是否存在
|
||||
dbus-send --session --print-reply \
|
||||
--dest=org.gnome.ScreenSaver \
|
||||
/org/gnome/ScreenSaver \
|
||||
org.freedesktop.DBus.Introspectable.Introspect
|
||||
|
||||
# 监听 GNOME 信号
|
||||
dbus-monitor --session "interface='org.gnome.ScreenSaver'"
|
||||
|
||||
# 锁屏
|
||||
gnome-screensaver-command -l
|
||||
```
|
||||
|
||||
#### Deepin 系统
|
||||
|
||||
运行 Deepin 专用调试脚本:
|
||||
|
||||
```bash
|
||||
./debug_deepin_dbus.sh
|
||||
```
|
||||
|
||||
这会显示所有可用的 Deepin 锁屏服务,然后实时监听信号。
|
||||
|
||||
常见的 Deepin 服务名:
|
||||
- `com.deepin.dde.lockFront`
|
||||
- `org.deepin.dde.lockFront`
|
||||
- `com.deepin.ScreenSaver`
|
||||
|
||||
#### Wayland 会话
|
||||
|
||||
Wayland 可能有不同的行为:
|
||||
|
||||
```bash
|
||||
# 检查会话类型
|
||||
echo $XDG_SESSION_TYPE
|
||||
|
||||
# 如果是 wayland,可能需要使用不同的方法
|
||||
# 某些 Wayland 合成器使用自己的锁屏协议
|
||||
```
|
||||
|
||||
## 常见问题解答
|
||||
|
||||
### Q: 为什么连接显示成功但收不到信号?
|
||||
|
||||
**A**: 可能原因:
|
||||
1. **路径不对**: 连接到了错误的会话路径
|
||||
2. **时机问题**: 信号在连接之前就发送了
|
||||
3. **权限问题**: 没有权限监听 system bus 信号
|
||||
4. **桌面环境**: 使用了非标准的锁屏机制
|
||||
|
||||
**解决**: 使用 `test_lock_signals.sh` 查看实际信号
|
||||
|
||||
### Q: 在虚拟机中测试有问题吗?
|
||||
|
||||
**A**: 可能会有。确保:
|
||||
- ✓ 使用完整的桌面环境(不是最小化安装)
|
||||
- ✓ 通过图形界面登录(不是 SSH)
|
||||
- ✓ 虚拟机有足够的资源
|
||||
- ✓ 安装了 Guest Additions / Tools
|
||||
|
||||
### Q: 日志显示 "connected: true" 但还是没反应?
|
||||
|
||||
**A**: 这说明连接成功了,但信号可能:
|
||||
1. 使用了不同的信号名(如 `Locked` vs `Lock`)
|
||||
2. 从不同的路径发出
|
||||
3. 带有额外的参数
|
||||
|
||||
运行 `dbus-monitor` 直接查看:
|
||||
|
||||
```bash
|
||||
# 监听所有 session bus 信号
|
||||
dbus-monitor --session "type='signal'" | grep -i lock
|
||||
|
||||
# 监听所有 system bus 信号
|
||||
dbus-monitor --system "type='signal'" | grep -i lock
|
||||
```
|
||||
|
||||
### Q: Deepin 系统上完全不工作?
|
||||
|
||||
**A**: Deepin 不同版本的接口差异很大:
|
||||
|
||||
1. 找到正确的服务名:
|
||||
```bash
|
||||
dbus-send --session --print-reply \
|
||||
--dest=org.freedesktop.DBus \
|
||||
/org/freedesktop/DBus \
|
||||
org.freedesktop.DBus.ListNames | grep -i deepin
|
||||
```
|
||||
|
||||
2. 查看服务接口:
|
||||
```bash
|
||||
dbus-send --session --print-reply \
|
||||
--dest=com.deepin.dde.lockFront \
|
||||
/com/deepin/dde/lockFront \
|
||||
org.freedesktop.DBus.Introspectable.Introspect
|
||||
```
|
||||
|
||||
3. 修改 `screenlockdetector.cpp` 中 `connectToDeepinDDE()` 的服务列表
|
||||
|
||||
## 技术细节
|
||||
|
||||
### 为什么需要空路径监听?
|
||||
|
||||
DBus 信号连接时指定路径会限制只接收该对象的信号。使用空路径 `""` 表示监听该接口的所有对象的信号。
|
||||
|
||||
```cpp
|
||||
// 只监听特定会话
|
||||
connect("service", "/path/to/session1", "interface", "signal", ...)
|
||||
|
||||
// 监听所有会话(推荐)
|
||||
connect("service", "", "interface", "signal", ...)
|
||||
```
|
||||
|
||||
### QDBusContext 的作用
|
||||
|
||||
继承 `QDBusContext` 后,在 slot 函数中可以调用 `message()` 获取触发信号的详细信息:
|
||||
|
||||
```cpp
|
||||
QDBusMessage msg = QDBusContext::message();
|
||||
qDebug() << "Signal from:" << msg.service() << msg.path();
|
||||
```
|
||||
|
||||
这对调试非常有用。
|
||||
|
||||
### systemd-logind Session 接口
|
||||
|
||||
标准接口应该有这些信号:
|
||||
- `Lock` - 会话锁定
|
||||
- `Unlock` - 会话解锁
|
||||
- `PauseDevice` - 设备暂停
|
||||
- `ResumeDevice` - 设备恢复
|
||||
|
||||
和这些属性:
|
||||
- `LockedHint` - 布尔值,指示会话是否锁定
|
||||
- `Active` - 会话是否活动
|
||||
- `Type` - 会话类型(x11, wayland, tty 等)
|
||||
|
||||
## 获取帮助
|
||||
|
||||
如果以上方法都不行,请提供以下信息:
|
||||
|
||||
1. **系统信息**:
|
||||
```bash
|
||||
cat /etc/os-release
|
||||
echo "Desktop: $XDG_CURRENT_DESKTOP"
|
||||
echo "Session: $XDG_SESSION_TYPE"
|
||||
```
|
||||
|
||||
2. **会话信息**:
|
||||
```bash
|
||||
loginctl show-session $XDG_SESSION_ID
|
||||
```
|
||||
|
||||
3. **程序输出**: 运行 `./run.sh` 的完整输出
|
||||
|
||||
4. **信号监听结果**: 运行 `./test_lock_signals.sh` 的输出
|
||||
|
||||
5. **手动测试结果**:
|
||||
```bash
|
||||
dbus-monitor --system "type='signal'" | grep -i lock
|
||||
# 然后锁屏,记录输出
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- 📖 详细修复说明: `LOCK_SIGNAL_FIX.md`
|
||||
- 🔧 Deepin 支持: `DEEPIN_SUPPORT.md`
|
||||
- 🏗️ 架构文档: `ARCHITECTURE.md`
|
||||
- 📝 项目概览: `PROJECT_OVERVIEW.md`
|
||||
|
||||
## 总结
|
||||
|
||||
核心修复点:
|
||||
1. ✅ 动态获取会话路径(不硬编码 "auto")
|
||||
2. ✅ 空路径监听(接收所有会话信号)
|
||||
3. ✅ 详细调试日志(便于诊断)
|
||||
4. ✅ 多重连接策略(提高兼容性)
|
||||
|
||||
大多数情况下,这些修复应该能解决问题。如果还有问题,使用提供的调试工具找出系统实际使用的信号机制。
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
#include <QDBusMessage>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusReply>
|
||||
|
||||
ScreenLockDetector::ScreenLockDetector(QObject *parent)
|
||||
: QObject(parent)
|
||||
|
|
@ -40,7 +41,9 @@ bool ScreenLockDetector::isScreenLocked() const
|
|||
|
||||
bool ScreenLockDetector::initialize()
|
||||
{
|
||||
qDebug() << "=================================================";
|
||||
qDebug() << "Initializing ScreenLockDetector...";
|
||||
qDebug() << "=================================================";
|
||||
|
||||
// 尝试连接到不同的DBus接口
|
||||
bool deepinOk = connectToDeepinDDE();
|
||||
|
|
@ -56,10 +59,12 @@ bool ScreenLockDetector::initialize()
|
|||
// 查询当前锁屏状态
|
||||
queryCurrentLockState();
|
||||
|
||||
qDebug() << "=================================================";
|
||||
qDebug() << "ScreenLockDetector initialized successfully";
|
||||
qDebug() << "Deepin DDE connected:" << m_deepinConnected;
|
||||
qDebug() << "GNOME ScreenSaver connected:" << m_gnomeConnected;
|
||||
qDebug() << "Login Manager connected:" << m_loginConnected;
|
||||
qDebug() << "=================================================";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -69,7 +74,9 @@ void ScreenLockDetector::setLockState(bool locked)
|
|||
if (m_isLocked != locked) {
|
||||
m_isLocked = locked;
|
||||
|
||||
qDebug() << "Screen lock state changed:" << (locked ? "LOCKED" : "UNLOCKED");
|
||||
qDebug() << "##################################################";
|
||||
qDebug() << "## Screen lock state changed:" << (locked ? "LOCKED" : "UNLOCKED");
|
||||
qDebug() << "##################################################";
|
||||
|
||||
emit lockStateChanged(locked);
|
||||
|
||||
|
|
@ -83,11 +90,9 @@ void ScreenLockDetector::setLockState(bool locked)
|
|||
|
||||
bool ScreenLockDetector::connectToGnomeScreenSaver()
|
||||
{
|
||||
// 连接到GNOME屏幕保护程序的DBus接口
|
||||
// Service: org.gnome.ScreenSaver
|
||||
// Path: /org/gnome/ScreenSaver
|
||||
// Interface: org.gnome.ScreenSaver
|
||||
qDebug() << "\n--- Connecting to GNOME ScreenSaver ---";
|
||||
|
||||
// 连接到GNOME屏幕保护程序的DBus接口
|
||||
m_gnomeInterface = new QDBusInterface(
|
||||
"org.gnome.ScreenSaver",
|
||||
"/org/gnome/ScreenSaver",
|
||||
|
|
@ -104,6 +109,8 @@ bool ScreenLockDetector::connectToGnomeScreenSaver()
|
|||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "GNOME ScreenSaver interface is valid";
|
||||
|
||||
// 连接ActiveChanged信号
|
||||
bool connected = QDBusConnection::sessionBus().connect(
|
||||
"org.gnome.ScreenSaver",
|
||||
|
|
@ -114,6 +121,8 @@ bool ScreenLockDetector::connectToGnomeScreenSaver()
|
|||
SLOT(onScreenSaverActiveChanged(bool))
|
||||
);
|
||||
|
||||
qDebug() << "GNOME ActiveChanged signal connected:" << connected;
|
||||
|
||||
if (!connected) {
|
||||
qWarning() << "Failed to connect to GNOME ScreenSaver ActiveChanged signal";
|
||||
delete m_gnomeInterface;
|
||||
|
|
@ -128,65 +137,134 @@ bool ScreenLockDetector::connectToGnomeScreenSaver()
|
|||
|
||||
bool ScreenLockDetector::connectToLoginManager()
|
||||
{
|
||||
// 连接到systemd-logind或其他登录管理器
|
||||
// Service: org.freedesktop.login1
|
||||
// Path: /org/freedesktop/login1/session/auto
|
||||
// Interface: org.freedesktop.login1.Session
|
||||
qDebug() << "\n--- Connecting to Login Manager (systemd-logind) ---";
|
||||
|
||||
m_loginInterface = new QDBusInterface(
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1/session/auto",
|
||||
"org.freedesktop.login1.Session",
|
||||
QDBusConnection::systemBus(),
|
||||
this
|
||||
);
|
||||
|
||||
if (!m_loginInterface->isValid()) {
|
||||
qDebug() << "Login1 interface not available:"
|
||||
<< m_loginInterface->lastError().message();
|
||||
delete m_loginInterface;
|
||||
m_loginInterface = nullptr;
|
||||
return false;
|
||||
// 首先获取当前会话的路径
|
||||
QString sessionPath = getCurrentSessionPath();
|
||||
if (sessionPath.isEmpty()) {
|
||||
qWarning() << "Could not determine current session path";
|
||||
qWarning() << "Will try to connect to generic session signals";
|
||||
} else {
|
||||
qDebug() << "Current session path:" << sessionPath;
|
||||
}
|
||||
|
||||
// 连接Lock信号
|
||||
// 方法1: 连接到特定会话路径(如果获取到了)
|
||||
if (!sessionPath.isEmpty()) {
|
||||
m_loginInterface = new QDBusInterface(
|
||||
"org.freedesktop.login1",
|
||||
sessionPath,
|
||||
"org.freedesktop.login1.Session",
|
||||
QDBusConnection::systemBus(),
|
||||
this
|
||||
);
|
||||
|
||||
if (m_loginInterface->isValid()) {
|
||||
qDebug() << "Login Manager interface is valid for session:" << sessionPath;
|
||||
|
||||
// 连接Lock和Unlock信号到特定会话
|
||||
bool lockConnected = QDBusConnection::systemBus().connect(
|
||||
"org.freedesktop.login1",
|
||||
sessionPath,
|
||||
"org.freedesktop.login1.Session",
|
||||
"Lock",
|
||||
this,
|
||||
SLOT(onSessionLocked())
|
||||
);
|
||||
|
||||
bool unlockConnected = QDBusConnection::systemBus().connect(
|
||||
"org.freedesktop.login1",
|
||||
sessionPath,
|
||||
"org.freedesktop.login1.Session",
|
||||
"Unlock",
|
||||
this,
|
||||
SLOT(onSessionUnlocked())
|
||||
);
|
||||
|
||||
qDebug() << "Session Lock signal connected:" << lockConnected;
|
||||
qDebug() << "Session Unlock signal connected:" << unlockConnected;
|
||||
|
||||
if (lockConnected || unlockConnected) {
|
||||
m_loginConnected = true;
|
||||
qDebug() << "Successfully connected to Login Manager via session path";
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Login Manager interface not valid:" << m_loginInterface->lastError().message();
|
||||
delete m_loginInterface;
|
||||
m_loginInterface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// 方法2: 监听所有会话的Lock/Unlock信号(不指定具体路径)
|
||||
qDebug() << "Attempting to connect to all login1 Session signals...";
|
||||
|
||||
bool lockConnected = QDBusConnection::systemBus().connect(
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1/session/auto",
|
||||
"", // 空路径表示监听所有对象
|
||||
"org.freedesktop.login1.Session",
|
||||
"Lock",
|
||||
this,
|
||||
SLOT(onSessionLocked())
|
||||
);
|
||||
|
||||
// 连接Unlock信号
|
||||
bool unlockConnected = QDBusConnection::systemBus().connect(
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1/session/auto",
|
||||
"", // 空路径表示监听所有对象
|
||||
"org.freedesktop.login1.Session",
|
||||
"Unlock",
|
||||
this,
|
||||
SLOT(onSessionUnlocked())
|
||||
);
|
||||
|
||||
if (!lockConnected || !unlockConnected) {
|
||||
qWarning() << "Failed to connect to Login Manager signals";
|
||||
delete m_loginInterface;
|
||||
m_loginInterface = nullptr;
|
||||
return false;
|
||||
qDebug() << "Generic Lock signal connected:" << lockConnected;
|
||||
qDebug() << "Generic Unlock signal connected:" << unlockConnected;
|
||||
|
||||
if (lockConnected || unlockConnected) {
|
||||
m_loginConnected = true;
|
||||
qDebug() << "Successfully connected to Login Manager via generic signals";
|
||||
return true;
|
||||
}
|
||||
|
||||
m_loginConnected = true;
|
||||
qDebug() << "Successfully connected to Login Manager";
|
||||
return true;
|
||||
qWarning() << "Failed to connect to Login Manager signals";
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ScreenLockDetector::getCurrentSessionPath()
|
||||
{
|
||||
// 尝试从环境变量获取
|
||||
QString xdgSessionId = qgetenv("XDG_SESSION_ID");
|
||||
if (!xdgSessionId.isEmpty()) {
|
||||
QString path = QString("/org/freedesktop/login1/session/%1").arg(xdgSessionId);
|
||||
qDebug() << "Session path from XDG_SESSION_ID:" << path;
|
||||
return path;
|
||||
}
|
||||
|
||||
// 尝试通过DBus调用获取当前会话
|
||||
QDBusInterface managerIface(
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1",
|
||||
"org.freedesktop.login1.Manager",
|
||||
QDBusConnection::systemBus()
|
||||
);
|
||||
|
||||
if (managerIface.isValid()) {
|
||||
// 获取当前用户的会话列表
|
||||
QDBusReply<QDBusObjectPath> reply = managerIface.call("GetSessionByPID", (quint32)QCoreApplication::applicationPid());
|
||||
if (reply.isValid()) {
|
||||
QString path = reply.value().path();
|
||||
qDebug() << "Session path from GetSessionByPID:" << path;
|
||||
return path;
|
||||
} else {
|
||||
qDebug() << "GetSessionByPID failed:" << reply.error().message();
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool ScreenLockDetector::connectToDeepinDDE()
|
||||
{
|
||||
// 尝试连接到多个可能的Deepin DDE DBus接口
|
||||
// Deepin不同版本可能使用不同的服务名称和信号
|
||||
|
||||
qDebug() << "Attempting to connect to Deepin DDE lock services...";
|
||||
qDebug() << "\n--- Connecting to Deepin DDE ---";
|
||||
|
||||
// 可能的服务配置列表
|
||||
struct DeepinService {
|
||||
|
|
@ -211,7 +289,7 @@ bool ScreenLockDetector::connectToDeepinDDE()
|
|||
};
|
||||
|
||||
for (const auto& svc : services) {
|
||||
qDebug() << "Trying service:" << svc.service;
|
||||
qDebug() << "Trying Deepin service:" << svc.service;
|
||||
|
||||
m_deepinInterface = new QDBusInterface(
|
||||
svc.service,
|
||||
|
|
@ -222,13 +300,13 @@ bool ScreenLockDetector::connectToDeepinDDE()
|
|||
);
|
||||
|
||||
if (!m_deepinInterface->isValid()) {
|
||||
qDebug() << " - Interface not available:" << m_deepinInterface->lastError().message();
|
||||
qDebug() << " Interface not available:" << m_deepinInterface->lastError().message();
|
||||
delete m_deepinInterface;
|
||||
m_deepinInterface = nullptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
qDebug() << " - Interface is valid, connecting signals...";
|
||||
qDebug() << " Interface is valid, connecting signals...";
|
||||
|
||||
// 尝试连接锁屏信号
|
||||
bool lockedConnected = QDBusConnection::sessionBus().connect(
|
||||
|
|
@ -249,8 +327,8 @@ bool ScreenLockDetector::connectToDeepinDDE()
|
|||
SLOT(onSessionUnlocked())
|
||||
);
|
||||
|
||||
qDebug() << " - Lock signal (" << svc.lockSignal << ") connected:" << lockedConnected;
|
||||
qDebug() << " - Unlock signal (" << svc.unlockSignal << ") connected:" << unlockedConnected;
|
||||
qDebug() << " Lock signal (" << svc.lockSignal << ") connected:" << lockedConnected;
|
||||
qDebug() << " Unlock signal (" << svc.unlockSignal << ") connected:" << unlockedConnected;
|
||||
|
||||
if (lockedConnected || unlockedConnected) {
|
||||
m_deepinConnected = true;
|
||||
|
|
@ -259,44 +337,44 @@ bool ScreenLockDetector::connectToDeepinDDE()
|
|||
return true;
|
||||
}
|
||||
|
||||
// 如果信号连接失败,清理接口
|
||||
qWarning() << " - Failed to connect signals for" << svc.service;
|
||||
qWarning() << " Failed to connect signals for" << svc.service;
|
||||
delete m_deepinInterface;
|
||||
m_deepinInterface = nullptr;
|
||||
}
|
||||
|
||||
qWarning() << "Failed to connect to any Deepin DDE lock service";
|
||||
qWarning() << "Please run debug_deepin_dbus.sh to find the correct service";
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScreenLockDetector::queryCurrentLockState()
|
||||
{
|
||||
qDebug() << "\n--- Querying current lock state ---";
|
||||
|
||||
// 尝试从Deepin DDE查询当前状态
|
||||
if (m_deepinInterface && m_deepinInterface->isValid()) {
|
||||
qDebug() << "Deepin DDE interface available, attempting to query lock state...";
|
||||
qDebug() << "Querying Deepin DDE lock state...";
|
||||
|
||||
// 尝试可能的查询方法
|
||||
QStringList possibleMethods = {"GetLocked", "IsLocked", "GetActive", "GetSessionLocked"};
|
||||
for (const QString& method : possibleMethods) {
|
||||
QDBusReply<bool> reply = m_deepinInterface->call(method);
|
||||
if (reply.isValid()) {
|
||||
bool locked = reply.value();
|
||||
qDebug() << "Successfully queried state via" << method << ":" << (locked ? "LOCKED" : "UNLOCKED");
|
||||
qDebug() << " Method" << method << "returned:" << (locked ? "LOCKED" : "UNLOCKED");
|
||||
setLockState(locked);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "No query method available, waiting for signals";
|
||||
qDebug() << " No query method worked, waiting for signals";
|
||||
}
|
||||
|
||||
// 尝试从GNOME屏幕保护程序查询当前状态
|
||||
if (m_gnomeInterface && m_gnomeInterface->isValid()) {
|
||||
qDebug() << "Querying GNOME ScreenSaver state...";
|
||||
QDBusReply<bool> reply = m_gnomeInterface->call("GetActive");
|
||||
if (reply.isValid()) {
|
||||
bool active = reply.value();
|
||||
qDebug() << "Current GNOME ScreenSaver state:" << (active ? "ACTIVE" : "INACTIVE");
|
||||
qDebug() << " Current GNOME ScreenSaver state:" << (active ? "ACTIVE/LOCKED" : "INACTIVE/UNLOCKED");
|
||||
setLockState(active);
|
||||
return;
|
||||
}
|
||||
|
|
@ -304,32 +382,78 @@ void ScreenLockDetector::queryCurrentLockState()
|
|||
|
||||
// 尝试从登录管理器查询锁定状态
|
||||
if (m_loginInterface && m_loginInterface->isValid()) {
|
||||
QDBusReply<QString> reply = m_loginInterface->call("GetProperty", "LockedHint");
|
||||
qDebug() << "Querying Login Manager lock state...";
|
||||
|
||||
// 尝试读取 LockedHint 属性
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(
|
||||
"org.freedesktop.login1",
|
||||
m_loginInterface->path(),
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"Get"
|
||||
);
|
||||
msg << "org.freedesktop.login1.Session" << "LockedHint";
|
||||
|
||||
QDBusReply<QVariant> reply = QDBusConnection::systemBus().call(msg);
|
||||
if (reply.isValid()) {
|
||||
// 注意:这个方法可能需要根据实际DBus接口调整
|
||||
qDebug() << "Queried login manager lock state";
|
||||
bool locked = reply.value().toBool();
|
||||
qDebug() << " LockedHint property:" << (locked ? "LOCKED" : "UNLOCKED");
|
||||
setLockState(locked);
|
||||
return;
|
||||
} else {
|
||||
qDebug() << " Could not read LockedHint:" << reply.error().message();
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "Could not query initial lock state, will detect on next lock/unlock event";
|
||||
}
|
||||
|
||||
void ScreenLockDetector::onScreenSaverActiveChanged(bool active)
|
||||
{
|
||||
qDebug() << "GNOME ScreenSaver ActiveChanged signal received:" << active;
|
||||
qDebug() << "##################################################";
|
||||
qDebug() << "## GNOME ScreenSaver ActiveChanged signal received";
|
||||
qDebug() << "## New state:" << (active ? "ACTIVE (LOCKED)" : "INACTIVE (UNLOCKED)");
|
||||
qDebug() << "##################################################";
|
||||
setLockState(active);
|
||||
}
|
||||
|
||||
void ScreenLockDetector::onSessionLocked()
|
||||
{
|
||||
qDebug() << "==================================================";
|
||||
qDebug() << "LOCK SIGNAL RECEIVED - Screen is now LOCKED";
|
||||
qDebug() << "==================================================";
|
||||
qDebug() << "##################################################";
|
||||
qDebug() << "## LOCK SIGNAL RECEIVED";
|
||||
qDebug() << "## Screen is now LOCKED";
|
||||
qDebug() << "## Sender:" << sender();
|
||||
|
||||
// 获取信号发送者的详细信息
|
||||
QDBusMessage msg = QDBusContext::message();
|
||||
if (msg.type() != QDBusMessage::InvalidMessage) {
|
||||
qDebug() << "## DBus Message Details:";
|
||||
qDebug() << "## Service:" << msg.service();
|
||||
qDebug() << "## Path:" << msg.path();
|
||||
qDebug() << "## Interface:" << msg.interface();
|
||||
qDebug() << "## Member:" << msg.member();
|
||||
}
|
||||
|
||||
qDebug() << "##################################################";
|
||||
setLockState(true);
|
||||
}
|
||||
|
||||
void ScreenLockDetector::onSessionUnlocked()
|
||||
{
|
||||
qDebug() << "==================================================";
|
||||
qDebug() << "UNLOCK SIGNAL RECEIVED - Screen is now UNLOCKED";
|
||||
qDebug() << "==================================================";
|
||||
qDebug() << "##################################################";
|
||||
qDebug() << "## UNLOCK SIGNAL RECEIVED";
|
||||
qDebug() << "## Screen is now UNLOCKED";
|
||||
qDebug() << "## Sender:" << sender();
|
||||
|
||||
// 获取信号发送者的详细信息
|
||||
QDBusMessage msg = QDBusContext::message();
|
||||
if (msg.type() != QDBusMessage::InvalidMessage) {
|
||||
qDebug() << "## DBus Message Details:";
|
||||
qDebug() << "## Service:" << msg.service();
|
||||
qDebug() << "## Path:" << msg.path();
|
||||
qDebug() << "## Interface:" << msg.interface();
|
||||
qDebug() << "## Member:" << msg.member();
|
||||
}
|
||||
|
||||
qDebug() << "##################################################";
|
||||
setLockState(false);
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@
|
|||
#include <QDBusConnection>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusReply>
|
||||
#include <QDBusContext>
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
||||
/**
|
||||
|
|
@ -13,7 +15,7 @@
|
|||
* 通过监听Linux系统的DBus信号来检测屏幕锁定/解锁状态
|
||||
* 支持多种桌面环境:Deepin DDE, GNOME, KDE, XFCE等
|
||||
*/
|
||||
class ScreenLockDetector : public QObject
|
||||
class ScreenLockDetector : public QObject, protected QDBusContext
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
@ -99,6 +101,12 @@ private:
|
|||
*/
|
||||
void queryCurrentLockState();
|
||||
|
||||
/**
|
||||
* @brief 获取当前会话的 DBus 路径
|
||||
* @return 当前会话的路径,如果无法确定则返回空字符串
|
||||
*/
|
||||
QString getCurrentSessionPath();
|
||||
|
||||
private:
|
||||
bool m_isLocked; // 当前锁屏状态
|
||||
QDBusInterface *m_gnomeInterface; // GNOME屏幕保护程序接口
|
||||
|
|
|
|||
|
|
@ -0,0 +1,251 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ========================================
|
||||
# DBus 锁屏信号测试脚本
|
||||
# 用于诊断为什么锁屏信号没有被接收到
|
||||
# ========================================
|
||||
|
||||
echo "========================================"
|
||||
echo "DBus Lock Signal Test Script"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 检查必要的工具
|
||||
echo "Checking required tools..."
|
||||
if ! command -v dbus-monitor &> /dev/null; then
|
||||
echo -e "${RED}✗${NC} dbus-monitor not found. Please install: sudo apt install dbus-x11"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v dbus-send &> /dev/null; then
|
||||
echo -e "${RED}✗${NC} dbus-send not found. Please install: sudo apt install dbus-x11"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✓${NC} All required tools available"
|
||||
echo ""
|
||||
|
||||
# ========================================
|
||||
# 1. 检查当前会话信息
|
||||
# ========================================
|
||||
echo "========================================"
|
||||
echo "Step 1: Session Information"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
echo "Environment Variables:"
|
||||
echo " XDG_SESSION_ID: ${XDG_SESSION_ID:-<not set>}"
|
||||
echo " XDG_SESSION_TYPE: ${XDG_SESSION_TYPE:-<not set>}"
|
||||
echo " XDG_CURRENT_DESKTOP: ${XDG_CURRENT_DESKTOP:-<not set>}"
|
||||
echo " DESKTOP_SESSION: ${DESKTOP_SESSION:-<not set>}"
|
||||
echo " GDMSESSION: ${GDMSESSION:-<not set>}"
|
||||
echo ""
|
||||
|
||||
# 尝试获取当前会话路径
|
||||
if [ -n "$XDG_SESSION_ID" ]; then
|
||||
SESSION_PATH="/org/freedesktop/login1/session/$XDG_SESSION_ID"
|
||||
echo "Calculated session path: $SESSION_PATH"
|
||||
echo ""
|
||||
|
||||
# 验证会话路径是否有效
|
||||
echo "Verifying session path..."
|
||||
if dbus-send --system --print-reply --dest=org.freedesktop.login1 \
|
||||
"$SESSION_PATH" \
|
||||
org.freedesktop.DBus.Introspectable.Introspect &>/dev/null; then
|
||||
echo -e "${GREEN}✓${NC} Session path is valid"
|
||||
else
|
||||
echo -e "${RED}✗${NC} Session path is not valid"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# ========================================
|
||||
# 2. 检查可用的锁屏相关服务
|
||||
# ========================================
|
||||
echo "========================================"
|
||||
echo "Step 2: Available Lock Services"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
echo "Checking Session Bus Services:"
|
||||
echo "-------------------------------"
|
||||
|
||||
# GNOME ScreenSaver
|
||||
echo -n " org.gnome.ScreenSaver: "
|
||||
if dbus-send --session --print-reply --dest=org.gnome.ScreenSaver \
|
||||
/org/gnome/ScreenSaver \
|
||||
org.freedesktop.DBus.Introspectable.Introspect &>/dev/null; then
|
||||
echo -e "${GREEN}Available${NC}"
|
||||
else
|
||||
echo -e "${RED}Not available${NC}"
|
||||
fi
|
||||
|
||||
# Deepin 相关服务
|
||||
DEEPIN_SERVICES=(
|
||||
"com.deepin.dde.lockFront"
|
||||
"com.deepin.ScreenSaver"
|
||||
"com.deepin.SessionManager"
|
||||
"org.deepin.dde.lockFront"
|
||||
)
|
||||
|
||||
for service in "${DEEPIN_SERVICES[@]}"; do
|
||||
echo -n " $service: "
|
||||
if dbus-send --session --print-reply --dest="$service" / \
|
||||
org.freedesktop.DBus.Introspectable.Introspect &>/dev/null; then
|
||||
echo -e "${GREEN}Available${NC}"
|
||||
else
|
||||
echo -e "${RED}Not available${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Checking System Bus Services:"
|
||||
echo "-----------------------------"
|
||||
|
||||
# systemd-logind
|
||||
echo -n " org.freedesktop.login1: "
|
||||
if dbus-send --system --print-reply --dest=org.freedesktop.login1 \
|
||||
/org/freedesktop/login1 \
|
||||
org.freedesktop.DBus.Introspectable.Introspect &>/dev/null; then
|
||||
echo -e "${GREEN}Available${NC}"
|
||||
else
|
||||
echo -e "${RED}Not available${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# ========================================
|
||||
# 3. 列出当前会话的所有可用信号
|
||||
# ========================================
|
||||
if [ -n "$SESSION_PATH" ]; then
|
||||
echo "========================================"
|
||||
echo "Step 3: Session Signals"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
echo "Available signals on $SESSION_PATH:"
|
||||
echo ""
|
||||
|
||||
dbus-send --system --print-reply --dest=org.freedesktop.login1 \
|
||||
"$SESSION_PATH" \
|
||||
org.freedesktop.DBus.Introspectable.Introspect 2>/dev/null | \
|
||||
grep -E "signal name" | sed 's/^[[:space:]]*/ /'
|
||||
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# ========================================
|
||||
# 4. 创建临时监听脚本
|
||||
# ========================================
|
||||
echo "========================================"
|
||||
echo "Step 4: Signal Monitoring Setup"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
TEMP_DIR="/tmp/lock_signal_test_$$"
|
||||
mkdir -p "$TEMP_DIR"
|
||||
|
||||
# Session bus monitor
|
||||
cat > "$TEMP_DIR/monitor_session.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
echo "=== Monitoring SESSION BUS ==="
|
||||
echo "Listening for lock-related signals..."
|
||||
echo ""
|
||||
dbus-monitor --session "type='signal'" 2>&1 | \
|
||||
grep --line-buffered -iE "signal|lock|Lock|screen|Screen|Active|active" | \
|
||||
while IFS= read -r line; do
|
||||
if echo "$line" | grep -q "signal"; then
|
||||
echo "$(date '+%H:%M:%S') [SIGNAL] $line"
|
||||
else
|
||||
echo "$(date '+%H:%M:%S') $line"
|
||||
fi
|
||||
done
|
||||
EOF
|
||||
|
||||
# System bus monitor
|
||||
cat > "$TEMP_DIR/monitor_system.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
echo "=== Monitoring SYSTEM BUS ==="
|
||||
echo "Listening for login1 Session signals..."
|
||||
echo ""
|
||||
dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Session'" 2>&1 | \
|
||||
grep --line-buffered -E "signal|Lock|Unlock|lock|unlock" | \
|
||||
while IFS= read -r line; do
|
||||
if echo "$line" | grep -q "signal"; then
|
||||
echo "$(date '+%H:%M:%S') [SIGNAL] $line"
|
||||
else
|
||||
echo "$(date '+%H:%M:%S') $line"
|
||||
fi
|
||||
done
|
||||
EOF
|
||||
|
||||
chmod +x "$TEMP_DIR/monitor_session.sh"
|
||||
chmod +x "$TEMP_DIR/monitor_system.sh"
|
||||
|
||||
echo "Monitoring scripts created in: $TEMP_DIR"
|
||||
echo ""
|
||||
|
||||
# ========================================
|
||||
# 5. 开始监听
|
||||
# ========================================
|
||||
echo "========================================"
|
||||
echo "Step 5: Real-time Signal Monitoring"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Instructions:${NC}"
|
||||
echo " 1. This script will now monitor DBus signals"
|
||||
echo " 2. Open another terminal and lock your screen:"
|
||||
echo " - Press Super+L (or Ctrl+Alt+L)"
|
||||
echo " - Or run: gnome-screensaver-command -l"
|
||||
echo " - Or run: dde-lock (on Deepin)"
|
||||
echo " 3. Observe which signals appear below"
|
||||
echo " 4. Unlock your screen"
|
||||
echo " 5. Press Ctrl+C to stop monitoring"
|
||||
echo ""
|
||||
echo -e "${CYAN}Monitoring both SESSION and SYSTEM buses...${NC}"
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# 创建日志文件
|
||||
LOG_FILE="$TEMP_DIR/signals.log"
|
||||
|
||||
# 在后台启动两个监听器
|
||||
"$TEMP_DIR/monitor_session.sh" 2>&1 | tee -a "$LOG_FILE" &
|
||||
SESSION_PID=$!
|
||||
|
||||
"$TEMP_DIR/monitor_system.sh" 2>&1 | tee -a "$LOG_FILE" &
|
||||
SYSTEM_PID=$!
|
||||
|
||||
# 等待用户中断
|
||||
wait_for_user() {
|
||||
while true; do
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
# 捕获 Ctrl+C
|
||||
trap "echo ''; echo 'Stopping monitors...'; kill $SESSION_PID $SYSTEM_PID 2>/dev/null; exit 0" INT TERM
|
||||
|
||||
wait_for_user
|
||||
|
||||
# ========================================
|
||||
# 清理
|
||||
# ========================================
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo "Cleanup"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
echo "Log file saved to: $LOG_FILE"
|
||||
echo "You can review it with: cat $LOG_FILE"
|
||||
echo ""
|
||||
echo "To clean up: rm -rf $TEMP_DIR"
|
||||
echo ""
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ========================================
|
||||
# 快速验证锁屏信号修复脚本
|
||||
# ========================================
|
||||
|
||||
echo "========================================"
|
||||
echo "Lock Signal Fix Verification Script"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 检查编译是否最新
|
||||
echo "Step 1: Checking build..."
|
||||
echo "--------------------------------------"
|
||||
if [ ! -f "build/bin/ScreenLockDemo" ]; then
|
||||
echo -e "${RED}✗${NC} Executable not found. Running build..."
|
||||
./build.sh
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}✗${NC} Build failed!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "${GREEN}✓${NC} Executable exists"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 检查环境信息
|
||||
echo "Step 2: Environment Information"
|
||||
echo "--------------------------------------"
|
||||
echo "Desktop Environment:"
|
||||
echo " XDG_CURRENT_DESKTOP: ${XDG_CURRENT_DESKTOP:-<not set>}"
|
||||
echo " DESKTOP_SESSION: ${DESKTOP_SESSION:-<not set>}"
|
||||
echo ""
|
||||
echo "Session Information:"
|
||||
echo " XDG_SESSION_ID: ${XDG_SESSION_ID:-<not set>}"
|
||||
echo " XDG_SESSION_TYPE: ${XDG_SESSION_TYPE:-<not set>}"
|
||||
echo ""
|
||||
|
||||
# 计算会话路径
|
||||
if [ -n "$XDG_SESSION_ID" ]; then
|
||||
SESSION_PATH="/org/freedesktop/login1/session/$XDG_SESSION_ID"
|
||||
echo "Expected session path: $SESSION_PATH"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 检查可用的服务
|
||||
echo "Step 3: Available DBus Services"
|
||||
echo "--------------------------------------"
|
||||
|
||||
echo "Checking for lock services:"
|
||||
|
||||
# GNOME ScreenSaver
|
||||
echo -n " org.gnome.ScreenSaver (session): "
|
||||
if dbus-send --session --print-reply --dest=org.gnome.ScreenSaver \
|
||||
/org/gnome/ScreenSaver \
|
||||
org.freedesktop.DBus.Introspectable.Introspect &>/dev/null; then
|
||||
echo -e "${GREEN}✓ Available${NC}"
|
||||
HAS_SERVICE=1
|
||||
else
|
||||
echo -e "${RED}✗ Not available${NC}"
|
||||
fi
|
||||
|
||||
# systemd-logind
|
||||
echo -n " org.freedesktop.login1 (system): "
|
||||
if dbus-send --system --print-reply --dest=org.freedesktop.login1 \
|
||||
/org/freedesktop/login1 \
|
||||
org.freedesktop.DBus.Introspectable.Introspect &>/dev/null; then
|
||||
echo -e "${GREEN}✓ Available${NC}"
|
||||
HAS_SERVICE=1
|
||||
else
|
||||
echo -e "${RED}✗ Not available${NC}"
|
||||
fi
|
||||
|
||||
# Deepin services
|
||||
DEEPIN_SERVICES=(
|
||||
"com.deepin.dde.lockFront"
|
||||
"com.deepin.ScreenSaver"
|
||||
"org.deepin.dde.lockFront"
|
||||
)
|
||||
|
||||
for service in "${DEEPIN_SERVICES[@]}"; do
|
||||
echo -n " $service (session): "
|
||||
if dbus-send --session --print-reply --dest="$service" / \
|
||||
org.freedesktop.DBus.Introspectable.Introspect &>/dev/null; then
|
||||
echo -e "${GREEN}✓ Available${NC}"
|
||||
HAS_SERVICE=1
|
||||
else
|
||||
echo -e "${RED}✗ Not available${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
if [ -z "$HAS_SERVICE" ]; then
|
||||
echo -e "${YELLOW}⚠ Warning: No lock services detected${NC}"
|
||||
echo "This might be expected if running in a minimal environment"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 运行程序
|
||||
echo "Step 4: Running Application"
|
||||
echo "--------------------------------------"
|
||||
echo ""
|
||||
echo -e "${CYAN}The application will now start.${NC}"
|
||||
echo -e "${CYAN}Please check the output for connection status.${NC}"
|
||||
echo ""
|
||||
echo "Look for these indicators:"
|
||||
echo " ${GREEN}✓${NC} 'ScreenLockDetector initialized successfully'"
|
||||
echo " ${GREEN}✓${NC} At least one 'connected: true'"
|
||||
echo " ${GREEN}✓${NC} Valid session path (not 'auto')"
|
||||
echo ""
|
||||
echo "Then test by locking your screen:"
|
||||
echo " - Press ${BLUE}Super+L${NC} or ${BLUE}Ctrl+Alt+L${NC}"
|
||||
echo " - Look for ${GREEN}'LOCK SIGNAL RECEIVED'${NC} in the output"
|
||||
echo " - Unlock and look for ${GREEN}'UNLOCK SIGNAL RECEIVED'${NC}"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to stop the application when done."
|
||||
echo ""
|
||||
|
||||
read -p "Press ENTER to start the application..."
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo "Application Output:"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
cd build/bin
|
||||
./ScreenLockDemo
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo "Application stopped"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# 提供进一步调试建议
|
||||
echo "If signals were NOT received:"
|
||||
echo "--------------------------------------"
|
||||
echo "1. Run the detailed test script:"
|
||||
echo " ${CYAN}./test_lock_signals.sh${NC}"
|
||||
echo ""
|
||||
echo "2. Check what signals your system actually sends:"
|
||||
echo " ${CYAN}dbus-monitor --system \"type='signal',interface='org.freedesktop.login1.Session'\"${NC}"
|
||||
echo " Then lock your screen in another terminal"
|
||||
echo ""
|
||||
echo "3. For Deepin systems, run:"
|
||||
echo " ${CYAN}./debug_deepin_dbus.sh${NC}"
|
||||
echo ""
|
||||
echo "4. Check session status:"
|
||||
echo " ${CYAN}loginctl show-session \$XDG_SESSION_ID${NC}"
|
||||
echo ""
|
||||
echo "5. Review the detailed fix guide:"
|
||||
echo " ${CYAN}cat LOCK_SIGNAL_FIX.md${NC}"
|
||||
echo ""
|
||||
Loading…
Reference in New Issue