From f0c6eb5e9d7bdb259ed7f532a7faafd73fbd5d84 Mon Sep 17 00:00:00 2001
From: liuxinhao <liuxinhao@kylinsec.com.cn>
Date: Tue, 13 Jun 2023 20:33:24 +0800
Subject: [PATCH] fix(crash&block): Fixed the crash caused by the exit slot not
 being disconnected in time, as well as SIGTERM processing where there may be
 blocking in the X event
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- 修复退出槽未及时断开导致的崩溃，以及SIGTERM处理中，可能会有阻塞在X事件中
---
 src/lightdm-greeter/main.cpp                |  3 --
 src/lightdm-greeter/term-signal-handler.cpp |  1 +
 src/lightdm-greeter/widgets/user-list.cpp   | 42 +++++++++++----------
 src/lightdm-greeter/widgets/user-list.h     |  1 +
 4 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/src/lightdm-greeter/main.cpp b/src/lightdm-greeter/main.cpp
index cec93b0..49911d6 100644
--- a/src/lightdm-greeter/main.cpp
+++ b/src/lightdm-greeter/main.cpp
@@ -122,9 +122,6 @@ int main(int argc, char* argv[])
     QApplication app(argc, argv);
     QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
 
-    TermSignalHandler signalHandler;
-    signalHandler.init();
-
     Prefs::globalInit();
     auto prefs = Prefs::getInstance();
 
diff --git a/src/lightdm-greeter/term-signal-handler.cpp b/src/lightdm-greeter/term-signal-handler.cpp
index 3a6dbde..5375d19 100644
--- a/src/lightdm-greeter/term-signal-handler.cpp
+++ b/src/lightdm-greeter/term-signal-handler.cpp
@@ -22,6 +22,7 @@
 #include <QApplication>
 #include <QSocketNotifier>
 
+//FIXME：该种方式退出时,可能会有线程阻塞在xcb_wait_for_reply
 namespace Kiran
 {
 namespace SessionGuard
diff --git a/src/lightdm-greeter/widgets/user-list.cpp b/src/lightdm-greeter/widgets/user-list.cpp
index 1bdbbd3..c84ed1d 100644
--- a/src/lightdm-greeter/widgets/user-list.cpp
+++ b/src/lightdm-greeter/widgets/user-list.cpp
@@ -42,6 +42,7 @@ UserList::UserList(QWidget *parent)
 
 UserList::~UserList()
 {
+    disconnect(qApp, &QApplication::focusChanged,this,&UserList::onAppFocusChanged);
     delete ui;
 }
 
@@ -137,25 +138,7 @@ void UserList::initUI()
     /// 连接QApplication的焦点切换信号
     /// 处理ListWidget内部焦点切换或焦点切换出ListWidge，滑动条特殊处理
     /// 处理当焦点从外部到UserItem时，应默认到当前行
-    connect(qApp, &QApplication::focusChanged, [this](QWidget *oldWidget, QWidget *newWidget)
-            {
-                bool oldFocusInList = oldWidget == nullptr ? false : oldWidget->objectName() == USERITEM_OBJ_NAME;
-                bool newFocusInList = newWidget == nullptr ? false : newWidget->objectName() == USERITEM_OBJ_NAME;
-                if (!oldFocusInList && !newFocusInList)
-                {
-                    return;
-                }
-                else if (newFocusInList)
-                {  ///UserItem->UserItem,滚动到焦点行
-                    UserItem *userItem = dynamic_cast<UserItem *>(newWidget);
-                    const QListWidgetItem *listItem = userItem->getListItem();
-                    ui->userList->scrollToItem(listItem);
-                }
-                else if (oldFocusInList)
-                {  ///UserItem->外部，滚动到当前行
-                    ui->userList->scrollToItem(ui->userList->currentItem());
-                }
-            });
+    connect(qApp, &QApplication::focusChanged,this,&UserList::onAppFocusChanged);
 }
 
 void UserList::loadUserList()
@@ -376,6 +359,27 @@ void UserList::onModelRowsInserted(const QModelIndex &parent, int first, int las
     emit userCountChanged(oldCount, newCount);
 }
 
+void UserList::onAppFocusChanged(QWidget *oldFocus, QWidget *newFocus)
+{
+    bool oldFocusInList = oldFocus == nullptr ? false : oldFocus->objectName() == USERITEM_OBJ_NAME;
+    bool newFocusInList = newFocus == nullptr ? false : newFocus->objectName() == USERITEM_OBJ_NAME;
+
+    if (!oldFocusInList && !newFocusInList)
+    {
+        return;
+    }
+    else if (newFocusInList)
+    {  /// UserItem->UserItem,滚动到焦点行
+        UserItem *userItem = dynamic_cast<UserItem *>(newFocus);
+        const QListWidgetItem *listItem = userItem->getListItem();
+        ui->userList->scrollToItem(listItem);
+    }
+    else if (oldFocusInList)
+    {  /// UserItem->外部，滚动到当前行
+        ui->userList->scrollToItem(ui->userList->currentItem());
+    }
+}
+
 QSize UserList::sizeHint() const
 {
     QSize size(0, (ui->userList->count() * 62) + 2);
diff --git a/src/lightdm-greeter/widgets/user-list.h b/src/lightdm-greeter/widgets/user-list.h
index 4251990..9e45f61 100644
--- a/src/lightdm-greeter/widgets/user-list.h
+++ b/src/lightdm-greeter/widgets/user-list.h
@@ -61,6 +61,7 @@ private slots:
     void onUserItemActivated();
     void onModelRowsRemoved(const QModelIndex &parent, int first, int last);
     void onModelRowsInserted(const QModelIndex &parent, int first, int last);
+    void onAppFocusChanged(QWidget* oldFocus,QWidget* newFocus);
 
 Q_SIGNALS:
     void userActivated(const UserInfo &userInfo);
-- 
2.33.0

