Merge pull request #12815 from Dentomologist/enable_hotkeys_and_controllers_for_focused_tas_input

TAS Input: Enable emulator hotkeys and controller input when TAS Input window has focus
This commit is contained in:
Admiral H. Curtiss 2024-06-15 15:25:40 +02:00 committed by GitHub
commit 3f0f5b3b4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 92 additions and 7 deletions

View File

@ -173,6 +173,11 @@ bool Host_RendererIsFullscreen()
return false;
}
bool Host_TASInputHasFocus()
{
return false;
}
void Host_YieldToUI()
{
}

View File

@ -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());

View File

@ -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();

View File

@ -111,6 +111,11 @@ bool Host_RendererIsFullscreen()
return s_platform->IsWindowFullscreen();
}
bool Host_TASInputHasFocus()
{
return false;
}
void Host_YieldToUI()
{
}

View File

@ -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);

View File

@ -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<bool> m_render_focus{false};
std::atomic<bool> m_render_full_focus{false};
std::atomic<bool> m_render_fullscreen{false};
std::atomic<bool> m_tas_input_focus{false};
};

View File

@ -6,7 +6,9 @@
#include <cmath>
#include <utility>
#include <QApplication>
#include <QCheckBox>
#include <QEvent>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
@ -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<ControlState> 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<TASInputWindow*>(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);
}

View File

@ -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;

View File

@ -84,6 +84,11 @@ bool Host_RendererIsFullscreen()
return false;
}
bool Host_TASInputHasFocus()
{
return false;
}
void Host_YieldToUI()
{
}

View File

@ -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);

View File

@ -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();

View File

@ -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)

View File

@ -59,6 +59,10 @@ bool Host_RendererIsFullscreen()
{
return false;
}
bool Host_TASInputHasFocus()
{
return false;
}
void Host_YieldToUI()
{
}

View File

@ -63,6 +63,10 @@ bool Host_RendererIsFullscreen()
{
return false;
}
bool Host_TASInputHasFocus()
{
return false;
}
void Host_YieldToUI()
{
}