Skip to content

Commit ab959a5

Browse files
committed
InputManager: Always call SetHook()/RemoveHook() on core thread
1 parent bcd7a43 commit ab959a5

File tree

5 files changed

+40
-11
lines changed

5 files changed

+40
-11
lines changed

src/core/fullscreenui_settings.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ void FullscreenUI::InputBindingDialog::Start(SettingsInterface* bsi, InputBindin
424424

425425
const bool game_settings = IsEditingGameSettings(bsi);
426426

427-
InputManager::SetHook([this, game_settings](InputBindingKey key, float value) -> InputInterceptHook::CallbackResult {
427+
auto input_hook = [this, game_settings](InputBindingKey key, float value) -> InputInterceptHook::CallbackResult {
428428
// holding the settings lock here will protect the input binding list
429429
const auto lock = Core::GetSettingsLock();
430430

@@ -501,15 +501,18 @@ void FullscreenUI::InputBindingDialog::Start(SettingsInterface* bsi, InputBindin
501501
}
502502

503503
return default_action;
504-
});
504+
};
505+
506+
Host::RunOnCoreThread(
507+
[input_hook = std::move(input_hook)]() mutable { InputManager::SetHook(std::move(input_hook)); });
505508
}
506509

507510
void FullscreenUI::InputBindingDialog::ClearState()
508511
{
509512
PopupDialog::ClearState();
510513

511514
if (m_binding_type != InputBindingInfo::Type::Unknown)
512-
InputManager::RemoveHook();
515+
Host::RunOnCoreThread(&InputManager::RemoveHook);
513516

514517
m_binding_type = InputBindingInfo::Type::Unknown;
515518
m_binding_section = {};

src/duckstation-qt/inputbindingdialog.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "core/core.h"
1111

12+
#include "common/assert.h"
1213
#include "common/bitutils.h"
1314

1415
#include "fmt/format.h"
@@ -20,6 +21,8 @@
2021

2122
#include "moc_inputbindingdialog.cpp"
2223

24+
InputBindingDialog* InputBindingDialog::s_current_hook_dialog = nullptr;
25+
2326
InputBindingDialog::InputBindingDialog(SettingsInterface* sif, InputBindingInfo::Type bind_type,
2427
std::string section_name, std::string key_name,
2528
std::vector<std::string> bindings, QWidget* parent)
@@ -403,13 +406,21 @@ void InputBindingDialog::onResetSensitivityClicked()
403406

404407
void InputBindingDialog::hookInputManager()
405408
{
406-
InputManager::SetHook([this](InputBindingKey key, float value) {
407-
QMetaObject::invokeMethod(this, &InputBindingDialog::inputManagerHookCallback, Qt::QueuedConnection, key, value);
408-
return InputInterceptHook::CallbackResult::StopProcessingEvent;
409+
DebugAssert(!s_current_hook_dialog);
410+
s_current_hook_dialog = this;
411+
Host::RunOnCoreThread([]() {
412+
InputManager::SetHook([](InputBindingKey key, float value) {
413+
Host::RunOnUIThread([key, value]() {
414+
if (s_current_hook_dialog)
415+
s_current_hook_dialog->inputManagerHookCallback(key, value);
416+
});
417+
return InputInterceptHook::CallbackResult::StopProcessingEvent;
418+
});
409419
});
410420
}
411421

412422
void InputBindingDialog::unhookInputManager()
413423
{
414-
InputManager::RemoveHook();
424+
s_current_hook_dialog = nullptr;
425+
Host::RunOnCoreThread(&InputManager::RemoveHook);
415426
}

src/duckstation-qt/inputbindingdialog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,6 @@ class InputBindingDialog : public QDialog
7171
QPoint m_input_listen_start_position{};
7272
bool m_mouse_mapping_enabled = false;
7373
bool m_sensor_mapping_enabled = false;
74+
75+
static InputBindingDialog* s_current_hook_dialog;
7476
};

src/duckstation-qt/inputbindingwidgets.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "core/core.h"
1111
#include "core/host.h"
1212

13+
#include "common/assert.h"
1314
#include "common/bitutils.h"
1415
#include "common/log.h"
1516
#include "common/string_util.h"
@@ -26,6 +27,8 @@
2627

2728
LOG_CHANNEL(Host);
2829

30+
InputBindingWidget* InputBindingWidget::s_current_hook_widget = nullptr;
31+
2932
InputBindingWidget::InputBindingWidget(QWidget* parent) : QPushButton(parent)
3033
{
3134
connect(this, &QPushButton::clicked, this, &InputBindingWidget::onClicked);
@@ -442,15 +445,23 @@ void InputBindingWidget::inputManagerHookCallback(InputBindingKey key, float val
442445

443446
void InputBindingWidget::hookInputManager()
444447
{
445-
InputManager::SetHook([this](InputBindingKey key, float value) {
446-
QMetaObject::invokeMethod(this, &InputBindingWidget::inputManagerHookCallback, Qt::QueuedConnection, key, value);
447-
return InputInterceptHook::CallbackResult::StopProcessingEvent;
448+
DebugAssert(!s_current_hook_widget);
449+
s_current_hook_widget = this;
450+
Host::RunOnCoreThread([]() {
451+
InputManager::SetHook([](InputBindingKey key, float value) {
452+
Host::RunOnUIThread([key, value]() {
453+
if (s_current_hook_widget)
454+
s_current_hook_widget->inputManagerHookCallback(key, value);
455+
});
456+
return InputInterceptHook::CallbackResult::StopProcessingEvent;
457+
});
448458
});
449459
}
450460

451461
void InputBindingWidget::unhookInputManager()
452462
{
453-
InputManager::RemoveHook();
463+
s_current_hook_widget = nullptr;
464+
Host::RunOnCoreThread(&InputManager::RemoveHook);
454465
}
455466

456467
void InputBindingWidget::openDialog()

src/duckstation-qt/inputbindingwidgets.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,6 @@ class InputBindingWidget : public QPushButton
7777
QPoint m_input_listen_start_position{};
7878
bool m_mouse_mapping_enabled = false;
7979
bool m_sensor_mapping_enabled = false;
80+
81+
static InputBindingWidget* s_current_hook_widget;
8082
};

0 commit comments

Comments
 (0)