Skip to content

Commit 22b7784

Browse files
mhduiy18202781743
authored andcommitted
fix: add X connection monitoring for session logout
Added XCB dependency and implemented X server connection monitoring to detect when the X server disconnects. This ensures the session properly logs out when the X server connection is lost, preventing orphaned sessions. 1. Added libxcb1-dev to Build-Depends in debian/control 2. Added XCB pkg-config check and linking in CMakeLists.txt 3. Implemented watchXConnection() method that establishes an XCB connection and monitors the file descriptor using QSocketNotifier 4. When X connection errors are detected, the session automatically triggers logout to clean up resources 5. Only activates on X11 displays, not Wayland This fix addresses cases where X server crashes or disconnects unexpectedly, leaving the session manager running without a display server. fix: 添加X连接监控以实现会话登出 添加XCB依赖并实现X服务器连接监控,以检测X服务器断开连接的情况。这确保当X 服务器连接丢失时会话能正确登出,防止出现孤儿会话。 1. 在debian/control的Build-Depends中添加libxcb1-dev 2. 在CMakeLists.txt中添加XCB pkg-config检查和链接 3. 实现watchXConnection()方法,使用XCB建立连接并通过QSocketNotifier监控 文件描述符 4. 当检测到X连接错误时,会话自动触发登出以清理资源 5. 仅在X11显示环境下激活,Wayland环境下不启用 此修复解决了X服务器崩溃或意外断开连接时,会话管理器在没有显示服务器的情 况下继续运行的问题。 PMS: BUG-353461
1 parent 6dd2af9 commit 22b7784

4 files changed

Lines changed: 38 additions & 1 deletion

File tree

debian/control

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Build-Depends:
1616
libxfixes-dev,
1717
pkg-config,
1818
qt6-base-dev,
19+
libxcb1-dev,
1920
Standards-Version: 4.1.3
2021
Homepage: https://www.deepin.org
2122

src/dde-session/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
1+
# SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
22
#
33
# SPDX-License-Identifier: CC0-1.0
44

@@ -14,6 +14,7 @@ pkg_check_modules(GIO2 REQUIRED IMPORTED_TARGET gio-2.0)
1414
pkg_check_modules(XCURSOR REQUIRED IMPORTED_TARGET xcursor)
1515
pkg_check_modules(XFIXES REQUIRED IMPORTED_TARGET xfixes)
1616
pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11)
17+
pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb)
1718

1819
# dbus adaptor
1920
qt_add_dbus_adaptor(ADAPTER_SOURCES
@@ -91,6 +92,7 @@ target_link_libraries(dde-session
9192
PkgConfig::XCURSOR
9293
PkgConfig::XFIXES
9394
PkgConfig::X11
95+
PkgConfig::XCB
9496
)
9597

9698
target_include_directories(dde-session PUBLIC

src/dde-session/impl/sessionmanager.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
#include <QFile>
1919
#include <QDBusPendingCall>
2020
#include <QDBusPendingCallWatcher>
21+
#include <QSocketNotifier>
2122

2223
#include <unistd.h>
2324
#include <signal.h>
25+
#include <xcb/xcb.h>
2426

2527
#define MASK_SERVICE(service) \
2628
{\
@@ -541,9 +543,40 @@ void SessionManager::init()
541543
startAtSpiService();
542544
startObexService();
543545

546+
if (!Utils::IS_WAYLAND_DISPLAY) {
547+
watchXConnection();
548+
}
549+
544550
qInfo() << "session manager init finished";
545551
}
546552

553+
void SessionManager::watchXConnection()
554+
{
555+
xcb_connection_t *conn = xcb_connect(nullptr, nullptr);
556+
if (xcb_connection_has_error(conn)) {
557+
qWarning() << "watchXConnection: failed to connect to X server";
558+
xcb_disconnect(conn);
559+
return;
560+
}
561+
562+
int fd = xcb_get_file_descriptor(conn);
563+
auto *notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
564+
connect(notifier, &QSocketNotifier::activated, this, [=]() {
565+
// 排空所有待处理事件
566+
xcb_generic_event_t *ev;
567+
while ((ev = xcb_poll_for_event(conn)) != nullptr) {
568+
free(ev);
569+
}
570+
// 若连接已断开则触发登出
571+
if (xcb_connection_has_error(conn)) {
572+
qWarning() << "X connection closed, logging out";
573+
notifier->setEnabled(false);
574+
xcb_disconnect(conn);
575+
doLogout();
576+
}
577+
});
578+
}
579+
547580
void SessionManager::stopSogouIme()
548581
{
549582
// TODO 使用kill函数杀死进程,前提是进程存在

src/dde-session/impl/sessionmanager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public Q_SLOTS:
100100
void setDPMSMode(bool on);
101101

102102
void handleOSSignal();
103+
void watchXConnection();
103104

104105
void shutdown(bool force);
105106
void reboot(bool force);

0 commit comments

Comments
 (0)