mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-27 17:39:34 -06:00
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.
This commit is contained in:
@ -27,7 +27,6 @@ void ControllersWindow::showEvent(QShowEvent* event)
|
||||
{
|
||||
QDialog::showEvent(event);
|
||||
m_wiimote_controllers->UpdateBluetoothAvailableStatus();
|
||||
m_wiimote_controllers->RefreshBluetoothAdapters();
|
||||
}
|
||||
|
||||
void ControllersWindow::CreateMainLayout()
|
||||
|
@ -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()
|
||||
{
|
||||
m_bluetooth_adapters->clear();
|
||||
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);
|
||||
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user