UI: Fix drag & drop of files on main window

This commit is contained in:
Antonino Di Guardo 2026-06-13 03:13:16 +02:00 committed by GitHub
parent 2ce45bd904
commit 16a53dfec7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 7 deletions

View File

@ -1019,6 +1019,13 @@ void cell_audio_thread::operator()()
// Destroy ringbuffer
ringbuffer.reset();
// Destroy the audio backend on this thread (the one that created it in cfg.reset()).
// The backend's ctor calls CoInitializeEx here on Windows; releasing it on a different
// thread (g_fxo->clear() runs on the GUI thread during Kill()) would land the matching
// CoUninitialize on the GUI thread, draining its OLE reference and silently breaking the
// main window's file drag&drop. Keep COM init/teardown balanced on this thread.
cfg.backend.reset();
}
audio_port* cell_audio_thread::open_port()

View File

@ -1413,6 +1413,20 @@ void rsxaudio_backend_thread::operator()()
{
lock.unlock();
backend_stop();
// Destroy the backend on this thread, the one that created it in backend_init().
// The backend's ctor calls CoInitializeEx here on Windows; if it is instead released
// by ~rsxaudio_backend_thread() (which runs on the GUI thread via g_fxo->clear()
// during Kill()), the matching CoUninitialize lands on the GUI thread, draining its
// OLE reference and silently breaking the main window's file drag&drop. Keep COM
// init/teardown balanced on this thread.
if (backend)
{
backend->Close();
backend->SetWriteCallback(nullptr);
backend->SetStateCallback(nullptr);
backend = nullptr;
}
return;
}

View File

@ -66,15 +66,24 @@ void fmt_class_string<QMediaPlayer::PlaybackState>::format(std::string& out, u64
qt_music_handler::qt_music_handler()
{
music_log.notice("Constructing Qt music handler...");
// Construct the QMediaPlayer on the GUI thread, the same thread on which it is destroyed
// (see ~qt_music_handler). cellMusic creates this handler from an emulated thread, but Qt's
// Windows multimedia backend balances its COM init/teardown per calling thread: constructing
// off the GUI thread and destroying on it left an unmatched CoUninitialize on the GUI thread,
// draining the OLE reference that Qt's startup OleInitialize set up until file drag&drop on
// the main window silently broke. Keeping both on the GUI thread keeps them balanced.
Emu.BlockingCallFromMainThread([this]()
{
music_log.notice("Constructing Qt music handler...");
m_media_player = std::make_unique<QMediaPlayer>();
m_media_player->setAudioOutput(new QAudioOutput(m_media_player.get()));
m_media_player = std::make_unique<QMediaPlayer>();
m_media_player->setAudioOutput(new QAudioOutput(m_media_player.get()));
connect(m_media_player.get(), &QMediaPlayer::mediaStatusChanged, this, &qt_music_handler::handle_media_status);
connect(m_media_player.get(), &QMediaPlayer::playbackStateChanged, this, &qt_music_handler::handle_music_state);
connect(m_media_player.get(), &QMediaPlayer::errorOccurred, this, &qt_music_handler::handle_music_error);
connect(m_media_player->audioOutput(), &QAudioOutput::volumeChanged, this, &qt_music_handler::handle_volume_change);
connect(m_media_player.get(), &QMediaPlayer::mediaStatusChanged, this, &qt_music_handler::handle_media_status);
connect(m_media_player.get(), &QMediaPlayer::playbackStateChanged, this, &qt_music_handler::handle_music_state);
connect(m_media_player.get(), &QMediaPlayer::errorOccurred, this, &qt_music_handler::handle_music_error);
connect(m_media_player->audioOutput(), &QAudioOutput::volumeChanged, this, &qt_music_handler::handle_volume_change);
});
}
qt_music_handler::~qt_music_handler()