TAS Input: Enable hotkeys and controller input when Input has focus

Enable emulator hotkeys and controller input (when that option is
enabled) when a TAS Input window has focus, as if it was the render
window instead.  This allows TASers to use frame advance and the like
without having to switch the focused window or disabling Hotkeys Require
Window Focus which also picks up keypresses while other apps are active.

Cursor updates are disabled when the TAS Input window has focus, as
otherwise the Wii IR widget (and anything else controlled by the mouse)
becomes unusable. The cursor continues to work normally when the render
window has focus.
This commit is contained in:
Dentomologist
2024-05-26 16:50:12 -07:00
parent 8ac22378a1
commit c3bdd05d2a
14 changed files with 92 additions and 7 deletions

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;