diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml
index cc7d32ea47971374a56f67f0a5f7e1f5b86d4baf..4207f35b69f7d82a51a889cb1e6d50644ec241dc 100644
--- a/resources/qml/Root.qml
+++ b/resources/qml/Root.qml
@@ -120,6 +120,11 @@ Page {
         }
     }
 
+    Shortcut {
+        sequence: "Alt+A"
+        onActivated: Rooms.nextRoomWithActivity()
+    }
+
     Shortcut {
         sequence: "Ctrl+Down"
         onActivated: Rooms.nextRoom()
diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp
index 942a4b05c61fa3aa6002fe4df436d5af8daa925c..0f44ec6c8d694bb939d507f28e38ab554bf5a7d9 100644
--- a/src/timeline/RoomlistModel.cpp
+++ b/src/timeline/RoomlistModel.cpp
@@ -899,6 +899,52 @@ FilteredRoomlistModel::toggleTag(QString roomid, QString tag, bool on)
         }
 }
 
+void
+FilteredRoomlistModel::nextRoomWithActivity()
+{
+        int roomWithMention       = -1;
+        int roomWithNotification  = -1;
+        int roomWithUnreadMessage = -1;
+        auto r                    = currentRoom();
+        int currentRoomIdx        = r ? roomidToIndex(r->roomId()) : -1;
+        // first look for mentions
+        for (int i = 0; i < (int)roomlistmodel->roomids.size(); i++) {
+                if (i == currentRoomIdx)
+                        continue;
+                if (this->data(index(i, 0), RoomlistModel::HasLoudNotification).toBool()) {
+                        roomWithMention = i;
+                        break;
+                }
+                if (roomWithNotification == -1 &&
+                    this->data(index(i, 0), RoomlistModel::NotificationCount).toInt() > 0) {
+                        roomWithNotification = i;
+                        // don't break, we must continue looking for rooms with mentions
+                }
+                if (roomWithNotification == -1 && roomWithUnreadMessage == -1 &&
+                    this->data(index(i, 0), RoomlistModel::HasUnreadMessages).toBool()) {
+                        roomWithUnreadMessage = i;
+                        // don't break, we must continue looking for rooms with mentions
+                }
+        }
+        QString targetRoomId = nullptr;
+        if (roomWithMention != -1) {
+                targetRoomId =
+                  this->data(index(roomWithMention, 0), RoomlistModel::RoomId).toString();
+                nhlog::ui()->debug("choosing {} for mentions", targetRoomId.toStdString());
+        } else if (roomWithNotification != -1) {
+                targetRoomId =
+                  this->data(index(roomWithNotification, 0), RoomlistModel::RoomId).toString();
+                nhlog::ui()->debug("choosing {} for notifications", targetRoomId.toStdString());
+        } else if (roomWithUnreadMessage != -1) {
+                targetRoomId =
+                  this->data(index(roomWithUnreadMessage, 0), RoomlistModel::RoomId).toString();
+                nhlog::ui()->debug("choosing {} for unread messages", targetRoomId.toStdString());
+        }
+        if (targetRoomId != nullptr) {
+                setCurrentRoom(targetRoomId);
+        }
+}
+
 void
 FilteredRoomlistModel::nextRoom()
 {
diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h
index 6ac6da18694ace471402caf4f3976744580ef6e1..dbdd06c2b5a38fef0184fbf28bf5ef635fc0c9e0 100644
--- a/src/timeline/RoomlistModel.h
+++ b/src/timeline/RoomlistModel.h
@@ -170,6 +170,7 @@ public slots:
         void setCurrentRoom(QString roomid) { roomlistmodel->setCurrentRoom(std::move(roomid)); }
         void resetCurrentRoom() { roomlistmodel->resetCurrentRoom(); }
 
+        void nextRoomWithActivity();
         void nextRoom();
         void previousRoom();