Browse Source

[macos] Fix infinite refresh loop in Game List (#3418)

On macOS, adding paths to QFileSystemWatcher can trigger immediate 'directoryChanged' signals (likely due to FSEvent behavior or .DS_Store updates during directory access). This caused a recursive loop where PopulateAsync would trigger itself indefinitely, leading to constant UI refreshing and high CPU usage.

This fix addresses the issue by:
1. Temporarily blocking QFileSystemWatcher signals while the watch list is being populated.
2. Correcting the usage of QList::mid() in the loop (passing length instead of an end index) to avoid massive path duplication.

These changes are isolated to macOS using #ifdef __APPLE__ to ensure no side effects on other platforms.

Authored-by: rayman30

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3418
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: rayman30 <silentbitdev@gmail.com>
Co-committed-by: rayman30 <silentbitdev@gmail.com>
release/0.1.0 v0.1.1
rayman30 1 week ago
committed by crueter
parent
commit
385b7cad77
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 18
      src/yuzu/game_list.cpp

18
src/yuzu/game_list.cpp

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include "yuzu/game_list.h" #include "yuzu/game_list.h"
@ -492,10 +492,24 @@ void GameList::DonePopulating(const QStringList& watch_list) {
constexpr int LIMIT_WATCH_DIRECTORIES = 5000; constexpr int LIMIT_WATCH_DIRECTORIES = 5000;
constexpr int SLICE_SIZE = 25; constexpr int SLICE_SIZE = 25;
int len = (std::min)(static_cast<int>(watch_list.size()), LIMIT_WATCH_DIRECTORIES); int len = (std::min)(static_cast<int>(watch_list.size()), LIMIT_WATCH_DIRECTORIES);
// Block signals to prevent the watcher from triggering a refresh while we are adding paths.
// This fixes a refresh loop on macOS.
#ifdef __APPLE__
const bool old_signals_blocked = watcher->blockSignals(true);
#endif
for (int i = 0; i < len; i += SLICE_SIZE) { for (int i = 0; i < len; i += SLICE_SIZE) {
watcher->addPaths(watch_list.mid(i, i + SLICE_SIZE));
auto chunk = watch_list.mid(i, SLICE_SIZE);
if (!chunk.isEmpty()) {
watcher->addPaths(chunk);
}
QCoreApplication::processEvents(); QCoreApplication::processEvents();
} }
#ifdef __APPLE__
watcher->blockSignals(old_signals_blocked);
#endif
tree_view->setEnabled(true); tree_view->setEnabled(true);
int children_total = 0; int children_total = 0;
for (int i = 1; i < item_model->rowCount() - 1; ++i) { for (int i = 1; i < item_model->rowCount() - 1; ++i) {

Loading…
Cancel
Save