diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 9fcf1b33a3..cb1a252d3c 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -173,6 +173,11 @@ bool Host_RendererIsFullscreen() return false; } +bool Host_TASInputHasFocus() +{ + return false; +} + void Host_YieldToUI() { } diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index f28a41f836..dcc766febc 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -1067,7 +1067,8 @@ void UpdateInputGate(bool require_focus, bool require_full_focus) { // If the user accepts background input, controls should pass even if an on screen interface is on const bool focus_passes = - !require_focus || (Host_RendererHasFocus() && !Host_UIBlocksControllerState()); + !require_focus || + ((Host_RendererHasFocus() || Host_TASInputHasFocus()) && !Host_UIBlocksControllerState()); // Ignore full focus if we don't require basic focus const bool full_focus_passes = !require_focus || !require_full_focus || (focus_passes && Host_RendererHasFullFocus()); diff --git a/Source/Core/Core/Host.h b/Source/Core/Core/Host.h index 8d22e9d59a..66a5e2d78e 100644 --- a/Source/Core/Core/Host.h +++ b/Source/Core/Core/Host.h @@ -53,6 +53,7 @@ bool Host_UIBlocksControllerState(); bool Host_RendererHasFocus(); bool Host_RendererHasFullFocus(); bool Host_RendererIsFullscreen(); +bool Host_TASInputHasFocus(); void Host_Message(HostMessageID id); void Host_PPCSymbolsChanged(); diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index 6cbb2750d2..40145e6e4c 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -111,6 +111,11 @@ bool Host_RendererIsFullscreen() return s_platform->IsWindowFullscreen(); } +bool Host_TASInputHasFocus() +{ + return false; +} + void Host_YieldToUI() { } diff --git a/Source/Core/DolphinQt/Host.cpp b/Source/Core/DolphinQt/Host.cpp index fe339364ab..bb912a7ab2 100644 --- a/Source/Core/DolphinQt/Host.cpp +++ b/Source/Core/DolphinQt/Host.cpp @@ -162,6 +162,11 @@ bool Host::GetGBAFocus() #endif } +bool Host::GetTASInputFocus() const +{ + return m_tas_input_focus; +} + bool Host::GetRenderFullscreen() { return m_render_fullscreen; @@ -177,6 +182,11 @@ void Host::SetRenderFullscreen(bool fullscreen) } } +void Host::SetTASInputFocus(const bool focus) +{ + m_tas_input_focus = focus; +} + void Host::ResizeSurface(int new_width, int new_height) { if (g_presenter) @@ -228,6 +238,11 @@ bool Host_RendererIsFullscreen() return Host::GetInstance()->GetRenderFullscreen(); } +bool Host_TASInputHasFocus() +{ + return Host::GetInstance()->GetTASInputFocus(); +} + void Host_YieldToUI() { qApp->processEvents(QEventLoop::ExcludeUserInputEvents); diff --git a/Source/Core/DolphinQt/Host.h b/Source/Core/DolphinQt/Host.h index 645c4bd54d..b7f21190da 100644 --- a/Source/Core/DolphinQt/Host.h +++ b/Source/Core/DolphinQt/Host.h @@ -25,12 +25,14 @@ public: bool GetRenderFullFocus(); bool GetRenderFullscreen(); bool GetGBAFocus(); + bool GetTASInputFocus() const; void SetMainWindowHandle(void* handle); void SetRenderHandle(void* handle); void SetRenderFocus(bool focus); void SetRenderFullFocus(bool focus); void SetRenderFullscreen(bool fullscreen); + void SetTASInputFocus(bool focus); void ResizeSurface(int new_width, int new_height); signals: @@ -49,4 +51,5 @@ private: std::atomic m_render_focus{false}; std::atomic m_render_full_focus{false}; std::atomic m_render_fullscreen{false}; + std::atomic m_tas_input_focus{false}; }; diff --git a/Source/Core/DolphinQt/TAS/TASInputWindow.cpp b/Source/Core/DolphinQt/TAS/TASInputWindow.cpp index 604a564991..d3dc078375 100644 --- a/Source/Core/DolphinQt/TAS/TASInputWindow.cpp +++ b/Source/Core/DolphinQt/TAS/TASInputWindow.cpp @@ -6,7 +6,9 @@ #include #include +#include #include +#include #include #include #include @@ -17,6 +19,7 @@ #include "Common/CommonTypes.h" +#include "DolphinQt/Host.h" #include "DolphinQt/QtUtils/AspectRatioWidget.h" #include "DolphinQt/QtUtils/QueueOnObject.h" #include "DolphinQt/Resources.h" @@ -268,3 +271,16 @@ std::optional TASInputWindow::GetSpinBox(TASSpinBox* spin, int zer return (spin->GetValue() - zero) / scale; } + +void TASInputWindow::changeEvent(QEvent* const event) +{ + if (event->type() == QEvent::ActivationChange) + { + const bool active_window_is_tas_input = + qobject_cast(QApplication::activeWindow()) != nullptr; + + // Switching between TAS Input windows will call SetTASInputFocus(true) twice, but that's fine. + Host::GetInstance()->SetTASInputFocus(active_window_is_tas_input); + } + QDialog::changeEvent(event); +} diff --git a/Source/Core/DolphinQt/TAS/TASInputWindow.h b/Source/Core/DolphinQt/TAS/TASInputWindow.h index 34cc843633..924e53ac87 100644 --- a/Source/Core/DolphinQt/TAS/TASInputWindow.h +++ b/Source/Core/DolphinQt/TAS/TASInputWindow.h @@ -18,6 +18,7 @@ class QBoxLayout; class QCheckBox; class QDialog; +class QEvent; class QGroupBox; class QSpinBox; class QString; @@ -68,6 +69,8 @@ protected: QKeySequence shortcut_key_sequence, Qt::Orientation orientation, QWidget* shortcut_widget); + void changeEvent(QEvent* event) override; + QGroupBox* m_settings_box; QCheckBox* m_use_controller; QSpinBox* m_turbo_press_frames; diff --git a/Source/Core/DolphinTool/ToolHeadlessPlatform.cpp b/Source/Core/DolphinTool/ToolHeadlessPlatform.cpp index 8c1772406f..0b04cbfa19 100644 --- a/Source/Core/DolphinTool/ToolHeadlessPlatform.cpp +++ b/Source/Core/DolphinTool/ToolHeadlessPlatform.cpp @@ -84,6 +84,11 @@ bool Host_RendererIsFullscreen() return false; } +bool Host_TASInputHasFocus() +{ + return false; +} + void Host_YieldToUI() { } diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp index 3c6a82dcd8..8d7f7c7ada 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp @@ -179,7 +179,8 @@ void KeyboardMouse::UpdateCursorInput() const auto win_height = std::max(rect.bottom - rect.top, 1l); POINT point = {}; - if (g_controller_interface.IsMouseCenteringRequested() && Host_RendererHasFocus()) + if (g_controller_interface.IsMouseCenteringRequested() && + (Host_RendererHasFocus() || Host_TASInputHasFocus())) { point.x = win_width / 2; point.y = win_height / 2; @@ -189,6 +190,15 @@ void KeyboardMouse::UpdateCursorInput() SetCursorPos(screen_point.x, screen_point.y); g_controller_interface.SetMouseCenteringRequested(false); } + else if (Host_TASInputHasFocus()) + { + // When a TAS Input window has focus and "Enable Controller Input" is checked most types of + // input should be read normally as if the render window had focus instead. The cursor is an + // exception, as otherwise using the mouse to set any control in the TAS Input window will also + // update the Wii IR value (or any other input controlled by the cursor). + + return; + } else { GetCursorPos(&point); diff --git a/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm b/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm index 55f212900d..9a8ddfc6df 100644 --- a/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm +++ b/Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm @@ -244,7 +244,8 @@ Core::DeviceRemoval KeyboardAndMouse::UpdateInput() const double window_width = std::max(bounds.size.width, 1.0); const double window_height = std::max(bounds.size.height, 1.0); - if (g_controller_interface.IsMouseCenteringRequested() && Host_RendererHasFocus()) + if (g_controller_interface.IsMouseCenteringRequested() && + (Host_RendererHasFocus() || Host_TASInputHasFocus())) { m_cursor.x = 0; m_cursor.y = 0; @@ -258,8 +259,13 @@ Core::DeviceRemoval KeyboardAndMouse::UpdateInput() g_controller_interface.SetMouseCenteringRequested(false); } - else + else if (!Host_TASInputHasFocus()) { + // When a TAS Input window has focus and "Enable Controller Input" is checked most types of + // input should be read normally as if the render window had focus instead. The cursor is an + // exception, as otherwise using the mouse to set any control in the TAS Input window will also + // update the Wii IR value (or any other input controlled by the cursor). + NSPoint loc = [NSEvent mouseLocation]; const auto window_scale = g_controller_interface.GetWindowInputScale(); diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp index e4b717e3af..057d774c5b 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp @@ -391,9 +391,16 @@ Core::DeviceRemoval KeyboardMouse::UpdateInput() m_state.axis.z += delta_z; m_state.axis.z /= SCROLL_AXIS_DECAY; - const bool should_center_mouse = - g_controller_interface.IsMouseCenteringRequested() && Host_RendererHasFocus(); - if (update_mouse || should_center_mouse) + const bool should_center_mouse = g_controller_interface.IsMouseCenteringRequested() && + (Host_RendererHasFocus() || Host_TASInputHasFocus()); + + // When a TAS Input window has focus and "Enable Controller Input" is checked most types of + // input should be read normally as if the render window had focus instead. The cursor is an + // exception, as otherwise using the mouse to set any control in the TAS Input window will also + // update the Wii IR value (or any other input controlled by the cursor). + const bool should_update_mouse = update_mouse && !Host_TASInputHasFocus(); + + if (should_update_mouse || should_center_mouse) UpdateCursor(should_center_mouse); if (update_keyboard) diff --git a/Source/DSPTool/StubHost.cpp b/Source/DSPTool/StubHost.cpp index d32346a457..e270acb23a 100644 --- a/Source/DSPTool/StubHost.cpp +++ b/Source/DSPTool/StubHost.cpp @@ -59,6 +59,10 @@ bool Host_RendererIsFullscreen() { return false; } +bool Host_TASInputHasFocus() +{ + return false; +} void Host_YieldToUI() { } diff --git a/Source/UnitTests/StubHost.cpp b/Source/UnitTests/StubHost.cpp index 47200bd40c..dc7dfe2277 100644 --- a/Source/UnitTests/StubHost.cpp +++ b/Source/UnitTests/StubHost.cpp @@ -63,6 +63,10 @@ bool Host_RendererIsFullscreen() { return false; } +bool Host_TASInputHasFocus() +{ + return false; +} void Host_YieldToUI() { }