diff --git a/debian/control b/debian/control index 7a4fc96..ff9279d 100644 --- a/debian/control +++ b/debian/control @@ -16,6 +16,7 @@ Build-Depends: libxfixes-dev, pkg-config, qt6-base-dev, + libxcb1-dev, Standards-Version: 4.1.3 Homepage: https://www.deepin.org diff --git a/src/dde-session/CMakeLists.txt b/src/dde-session/CMakeLists.txt index 832cc9d..249b2a0 100644 --- a/src/dde-session/CMakeLists.txt +++ b/src/dde-session/CMakeLists.txt @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +# SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: CC0-1.0 @@ -14,6 +14,7 @@ pkg_check_modules(GIO2 REQUIRED IMPORTED_TARGET gio-2.0) pkg_check_modules(XCURSOR REQUIRED IMPORTED_TARGET xcursor) pkg_check_modules(XFIXES REQUIRED IMPORTED_TARGET xfixes) pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11) +pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb) # dbus adaptor qt_add_dbus_adaptor(ADAPTER_SOURCES @@ -91,6 +92,7 @@ target_link_libraries(dde-session PkgConfig::XCURSOR PkgConfig::XFIXES PkgConfig::X11 + PkgConfig::XCB ) target_include_directories(dde-session PUBLIC diff --git a/src/dde-session/impl/sessionmanager.cpp b/src/dde-session/impl/sessionmanager.cpp index 7a27f6c..9b50d3e 100644 --- a/src/dde-session/impl/sessionmanager.cpp +++ b/src/dde-session/impl/sessionmanager.cpp @@ -18,9 +18,11 @@ #include #include #include +#include #include #include +#include #define MASK_SERVICE(service) \ {\ @@ -541,9 +543,40 @@ void SessionManager::init() startAtSpiService(); startObexService(); + if (!Utils::IS_WAYLAND_DISPLAY) { + watchXConnection(); + } + qInfo() << "session manager init finished"; } +void SessionManager::watchXConnection() +{ + xcb_connection_t *conn = xcb_connect(nullptr, nullptr); + if (xcb_connection_has_error(conn)) { + qWarning() << "watchXConnection: failed to connect to X server"; + xcb_disconnect(conn); + return; + } + + int fd = xcb_get_file_descriptor(conn); + auto *notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); + connect(notifier, &QSocketNotifier::activated, this, [=]() { + // 排空所有待处理事件 + xcb_generic_event_t *ev; + while ((ev = xcb_poll_for_event(conn)) != nullptr) { + free(ev); + } + // 若连接已断开则触发登出 + if (xcb_connection_has_error(conn)) { + qWarning() << "X connection closed, logging out"; + notifier->setEnabled(false); + xcb_disconnect(conn); + doLogout(); + } + }); +} + void SessionManager::stopSogouIme() { // TODO 使用kill函数杀死进程,前提是进程存在 diff --git a/src/dde-session/impl/sessionmanager.h b/src/dde-session/impl/sessionmanager.h index 5d5b867..5b2e12e 100644 --- a/src/dde-session/impl/sessionmanager.h +++ b/src/dde-session/impl/sessionmanager.h @@ -100,6 +100,7 @@ public Q_SLOTS: void setDPMSMode(bool on); void handleOSSignal(); + void watchXConnection(); void shutdown(bool force); void reboot(bool force);