diff options
| author | QuantumDriftDev <350698041+QuantumDriftDev@users.noreply.github.com> | 2026-10-31 14:33:08 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-10-31 14:33:08 +0100 |
| commit | d4e2dc88611252748b8dc3bb70baf56fc8bd2256 (patch) | |
| tree | 88cf5a92002f58efee5de70df65fe40519a45b01 | |
| parent | 7b6f27b91e0ecaebcc4d66ee7dd3855bebce6c78 (diff) | |
Fix game list crash, unresponsive macOS menu, and missing SDL gamepad input (#100)
* game_list: fix crash when scanning games by removing nested event processing
Assisted-by: DeepSeek V4 Pro (root cause diagnosis and fix)
Signed-off-by: QuantumDriftDev <350698041+QuantumDriftDev@users.noreply.github.com>
* macos: fix unresponsive application menu by removing the SDL/Qt event loop conflict
Assisted-by: GPT-6.1 Sol (root cause diagnosis and implementation)
Signed-off-by: QuantumDriftDev <350698041+QuantumDriftDev@users.noreply.github.com>
* input_common: handle SDL gamepad button and axis events
Assisted-by: DeepSeek V4 Pro (implementation)
Signed-off-by: QuantumDriftDev <350698041+QuantumDriftDev@users.noreply.github.com>
---------
Signed-off-by: QuantumDriftDev <350698041+QuantumDriftDev@users.noreply.github.com>
| -rw-r--r-- | src/input_common/drivers/sdl_driver.cpp | 16 | ||||
| -rw-r--r-- | src/yuzu/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/yuzu/game/game_list.cpp | 1 | ||||
| -rw-r--r-- | src/yuzu/main_window.cpp | 20 | ||||
| -rw-r--r-- | src/yuzu/main_window.h | 3 | ||||
| -rw-r--r-- | src/yuzu/util/macos_sleep.cpp | 25 | ||||
| -rw-r--r-- | src/yuzu/util/macos_sleep.h | 12 |
7 files changed, 77 insertions, 2 deletions
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index c3e9a066b3..1f1f9543f4 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -589,6 +589,15 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { } break; } + case SDL_EVENT_GAMEPAD_BUTTON_DOWN: + case SDL_EVENT_GAMEPAD_BUTTON_UP: { + const bool down = event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN; + if (const auto joystick = GetSDLJoystickBySDLID(event.gbutton.which)) { + const PadIdentifier identifier = joystick->GetPadIdentifier(); + SetButton(identifier, event.gbutton.button, down); + } + break; + } case SDL_EVENT_JOYSTICK_HAT_MOTION: { if (const auto joystick = GetSDLJoystickBySDLID(event.jhat.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); @@ -603,6 +612,13 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { } break; } + case SDL_EVENT_GAMEPAD_AXIS_MOTION: { + if (const auto joystick = GetSDLJoystickBySDLID(event.gaxis.which)) { + const PadIdentifier identifier = joystick->GetPadIdentifier(); + SetAxis(identifier, event.gaxis.axis, event.gaxis.value / 32767.0f); + } + break; + } case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: { auto joystick = GetSDLJoystickByGamepadID(event.gsensor.which); if (!joystick) { diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index e6906a4ef0..40ff1d45f9 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -358,6 +358,8 @@ target_sources(yuzu # TODO(crueter): Move Assets.car/icon/icns handling to its own Module. if (APPLE) + target_sources(yuzu PRIVATE util/macos_sleep.cpp util/macos_sleep.h) + # Xcode will automatically generate the Assets.car and icns file for us. set(_dist "${CMAKE_SOURCE_DIR}/dist") if (CMAKE_GENERATOR MATCHES "Xcode") diff --git a/src/yuzu/game/game_list.cpp b/src/yuzu/game/game_list.cpp index 6b89e59253..cd7fc19de4 100644 --- a/src/yuzu/game/game_list.cpp +++ b/src/yuzu/game/game_list.cpp @@ -295,7 +295,6 @@ void GameList::OnPopulatingCompleted(const QStringList& watch_list) { if (!chunk.isEmpty()) { callback(chunk); } - QCoreApplication::processEvents(); } }; diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index 13359620dd..b0c0446add 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -85,6 +85,10 @@ #include <QStatusBar> #include <QtConcurrentRun> +#ifdef __APPLE__ +#include "util/macos_sleep.h" +#endif + // Qt Common // #include "qt_common/config/shared_translation.h" #include "qt_common/config/uisettings.h" @@ -493,7 +497,8 @@ MainWindow::MainWindow(bool has_broken_vulkan) VkDeviceInfo::PopulateRecords(vk_device_records, this->window()->windowHandle()); } -#if !defined(_WIN32) + // On macOS, SDL video would pump AppKit events alongside Qt and disrupt native menus. +#if !defined(_WIN32) && !defined(__APPLE__) SDL_InitSubSystem(SDL_INIT_VIDEO); // Set a screensaver inhibition reason string. Currently passed to DBus by SDL and visible to @@ -549,6 +554,10 @@ MainWindow::MainWindow(bool has_broken_vulkan) } MainWindow::~MainWindow() { +#ifdef __APPLE__ + AllowOSSleep(); +#endif + // will get automatically deleted otherwise if (render_window->parent() == nullptr) { delete render_window; @@ -1758,6 +1767,10 @@ void MainWindow::OnSigInterruptNotifierActivated() { void MainWindow::PreventOSSleep() { #ifdef _WIN32 SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); +#elif defined(__APPLE__) + if (sleep_assertion_id == 0) { + sleep_assertion_id = MacOS::PreventSleep(); + } #else SDL_DisableScreenSaver(); #endif @@ -1766,6 +1779,11 @@ void MainWindow::PreventOSSleep() { void MainWindow::AllowOSSleep() { #ifdef _WIN32 SetThreadExecutionState(ES_CONTINUOUS); +#elif defined(__APPLE__) + if (sleep_assertion_id != 0) { + MacOS::AllowSleep(sleep_assertion_id); + sleep_assertion_id = 0; + } #else SDL_EnableScreenSaver(); #endif diff --git a/src/yuzu/main_window.h b/src/yuzu/main_window.h index 8aedeec721..57f585fef9 100644 --- a/src/yuzu/main_window.h +++ b/src/yuzu/main_window.h @@ -546,6 +546,9 @@ private: bool auto_paused = false; bool auto_muted = false; +#ifdef __APPLE__ + u32 sleep_assertion_id = 0; +#endif QTimer mouse_hide_timer; QTimer update_input_timer; diff --git a/src/yuzu/util/macos_sleep.cpp b/src/yuzu/util/macos_sleep.cpp new file mode 100644 index 0000000000..7525c37dca --- /dev/null +++ b/src/yuzu/util/macos_sleep.cpp @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include <IOKit/pwr_mgt/IOPMLib.h> +#include "common/logging.h" +#include "yuzu/util/macos_sleep.h" + +namespace MacOS { + +u32 PreventSleep() { + IOPMAssertionID assertion_id = kIOPMNullAssertionID; + const auto result = + IOPMAssertionCreateWithName(kIOPMAssertionTypePreventUserIdleDisplaySleep, + kIOPMAssertionLevelOn, CFSTR("Running a game"), &assertion_id); + if (result != kIOReturnSuccess) { + LOG_WARNING(Frontend, "Failed to prevent display sleep: {}", result); + return kIOPMNullAssertionID; + } + return assertion_id; +} + +void AllowSleep(u32 assertion_id) { + IOPMAssertionRelease(assertion_id); +} + +} // namespace MacOS diff --git a/src/yuzu/util/macos_sleep.h b/src/yuzu/util/macos_sleep.h new file mode 100644 index 0000000000..600dd7c553 --- /dev/null +++ b/src/yuzu/util/macos_sleep.h @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "common/common_types.h" + +namespace MacOS { + +u32 PreventSleep(); +void AllowSleep(u32 assertion_id); + +} // namespace MacOS |
