From aaae72a4f2936df84dbb94052c0d303a1fcc33a9 Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@hotmail.de>
Date: Thu, 13 Jan 2022 04:16:11 +0100
Subject: [PATCH] Fix focus and qml parenting with qml root

---
 resources/qml/PrivacyScreen.qml                       |  2 +-
 .../qml/device-verification/DeviceVerification.qml    |  1 -
 resources/qml/dialogs/ImagePackEditorDialog.qml       |  2 --
 resources/qml/dialogs/ImagePackSettingsDialog.qml     |  1 -
 resources/qml/dialogs/InputDialog.qml                 |  1 -
 resources/qml/dialogs/InviteDialog.qml                |  1 -
 resources/qml/dialogs/JoinRoomDialog.qml              |  1 -
 resources/qml/dialogs/PhoneNumberInputDialog.qml      |  1 -
 resources/qml/dialogs/RawMessageDialog.qml            |  1 -
 resources/qml/dialogs/ReadReceipts.qml                |  1 -
 resources/qml/dialogs/RoomDirectory.qml               |  1 -
 resources/qml/dialogs/RoomMembers.qml                 |  1 -
 resources/qml/dialogs/RoomSettings.qml                |  1 -
 resources/qml/dialogs/UserProfile.qml                 |  4 ----
 src/ChatPage.cpp                                      |  2 --
 src/ChatPage.h                                        |  1 -
 src/MainWindow.cpp                                    |  6 ------
 src/MainWindow.h                                      |  1 -
 src/timeline/TimelineModel.cpp                        |  2 +-
 src/timeline/TimelineViewManager.cpp                  | 11 +++++++++++
 src/timeline/TimelineViewManager.h                    | 11 ++---------
 21 files changed, 15 insertions(+), 38 deletions(-)

diff --git a/resources/qml/PrivacyScreen.qml b/resources/qml/PrivacyScreen.qml
index 6ad2a5574..fb3818df3 100644
--- a/resources/qml/PrivacyScreen.qml
+++ b/resources/qml/PrivacyScreen.qml
@@ -26,7 +26,7 @@ Item {
             }
         }
 
