From 385b7cad77c3546082087c3993a3944c2050dd15 Mon Sep 17 00:00:00 2001 From: rayman30 Date: Fri, 30 Jan 2026 18:06:57 +0100 Subject: [PATCH] [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 Reviewed-by: crueter Co-authored-by: rayman30 Co-committed-by: rayman30 --- src/yuzu/game_list.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 0c59f4cc5e..c67d949114 100644 --- a/src/yuzu/game_list.cpp +++ b/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 #include "yuzu/game_list.h" @@ -492,10 +492,24 @@ void GameList::DonePopulating(const QStringList& watch_list) { constexpr int LIMIT_WATCH_DIRECTORIES = 5000; constexpr int SLICE_SIZE = 25; int len = (std::min)(static_cast(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) { - 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(); } + +#ifdef __APPLE__ + watcher->blockSignals(old_signals_blocked); +#endif tree_view->setEnabled(true); int children_total = 0; for (int i = 1; i < item_model->rowCount() - 1; ++i) {