diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp
index d18157edb..2d5af1b0c 100644
--- a/src/citra_qt/game_list.cpp
+++ b/src/citra_qt/game_list.cpp
@@ -301,7 +301,7 @@ GameList::GameList(GMainWindow* parent) : QWidget{parent} {
     item_model->setHeaderData(COLUMN_REGION, Qt::Horizontal, tr("Region"));
     item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, tr("File type"));
     item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, tr("Size"));
-    item_model->setSortRole(GameListItemPath::TitleRole);
+    item_model->setSortRole(GameListItemPath::SortRole);
 
     connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::onUpdateThemedIcons);
     connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry);
@@ -426,6 +426,8 @@ void GameList::DonePopulating(QStringList watch_list) {
     if (children_total > 0) {
         search_field->setFocus();
     }
+    item_model->sort(tree_view->header()->sortIndicatorSection(),
+                     tree_view->header()->sortIndicatorOrder());
 
     emit PopulatingCompleted();
 }
@@ -675,8 +677,6 @@ void GameList::LoadInterfaceLayout() {
         // so make it as large as possible as default.
         header->resizeSection(COLUMN_NAME, header->width());
     }
-
-    item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
 }
 
 const QStringList GameList::supported_file_extensions = {
diff --git a/src/citra_qt/game_list_p.h b/src/citra_qt/game_list_p.h
index 7c55f2aec..f4656e5b5 100644
--- a/src/citra_qt/game_list_p.h
+++ b/src/citra_qt/game_list_p.h
@@ -146,11 +146,11 @@ static const std::unordered_map<UISettings::GameListIconSize, int> IconSizes{
  */
 class GameListItemPath : public GameListItem {
 public:
-    static const int TitleRole = SortRole;
-    static const int FullPathRole = SortRole + 1;
-    static const int ProgramIdRole = SortRole + 2;
-    static const int ExtdataIdRole = SortRole + 3;
-    static const int LongTitleRole = SortRole + 4;
+    static const int TitleRole = SortRole + 1;
+    static const int FullPathRole = SortRole + 2;
+    static const int ProgramIdRole = SortRole + 3;
+    static const int ExtdataIdRole = SortRole + 4;
+    static const int LongTitleRole = SortRole + 5;
 
     GameListItemPath() = default;
     GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id,
@@ -196,7 +196,7 @@ public:
     }
 
     QVariant data(int role) const override {
-        if (role == Qt::DisplayRole) {
+        if (role == Qt::DisplayRole || role == SortRole) {
             std::string path, filename, extension;
             Common::SplitPath(data(FullPathRole).toString().toStdString(), &path, &filename,
                               &extension);
@@ -212,6 +212,9 @@ public:
 
             const QString& row1 = display_texts.at(UISettings::values.game_list_row_1).simplified();
 
+            if (role == SortRole)
+                return row1.toLower();
+
             QString row2;
             auto row_2_id = UISettings::values.game_list_row_2;
             if (row_2_id != UISettings::GameListText::NoText) {
@@ -377,6 +380,13 @@ public:
         return static_cast<int>(dir_type);
     }
 
+    /**
+     * Override to prevent automatic sorting.
+     */
+    bool operator<(const QStandardItem& other) const override {
+        return false;
+    }
+
 private:
     GameListItemType dir_type;
 };
@@ -394,6 +404,10 @@ public:
     int type() const override {
         return static_cast<int>(GameListItemType::AddDir);
     }
+
+    bool operator<(const QStandardItem& other) const override {
+        return false;
+    }
 };
 
 class GameList;