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 +#include #include #include #include @@ -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 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