summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorDentomologist <dentomologist@gmail.com>2025-05-15 02:37:01 -0700
committerDentomologist <dentomologist@gmail.com>2025-05-15 20:36:21 -0700
commitffd46cd10c686a16e398fcfed54f1cf49911e3f5 (patch)
treeccb5c299c65929b44ba1865eb0784091c1eba1e4 /Source
parentfc833f845c1d9f2ce158413ed2aed05b7e3e7ab2 (diff)
WiimoteControllersWidget: Fix UI hang on opening
Fix the UI hanging for several seconds when opening the Controllers window. Move the scan for Bluetooth adapters onto a separate thread so the Host thread doesn't have to wait for it. Only automatically scan for adapters once, when opening the Controllers window for the first time. Add a Refresh button to let the user refresh the adapter list afterward.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/DolphinQt/Config/ControllersWindow.cpp1
-rw-r--r--Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp70
-rw-r--r--Source/Core/DolphinQt/Config/WiimoteControllersWidget.h15
3 files changed, 75 insertions, 11 deletions
diff --git a/Source/Core/DolphinQt/Config/ControllersWindow.cpp b/Source/Core/DolphinQt/Config/ControllersWindow.cpp
index bb0e7a0489..2470910e8e 100644
--- a/Source/Core/DolphinQt/Config/ControllersWindow.cpp
+++ b/Source/Core/DolphinQt/Config/ControllersWindow.cpp
@@ -27,7 +27,6 @@ void ControllersWindow::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
m_wiimote_controllers->UpdateBluetoothAvailableStatus();
- m_wiimote_controllers->RefreshBluetoothAdapters();
}
void ControllersWindow::CreateMainLayout()
diff --git a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp
index 69de3837ad..960cfac080 100644
--- a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp
+++ b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp
@@ -19,6 +19,7 @@
#include <optional>
#include "Common/Config/Config.h"
+#include "Common/WorkQueueThread.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/WiimoteSettings.h"
@@ -35,6 +36,7 @@
#include "DolphinQt/Config/Mapping/MappingWindow.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
+#include "DolphinQt/QtUtils/QueueOnObject.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/SignalBlocking.h"
#include "DolphinQt/Settings.h"
@@ -51,6 +53,14 @@ WiimoteControllersWidget::WiimoteControllersWidget(QWidget* parent) : QWidget(pa
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
[this](Core::State state) { LoadSettings(state); });
LoadSettings(Core::GetState(Core::System::GetInstance()));
+
+ m_bluetooth_adapter_refresh_thread.Reset("Bluetooth Adapter Refresh Thread");
+ StartBluetoothAdapterRefresh();
+}
+
+WiimoteControllersWidget::~WiimoteControllersWidget()
+{
+ m_bluetooth_adapter_refresh_thread.WaitForCompletion();
}
void WiimoteControllersWidget::UpdateBluetoothAvailableStatus()
@@ -58,17 +68,46 @@ void WiimoteControllersWidget::UpdateBluetoothAvailableStatus()
m_bluetooth_unavailable->setHidden(WiimoteReal::IsScannerReady());
}
-void WiimoteControllersWidget::RefreshBluetoothAdapters()
+void WiimoteControllersWidget::StartBluetoothAdapterRefresh()
{
+ if (m_bluetooth_adapter_scan_in_progress)
+ return;
+
m_bluetooth_adapters->clear();
+ m_bluetooth_adapters->setDisabled(true);
+ m_bluetooth_adapters->addItem(tr("Scanning for adapters..."));
+
+ m_bluetooth_adapter_scan_in_progress = true;
+
+ const auto scan_func = [this]() {
+ INFO_LOG_FMT(COMMON, "Refreshing Bluetooth adapter list...");
+ auto device_list = IOS::HLE::BluetoothRealDevice::ListDevices();
+ INFO_LOG_FMT(COMMON, "{} Bluetooth adapters available.", device_list.size());
+ const auto refresh_complete_func = [this, devices = std::move(device_list)]() {
+ OnBluetoothAdapterRefreshComplete(devices);
+ };
+ QueueOnObject(this, refresh_complete_func);
+ };
+
+ m_bluetooth_adapter_refresh_thread.Push(scan_func);
+}
+void WiimoteControllersWidget::OnBluetoothAdapterRefreshComplete(
+ const std::vector<IOS::HLE::BluetoothRealDevice::BluetoothDeviceInfo>& devices)
+{
const int configured_vid = Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_VID);
const int configured_pid = Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_PID);
bool found_configured_device = configured_vid == -1 || configured_pid == -1;
+ m_bluetooth_adapters->clear();
+ m_bluetooth_adapter_scan_in_progress = false;
+
+ const auto state = Core::GetState(Core::System::GetInstance());
+ UpdateBluetoothAdapterWidgetsEnabled(state);
+
m_bluetooth_adapters->addItem(tr("Automatic"));
- for (auto& device : IOS::HLE::BluetoothRealDevice::ListDevices())
+ for (auto& device : devices)
{
std::string name = device.name.empty() ? tr("Unknown Device").toStdString() : device.name;
QString device_info =
@@ -149,8 +188,9 @@ void WiimoteControllersWidget::CreateLayout()
m_wiimote_box->setLayout(m_wiimote_layout);
m_wiimote_passthrough = new QRadioButton(tr("Passthrough a Bluetooth adapter"));
- m_bluetooth_adapters_label = new QLabel(tr("Bluetooth adapter"));
+ m_bluetooth_adapters_label = new QLabel(tr("Adapter"));
m_bluetooth_adapters = new QComboBox();
+ m_bluetooth_adapters_refresh = new NonDefaultQPushButton(tr("Refresh"));
m_wiimote_sync = new NonDefaultQPushButton(tr("Sync"));
m_wiimote_reset = new NonDefaultQPushButton(tr("Reset"));
m_wiimote_refresh = new NonDefaultQPushButton(tr("Refresh"));
@@ -172,7 +212,8 @@ void WiimoteControllersWidget::CreateLayout()
int adapter_row = m_wiimote_layout->rowCount();
m_wiimote_layout->addWidget(m_bluetooth_adapters_label, adapter_row, 1, 1, 1);
- m_wiimote_layout->addWidget(m_bluetooth_adapters, adapter_row, 2, 1, 2);
+ m_wiimote_layout->addWidget(m_bluetooth_adapters, adapter_row, 2, 1, 1);
+ m_wiimote_layout->addWidget(m_bluetooth_adapters_refresh, adapter_row, 3, 1, 1);
int sync_row = m_wiimote_layout->rowCount();
m_wiimote_layout->addWidget(m_wiimote_pt_labels[0], sync_row, 1, 1, 2);
@@ -242,6 +283,8 @@ void WiimoteControllersWidget::ConnectWidgets()
&WiimoteControllersWidget::SaveSettings);
connect(m_bluetooth_adapters, &QComboBox::activated, this,
&WiimoteControllersWidget::OnBluetoothPassthroughDeviceChanged);
+ connect(m_bluetooth_adapters_refresh, &QPushButton::clicked, this,
+ &WiimoteControllersWidget::StartBluetoothAdapterRefresh);
connect(m_wiimote_sync, &QPushButton::clicked, this,
&WiimoteControllersWidget::OnBluetoothPassthroughSyncPressed);
connect(m_wiimote_reset, &QPushButton::clicked, this,
@@ -339,6 +382,19 @@ void WiimoteControllersWidget::OnWiimoteConfigure(size_t index)
window->show();
}
+void WiimoteControllersWidget::UpdateBluetoothAdapterWidgetsEnabled(const Core::State state)
+{
+ const bool running = state != Core::State::Uninitialized;
+ const bool running_wii = running && Core::System::GetInstance().IsWii();
+ const bool enable_adapter_refresh = m_wiimote_passthrough->isChecked() && !running_wii;
+ const bool enable_adapter_selection =
+ enable_adapter_refresh && !m_bluetooth_adapter_scan_in_progress;
+
+ m_bluetooth_adapters_label->setEnabled(enable_adapter_selection);
+ m_bluetooth_adapters->setEnabled(enable_adapter_selection);
+ m_bluetooth_adapters_refresh->setEnabled(enable_adapter_refresh);
+}
+
void WiimoteControllersWidget::LoadSettings(Core::State state)
{
for (size_t i = 0; i < m_wiimote_groups.size(); i++)
@@ -369,15 +425,13 @@ void WiimoteControllersWidget::LoadSettings(Core::State state)
m_wiimote_passthrough->setEnabled(!running);
const bool running_gc = running && !Core::System::GetInstance().IsWii();
- const bool running_wii = running && Core::System::GetInstance().IsWii();
const bool enable_passthrough = m_wiimote_passthrough->isChecked() && !running_gc;
- const bool enable_adapter_selection = m_wiimote_passthrough->isChecked() && !running_wii;
const bool enable_emu_bt = !m_wiimote_passthrough->isChecked() && !running_gc;
const bool is_netplay = NetPlay::IsNetPlayRunning();
const bool running_netplay = running && is_netplay;
- m_bluetooth_adapters_label->setEnabled(enable_adapter_selection);
- m_bluetooth_adapters->setEnabled(enable_adapter_selection);
+ UpdateBluetoothAdapterWidgetsEnabled(state);
+
m_wiimote_sync->setEnabled(enable_passthrough);
m_wiimote_reset->setEnabled(enable_passthrough);
diff --git a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.h b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.h
index bb2f50caad..b174c1b786 100644
--- a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.h
+++ b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.h
@@ -3,9 +3,12 @@
#pragma once
+#include <array>
+
#include <QWidget>
-#include <array>
+#include "Common/WorkQueueThread.h"
+#include "Core/IOS/USB/Bluetooth/BTReal.h"
class QCheckBox;
class QComboBox;
@@ -26,17 +29,21 @@ class WiimoteControllersWidget final : public QWidget
Q_OBJECT
public:
explicit WiimoteControllersWidget(QWidget* parent);
+ ~WiimoteControllersWidget();
void UpdateBluetoothAvailableStatus();
- void RefreshBluetoothAdapters();
private:
void SaveSettings();
void OnBluetoothPassthroughDeviceChanged(int index);
void OnBluetoothPassthroughSyncPressed();
void OnBluetoothPassthroughResetPressed();
+ void OnBluetoothAdapterRefreshComplete(
+ const std::vector<IOS::HLE::BluetoothRealDevice::BluetoothDeviceInfo>& devices);
void OnWiimoteRefreshPressed();
void OnWiimoteConfigure(size_t index);
+ void StartBluetoothAdapterRefresh();
+ void UpdateBluetoothAdapterWidgetsEnabled(Core::State state);
void CreateLayout();
void ConnectWidgets();
@@ -50,10 +57,14 @@ private:
std::array<QHBoxLayout*, 4> m_wiimote_groups;
std::array<QLabel*, 2> m_wiimote_pt_labels;
+ Common::AsyncWorkThreadSP m_bluetooth_adapter_refresh_thread;
+ bool m_bluetooth_adapter_scan_in_progress = false;
+
QRadioButton* m_wiimote_emu;
QRadioButton* m_wiimote_passthrough;
QLabel* m_bluetooth_adapters_label;
QComboBox* m_bluetooth_adapters;
+ QPushButton* m_bluetooth_adapters_refresh;
QPushButton* m_wiimote_sync;
QPushButton* m_wiimote_reset;
QCheckBox* m_wiimote_continuous_scanning;