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 afe535603dbc6872a2edb10cff8548628ab33b79..2d1dd49d26fcba725bd04d441fc52f5bbca3b25c 100644
--- a/src/timeline/RoomlistModel.cpp
+++ b/src/timeline/RoomlistModel.cpp
@@ -917,6 +917,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 c0a87aee5540f92809453576daf41b91f8281d4a..27c14bec28e06912f17a3e1e1063877bda240795 100644
--- a/src/timeline/RoomlistModel.h
+++ b/src/timeline/RoomlistModel.h
@@ -172,6 +172,7 @@ public slots:
         void setCurrentRoom(QString roomid) { roomlistmodel->setCurrentRoom(std::move(roomid)); }
         void resetCurrentRoom() { roomlistmodel->resetCurrentRoom(); }
 
+        void nextRoomWithActivity();
         void nextRoom();
         void previousRoom();