From 5cf42cb04cac2926a4ee8c0c45ee795c3f77f51b Mon Sep 17 00:00:00 2001 From: liuxinhao Date: Tue, 12 Sep 2023 15:01:41 +0800 Subject: [PATCH] fix(logout): Fixed the shutdown of the screensaver process when the logout query phase window was closed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复由于注销询问阶段,窗口被关闭导致屏保进程退出,后续无法锁屏的问题 Closes #15523 --- src/grab/grab.cpp | 21 ++++++++++++++++++++- src/grab/grab.h | 3 ++- src/grab/invisible-window.cpp | 6 ++++++ src/grab/invisible-window.h | 6 ++++++ src/main.cpp | 7 +++++++ 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/grab/grab.cpp b/src/grab/grab.cpp index 3c4a079..8bffc7e 100644 --- a/src/grab/grab.cpp +++ b/src/grab/grab.cpp @@ -23,6 +23,7 @@ #include #include #include +#include using namespace Kiran::ScreenSaver; @@ -72,13 +73,31 @@ Grab* Grab::getInstance() Grab::~Grab() { - // delete m_invisibleWindow; + delete m_recreateInvisibleWindowTimer; + delete m_invisibleWindow; } Grab::Grab() { m_invisibleWindow = new InvisibleWindow; m_invisibleWindow->show(); + + //NOTE: + // #15523 + // xsmp SmSaveGlobal 询问退出阶段, QGuiApplicationPrivate::commitData会尝试关闭所有窗口 + // 该点会导致invisible window close + // 通过感知close事件后,重新拉取invisible window避免注销取消后,无法抓取输入到离屏窗口之上的问题 + m_recreateInvisibleWindowTimer = new QTimer; + m_recreateInvisibleWindowTimer->setSingleShot(true); + m_recreateInvisibleWindowTimer->setInterval(0); + + QObject::connect(m_recreateInvisibleWindowTimer,&QTimer::timeout,[this](){ + this->m_invisibleWindow->show(); + }); + + QObject::connect(m_invisibleWindow,&InvisibleWindow::windowClosed,[this](){ + this->m_recreateInvisibleWindowTimer->start(); + }); } void Grab::releaseGrab() diff --git a/src/grab/grab.h b/src/grab/grab.h index f4e3d16..c77273c 100644 --- a/src/grab/grab.h +++ b/src/grab/grab.h @@ -18,7 +18,7 @@ #include - +class QTimer; namespace Kiran { namespace ScreenSaver @@ -53,6 +53,7 @@ private: private: InvisibleWindow* m_invisibleWindow = nullptr; WId m_grabWID = 0; + QTimer* m_recreateInvisibleWindowTimer; }; } // namespace ScreenSaver } // namespace Kiran diff --git a/src/grab/invisible-window.cpp b/src/grab/invisible-window.cpp index ddd51ae..59f93f5 100644 --- a/src/grab/invisible-window.cpp +++ b/src/grab/invisible-window.cpp @@ -25,4 +25,10 @@ InvisibleWindow::InvisibleWindow(QWidget *parent) InvisibleWindow::~InvisibleWindow() { +} + +void InvisibleWindow::closeEvent(QCloseEvent *event) +{ + emit windowClosed(); + QWidget::closeEvent(event); } \ No newline at end of file diff --git a/src/grab/invisible-window.h b/src/grab/invisible-window.h index 1a51c00..08d0359 100644 --- a/src/grab/invisible-window.h +++ b/src/grab/invisible-window.h @@ -30,6 +30,12 @@ class InvisibleWindow : public QWidget public: InvisibleWindow(QWidget* parent = nullptr); ~InvisibleWindow(); + +signals: + void windowClosed(); + +protected: + void closeEvent(QCloseEvent *event) override; }; } // namespace ScreenSaver } // namespace Kiran diff --git a/src/main.cpp b/src/main.cpp index 777defe..4c1a9d7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,13 @@ int main(int argc, char *argv[]) KiranApplication app(argc, argv); + //NOTE: + // #15523 + // xsmp QueryEndSession 会话询问退出阶段 + // QxcbSessionManager -> QGuiApplicationPrivate::commitData将会尝试关闭所有窗口,导致进程退出 + // 屏保服务需加入该标识,窗口全部关闭时也不退出 + QGuiApplication::setQuitOnLastWindowClosed(false); + int xsetProcess = QProcess::execute("xset",QStringList() << "s" << "0" << "0"); auto translator = new QTranslator; -- 2.33.0