summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--resources/qml/RoomList.qml3
-rw-r--r--resources/qml/Root.qml2
-rw-r--r--src/ChatPage.cpp21
-rw-r--r--src/ChatPage.h8
-rw-r--r--src/MainWindow.cpp47
-rw-r--r--src/MainWindow.h18
-rw-r--r--src/timeline/InputBar.cpp12
-rw-r--r--src/timeline/TimelineModel.cpp6
-rw-r--r--src/ui/UserProfile.cpp4
9 files changed, 80 insertions, 41 deletions
diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml
index d33c562e..440a9cb9 100644
--- a/resources/qml/RoomList.qml
+++ b/resources/qml/RoomList.qml
@@ -73,7 +73,8 @@ Page {
                 property var room: null
                 property var roomPreview: null
 
-                onActiveChanged: if (active) {MainWindow.activeRoom = (room.roomId || roomPreview.roomid)}
+                Component.onCompleted: MainWindow.addPerRoomWindow(room.roomId || roomPreview.roomid, roomWindowW)
+                Component.onDestruction: MainWindow.removePerRoomWindow(room.roomId || roomPreview.roomid, roomWindowW)
 
                 height: 650
                 width: 420
diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml
index 92bff0e0..72f30b7a 100644
--- a/resources/qml/Root.qml
+++ b/resources/qml/Root.qml
@@ -25,8 +25,6 @@ Pane {
     background: null
     padding: 0
 
-    Window.onActiveChanged: if (Window.active) {MainWindow.activeRoom = Qt.binding(function() { return Rooms.currentRoom.roomId || Rooms.currentRoomPreview.roomid })}
-
     FontMetrics {
         id: fontMetrics
     }
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 4c64c25c..88226c33 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -811,10 +811,8 @@ ChatPage::changeRoom(const QString &room_id)
 }
 
 void
-ChatPage::inviteUser(QString userid, QString reason)
+ChatPage::inviteUser(const QString &room, QString userid, QString reason)
 {
-    auto room = MainWindow::instance()->activeRoom();
-
     if (QMessageBox::question(nullptr,
                               tr("Confirm invite"),
                               tr("Do you really want to invite %1 (%2)?")
@@ -837,10 +835,8 @@ ChatPage::inviteUser(QString userid, QString reason)
       reason.trimmed().toStdString());
 }
 void
-ChatPage::kickUser(QString userid, QString reason)
+ChatPage::kickUser(const QString &room, QString userid, QString reason)
 {
-    auto room = MainWindow::instance()->activeRoom();
-
     bool confirmed;
     reason =
       QInputDialog::getText(nullptr,
@@ -868,10 +864,8 @@ ChatPage::kickUser(QString userid, QString reason)
       reason.trimmed().toStdString());
 }
 void
-ChatPage::banUser(QString userid, QString reason)
+ChatPage::banUser(const QString &room, QString userid, QString reason)
 {
-    auto room = MainWindow::instance()->activeRoom();
-
     bool confirmed;
     reason =
       QInputDialog::getText(nullptr,
@@ -899,10 +893,8 @@ ChatPage::banUser(QString userid, QString reason)
       reason.trimmed().toStdString());
 }
 void
-ChatPage::unbanUser(QString userid, QString reason)
+ChatPage::unbanUser(const QString &room, QString userid, QString reason)
 {
-    auto room = MainWindow::instance()->activeRoom();
-
     if (QMessageBox::question(nullptr,
                               tr("Confirm unban"),
                               tr("Do you really want to unban %1 (%2)?")
@@ -1398,7 +1390,7 @@ ChatPage::handleMatrixUri(QString uri)
 
     if (sigil1 == u"u") {
         if (action.isEmpty()) {
-            auto t = MainWindow::instance()->activeRoom();
+            auto t = MainWindow::instance()->focusedRoom();
             if (!t.isEmpty() && cache::isRoomMember(mxid1.toStdString(), t.toStdString())) {
                 auto rm = view_manager_->rooms()->getRoomById(t);
                 if (rm)
@@ -1468,5 +1460,6 @@ ChatPage::handleMatrixUri(const QUrl &uri)
 bool
 ChatPage::isRoomActive(const QString &room_id)
 {
-    return QGuiApplication::focusWindow() && MainWindow::instance()->activeRoom() == room_id;
+    return QGuiApplication::focusWindow() && QGuiApplication::focusWindow()->isActive() &&
+           MainWindow::instance()->windowForRoom(room_id) == QGuiApplication::focusWindow();
 }
diff --git a/src/ChatPage.h b/src/ChatPage.h
index fa920907..165f7068 100644
--- a/src/ChatPage.h
+++ b/src/ChatPage.h
@@ -92,10 +92,10 @@ public slots:
                      bool promptForConfirmation = true,
                      const QString &reason      = "");
 
-    void inviteUser(QString userid, QString reason);
-    void kickUser(QString userid, QString reason);
-    void banUser(QString userid, QString reason);
-    void unbanUser(QString userid, QString reason);
+    void inviteUser(const QString &room, QString userid, QString reason);
+    void kickUser(const QString &room, QString userid, QString reason);
+    void banUser(const QString &room, QString userid, QString reason);
+    void unbanUser(const QString &room, QString userid, QString reason);
 
     void receivedSessionKey(const std::string &room_id, const std::string &session_id);
     void decryptDownloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescription keyDesc,
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index ffc3c6c1..7f62b23b 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -434,3 +434,50 @@ MainWindow::showDialog(QWidget *dialog)
     utils::centerWidget(dialog, this);
     dialog->window()->windowHandle()->setTransientParent(this);
 }
+
+void
+MainWindow::addPerRoomWindow(const QString &room, QWindow *window)
+{
+    roomWindows_.insert(room, window);
+}
+void
+MainWindow::removePerRoomWindow(const QString &room, QWindow *window)
+{
+    roomWindows_.remove(room, window);
+}
+const QWindow *
+MainWindow::windowForRoom(const QString &room) const
+{
+    auto currMainWindowRoom = ChatPage::instance()->timelineManager()->rooms()->currentRoom();
+    if ((currMainWindowRoom && currMainWindowRoom->roomId() == room) ||
+        ChatPage::instance()->timelineManager()->rooms()->currentRoomPreview().roomid_ == room)
+        return this;
+    else if (auto res = roomWindows_.find(room); res != roomWindows_.end())
+        return res.value();
+    return nullptr;
+}
+
+QString
+MainWindow::focusedRoom() const
+{
+    auto focus = QGuiApplication::focusWindow();
+    if (!focus)
+        return {};
+
+    if (focus == this) {
+        auto currMainWindowRoom = ChatPage::instance()->timelineManager()->rooms()->currentRoom();
+        if (currMainWindowRoom)
+            return currMainWindowRoom->roomId();
+        else
+            return ChatPage::instance()->timelineManager()->rooms()->currentRoomPreview().roomid_;
+    }
+
+    auto i = roomWindows_.constBegin();
+    while (i != roomWindows_.constEnd()) {
+        if (i.value() == focus)
+            return i.key();
+        ++i;
+    }
+
+    return nullptr;
+}
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 523b253d..8c34b348 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -8,6 +8,7 @@
 
 #include <functional>
 
+#include <QHash>
 #include <QQuickView>
 #include <QSharedPointer>
 #include <QSystemTrayIcon>
@@ -40,7 +41,6 @@ class ReCaptcha;
 class MainWindow : public QQuickView
 {
     Q_OBJECT
-    Q_PROPERTY(QString activeRoom READ activeRoom WRITE updateActiveRoom NOTIFY activeRoomChanged)
 
 public:
     explicit MainWindow(QWindow *parent = nullptr);
@@ -59,14 +59,10 @@ public:
     bool dbusAvailable() const { return dbusAvailable_; }
 #endif
 
-    QString activeRoom() const { return activeRoom_; }
-    void updateActiveRoom(QString r)
-    {
-        if (activeRoom_ != r) {
-            activeRoom_ = std::move(r);
-            emit activeRoomChanged();
-        }
-    }
+    Q_INVOKABLE void addPerRoomWindow(const QString &room, QWindow *window);
+    Q_INVOKABLE void removePerRoomWindow(const QString &room, QWindow *window);
+    const QWindow *windowForRoom(const QString &room) const;
+    QString focusedRoom() const;
 
 protected:
     void closeEvent(QCloseEvent *event);
@@ -88,8 +84,6 @@ signals:
     void switchToWelcomePage();
     void switchToLoginPage(QString error);
 
-    void activeRoomChanged();
-
 private:
     void showDialog(QWidget *dialog);
     bool hasActiveUser();
@@ -113,7 +107,7 @@ private:
 
     MxcImageProvider *imgProvider = nullptr;
 
-    QString activeRoom_;
+    QMultiHash<QString, QWindow *> roomWindows_;
 
 #ifdef NHEKO_DBUS_SYS
     bool dbusAvailable_{false};
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
index 1de7a141..7ef61da4 100644
--- a/src/timeline/InputBar.cpp
+++ b/src/timeline/InputBar.cpp
@@ -675,13 +675,17 @@ InputBar::command(const QString &command, QString args)
     } else if (command == QLatin1String("part") || command == QLatin1String("leave")) {
         ChatPage::instance()->timelineManager()->openLeaveRoomDialog(room->roomId(), args);
     } else if (command == QLatin1String("invite")) {
-        ChatPage::instance()->inviteUser(args.section(' ', 0, 0), args.section(' ', 1, -1));
+        ChatPage::instance()->inviteUser(
+          room->roomId(), args.section(' ', 0, 0), args.section(' ', 1, -1));
     } else if (command == QLatin1String("kick")) {
-        ChatPage::instance()->kickUser(args.section(' ', 0, 0), args.section(' ', 1, -1));
+        ChatPage::instance()->kickUser(
+          room->roomId(), args.section(' ', 0, 0), args.section(' ', 1, -1));
     } else if (command == QLatin1String("ban")) {
-        ChatPage::instance()->banUser(args.section(' ', 0, 0), args.section(' ', 1, -1));
+        ChatPage::instance()->banUser(
+          room->roomId(), args.section(' ', 0, 0), args.section(' ', 1, -1));
     } else if (command == QLatin1String("unban")) {
-        ChatPage::instance()->unbanUser(args.section(' ', 0, 0), args.section(' ', 1, -1));
+        ChatPage::instance()->unbanUser(
+          room->roomId(), args.section(' ', 0, 0), args.section(' ', 1, -1));
     } else if (command == QLatin1String("roomnick")) {
         mtx::events::state::Member member;
         member.display_name = args.toStdString();
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index b9c2cefa..142ca793 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -1072,7 +1072,8 @@ TimelineModel::setCurrentIndex(int index)
     if (index != oldIndex)
         emit currentIndexChanged(index);
 
-    if (MainWindow::instance()->activeRoom() != roomId() && QGuiApplication::focusWindow())
+    if (!QGuiApplication::focusWindow() || !QGuiApplication::focusWindow()->isActive() ||
+        MainWindow::instance()->windowForRoom(roomId()) != QGuiApplication::focusWindow())
         return;
 
     if (!currentId.startsWith('m')) {
@@ -2338,7 +2339,8 @@ TimelineModel::acceptKnock(const QString &id)
     if (event->content.membership != Membership::Knock)
         return;
 
-    ChatPage::instance()->inviteUser(QString::fromStdString(event->state_key), QLatin1String(""));
+    ChatPage::instance()->inviteUser(
+      room_id_, QString::fromStdString(event->state_key), QLatin1String(""));
 }
 
 bool
diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp
index c60eca6f..e9d1bc18 100644
--- a/src/ui/UserProfile.cpp
+++ b/src/ui/UserProfile.cpp
@@ -297,7 +297,7 @@ UserProfile::updateVerificationStatus()
 void
 UserProfile::banUser()
 {
-    ChatPage::instance()->banUser(this->userid_, QLatin1String(""));
+    ChatPage::instance()->banUser(roomid_, this->userid_, QLatin1String(""));
 }
 
 // void ignoreUser(){
@@ -307,7 +307,7 @@ UserProfile::banUser()
 void
 UserProfile::kickUser()
 {
-    ChatPage::instance()->kickUser(this->userid_, QLatin1String(""));
+    ChatPage::instance()->kickUser(roomid_, this->userid_, QLatin1String(""));
 }
 
 void