-        target: MainWindow
+        target: TimelineManager
     }
 
     Timer {
diff --git a/resources/qml/device-verification/DeviceVerification.qml b/resources/qml/device-verification/DeviceVerification.qml
index c00a0bdba..90dc9ac47 100644
--- a/resources/qml/device-verification/DeviceVerification.qml
+++ b/resources/qml/device-verification/DeviceVerification.qml
@@ -21,7 +21,6 @@ ApplicationWindow {
     minimumHeight: stack.implicitHeight
     width: stack.implicitWidth
     flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
-    Component.onCompleted: Nheko.reparent(dialog)
 
     StackView {
         id: stack
diff --git a/resources/qml/dialogs/ImagePackEditorDialog.qml b/resources/qml/dialogs/ImagePackEditorDialog.qml
index 3ba04d949..9c46a4908 100644
--- a/resources/qml/dialogs/ImagePackEditorDialog.qml
+++ b/resources/qml/dialogs/ImagePackEditorDialog.qml
@@ -12,8 +12,6 @@ import QtQuick.Layouts 1.12
 import im.nheko 1.0
 
 ApplicationWindow {
-    //Component.onCompleted: Nheko.reparent(win)
-
     id: win
 
     property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 2.3)
diff --git a/resources/qml/dialogs/ImagePackSettingsDialog.qml b/resources/qml/dialogs/ImagePackSettingsDialog.qml
index fa079855a..18c32c416 100644
--- a/resources/qml/dialogs/ImagePackSettingsDialog.qml
+++ b/resources/qml/dialogs/ImagePackSettingsDialog.qml
@@ -28,7 +28,6 @@ ApplicationWindow {
     color: Nheko.colors.base
     modality: Qt.NonModal
     flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
-    Component.onCompleted: Nheko.reparent(win)
 
     Component {
         id: packEditor
diff --git a/resources/qml/dialogs/InputDialog.qml b/resources/qml/dialogs/InputDialog.qml
index 63ca31818..cf1474dc6 100644
--- a/resources/qml/dialogs/InputDialog.qml
+++ b/resources/qml/dialogs/InputDialog.qml
@@ -18,7 +18,6 @@ ApplicationWindow {
 
     modality: Qt.NonModal
     flags: Qt.Dialog
-    Component.onCompleted: Nheko.reparent(inputDialog)
     width: 350
     height: fontMetrics.lineSpacing * 7
 
diff --git a/resources/qml/dialogs/InviteDialog.qml b/resources/qml/dialogs/InviteDialog.qml
index 917bc8567..e7dd4e3a2 100644
--- a/resources/qml/dialogs/InviteDialog.qml
+++ b/resources/qml/dialogs/InviteDialog.qml
@@ -37,7 +37,6 @@ ApplicationWindow {
     palette: Nheko.colors
     color: Nheko.colors.window
     flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
-    Component.onCompleted: Nheko.reparent(inviteDialogRoot)
 
     Shortcut {
         sequence: "Ctrl+Enter"
diff --git a/resources/qml/dialogs/JoinRoomDialog.qml b/resources/qml/dialogs/JoinRoomDialog.qml
index 9ce6bcf15..e49f538d6 100644
--- a/resources/qml/dialogs/JoinRoomDialog.qml
+++ b/resources/qml/dialogs/JoinRoomDialog.qml
@@ -17,7 +17,6 @@ ApplicationWindow {
     flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
     palette: Nheko.colors
     color: Nheko.colors.window
-    Component.onCompleted: Nheko.reparent(joinRoomRoot)
     width: 350
     height: fontMetrics.lineSpacing * 7
 
diff --git a/resources/qml/dialogs/PhoneNumberInputDialog.qml b/resources/qml/dialogs/PhoneNumberInputDialog.qml
index 399b11d51..9c36c98ff 100644
--- a/resources/qml/dialogs/PhoneNumberInputDialog.qml
+++ b/resources/qml/dialogs/PhoneNumberInputDialog.qml
@@ -19,7 +19,6 @@ ApplicationWindow {
 
     modality: Qt.NonModal
     flags: Qt.Dialog
-    Component.onCompleted: Nheko.reparent(inputDialog)
     width: 350
     height: fontMetrics.lineSpacing * 7
 
diff --git a/resources/qml/dialogs/RawMessageDialog.qml b/resources/qml/dialogs/RawMessageDialog.qml
index 34104394e..774b078be 100644
--- a/resources/qml/dialogs/RawMessageDialog.qml
+++ b/resources/qml/dialogs/RawMessageDialog.qml
@@ -17,7 +17,6 @@ ApplicationWindow {
     palette: Nheko.colors
     color: Nheko.colors.window
     flags: Qt.Tool | Qt.WindowStaysOnTopHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
-    Component.onCompleted: Nheko.reparent(rawMessageRoot)
 
     Shortcut {
         sequence: StandardKey.Cancel
diff --git a/resources/qml/dialogs/ReadReceipts.qml b/resources/qml/dialogs/ReadReceipts.qml
index aced4374b..da87996e0 100644
--- a/resources/qml/dialogs/ReadReceipts.qml
+++ b/resources/qml/dialogs/ReadReceipts.qml
@@ -22,7 +22,6 @@ ApplicationWindow {
     palette: Nheko.colors
     color: Nheko.colors.window
     flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
-    Component.onCompleted: Nheko.reparent(readReceiptsRoot)
 
     Shortcut {
         sequence: StandardKey.Cancel
diff --git a/resources/qml/dialogs/RoomDirectory.qml b/resources/qml/dialogs/RoomDirectory.qml
index f458ac51c..99da63bb7 100644
--- a/resources/qml/dialogs/RoomDirectory.qml
+++ b/resources/qml/dialogs/RoomDirectory.qml
@@ -22,7 +22,6 @@ ApplicationWindow {
     color: Nheko.colors.window
     modality: Qt.WindowModal
     flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
-    Component.onCompleted: Nheko.reparent(roomDirectoryWindow)
     title: qsTr("Explore Public Rooms")
 
     Shortcut {
diff --git a/resources/qml/dialogs/RoomMembers.qml b/resources/qml/dialogs/RoomMembers.qml
index 89cce4148..55d5488bc 100644
--- a/resources/qml/dialogs/RoomMembers.qml
+++ b/resources/qml/dialogs/RoomMembers.qml
@@ -24,7 +24,6 @@ ApplicationWindow {
     palette: Nheko.colors
     color: Nheko.colors.window
     flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
-    Component.onCompleted: Nheko.reparent(roomMembersRoot)
 
     Shortcut {
         sequence: StandardKey.Cancel
diff --git a/resources/qml/dialogs/RoomSettings.qml b/resources/qml/dialogs/RoomSettings.qml
index c9f2b1a13..48d2e2b72 100644
--- a/resources/qml/dialogs/RoomSettings.qml
+++ b/resources/qml/dialogs/RoomSettings.qml
@@ -23,7 +23,6 @@ ApplicationWindow {
     color: Nheko.colors.window
     modality: Qt.NonModal
     flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
-    Component.onCompleted: Nheko.reparent(roomSettingsDialog)
     title: qsTr("Room Settings")
 
     Shortcut {
diff --git a/resources/qml/dialogs/UserProfile.qml b/resources/qml/dialogs/UserProfile.qml
index 29ce2c3fe..73c4e68bf 100644
--- a/resources/qml/dialogs/UserProfile.qml
+++ b/resources/qml/dialogs/UserProfile.qml
@@ -13,9 +13,6 @@ import QtQuick.Window 2.13
 import im.nheko 1.0
 
 ApplicationWindow {
-    // this does not work in ApplicationWindow, just in Window
-    //transientParent: Nheko.mainwindow()
-
     id: userProfileDialog
 
     property var profile
@@ -29,7 +26,6 @@ ApplicationWindow {
     title: profile.isGlobalUserProfile ? qsTr("Global User Profile") : qsTr("Room User Profile")
     modality: Qt.NonModal
     flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
-    Component.onCompleted: Nheko.reparent(userProfileDialog)
 
     Shortcut {
         sequence: StandardKey.Cancel
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index fc90e6c71..f30e0466c 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -175,8 +175,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QObject *parent)
             &ChatPage::initializeEmptyViews,
             view_manager_,
             &TimelineViewManager::initializeRoomlist);
-    connect(
-      this, &ChatPage::chatFocusChanged, view_manager_, &TimelineViewManager::chatFocusChanged);
     connect(this, &ChatPage::syncUI, this, [this](const mtx::responses::Sync &sync) {
         view_manager_->sync(sync);
 
diff --git a/src/ChatPage.h b/src/ChatPage.h
index 5e3b509df..4b7351a5e 100644
--- a/src/ChatPage.h
+++ b/src/ChatPage.h
@@ -143,7 +143,6 @@ signals:
     void retrievedPresence(const QString &statusMsg, mtx::presence::PresenceState state);
     void themeChanged();
     void decryptSidebarChanged();
-    void chatFocusChanged(const bool focused);
 
     //! Signals for device verificaiton
     void receivedDeviceVerificationAccept(const mtx::events::msg::KeyVerificationAccept &message);
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index 5e7fe6ce9..03a99b0f1 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -130,8 +130,6 @@ MainWindow::MainWindow(QWindow *parent)
 
     connect(chat_page_, SIGNAL(contentLoaded()), this, SLOT(removeOverlayProgressBar()));
 
-    connect(this, &MainWindow::focusChanged, chat_page_, &ChatPage::chatFocusChanged);
-
     // connect(login_page_, &LoginPage::loginOk, this, [this](const mtx::responses::Login &res) {
     //     http::client()->set_user(res.user_id);
     //     showChatPage();
@@ -342,10 +340,6 @@ MainWindow::event(QEvent *event)
 
     if (type == QEvent::Close) {
         closeEvent(static_cast<QCloseEvent *>(event));
-    } else if (type == QEvent::WindowActivate) {
-        emit focusChanged(true);
-    } else if (type == QEvent::WindowDeactivate) {
-        emit focusChanged(false);
     }
 
     return QQuickView::event(event);
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 04311e12b..ea919f4d0 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -91,7 +91,6 @@ private slots:
     virtual void setWindowTitle(int notificationCount);
 
 signals:
-    void focusChanged(const bool focused);
     void reload();
     void secretsChanged();
 
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index e769fa40a..6b380f79a 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -1031,7 +1031,7 @@ TimelineModel::setCurrentIndex(int index)
     if (index != oldIndex)
         emit currentIndexChanged(index);
 
-    if (!MainWindow::instance()->isActive())
+    if (MainWindow::instance() != QGuiApplication::focusWindow())
         return;
 
     if (!currentId.startsWith('m')) {
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 5d2a44439..0abd102be 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -5,6 +5,7 @@
 
 #include "TimelineViewManager.h"
 
+#include <QApplication>
 #include <QDropEvent>
 #include <QFileDialog>
 #include <QMetaType>
@@ -157,6 +158,16 @@ TimelineViewManager::TimelineViewManager(CallManager *, ChatPage *parent)
         isInitialSync_ = true;
         emit initialSyncChanged(true);
     });
+    connect(qobject_cast<QApplication *>(QApplication::instance()),
+            &QApplication::focusWindowChanged,
+            this,
+            &TimelineViewManager::focusChanged);
+}
+
+bool
+TimelineViewManager::isWindowFocused() const
+{
+    return MainWindow::instance() == QApplication::focusWindow();
 }
 
 void
diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 424d78d6e..9419f2241 100644
--- a/src/timeline/TimelineViewManager.h
+++ b/src/timeline/TimelineViewManager.h
@@ -41,8 +41,7 @@ class TimelineViewManager : public QObject
 
     Q_PROPERTY(
       bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged)
-    Q_PROPERTY(
-      bool isWindowFocused MEMBER isWindowFocused_ READ isWindowFocused NOTIFY focusChanged)
+    Q_PROPERTY(bool isWindowFocused READ isWindowFocused NOTIFY focusChanged)
 
 public:
     TimelineViewManager(CallManager *callManager, ChatPage *parent = nullptr);
@@ -54,7 +53,7 @@ public:
     void clearAll() { rooms_->clear(); }
 
     Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; }
-    bool isWindowFocused() const { return isWindowFocused_; }
+    bool isWindowFocused() const;
     Q_INVOKABLE void openImageOverlay(TimelineModel *room, QString mxcUrl, QString eventId);
     Q_INVOKABLE void openImagePackSettings(QString roomid);
     Q_INVOKABLE void saveMedia(QString mxcUrl);
@@ -93,11 +92,6 @@ public slots:
     void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
     void receivedSessionKey(const std::string &room_id, const std::string &session_id);
     void initializeRoomlist();
-    void chatFocusChanged(bool focused)
-    {
-        isWindowFocused_ = focused;
-        emit focusChanged();
-    }
 
     void showEvent(const QString &room_id, const QString &event_id);
 
@@ -117,7 +111,6 @@ public slots:
 
 private:
     bool isInitialSync_   = true;
-    bool isWindowFocused_ = false;
 
     RoomlistModel *rooms_          = nullptr;
     CommunitiesModel *communities_ = nullptr;
-- 
GitLab