UI/GTK: Avoid nested event loop when waiting for clipboard text

We no longer support more than one event loop per thread as of 02b2053
so this was causing a crash when pasting. We now spin the main event
loop until a "done" flag is set.

Fixes #9928
This commit is contained in:
Callum Law 2026-06-07 02:10:38 +12:00 committed by Andreas Kling
parent 7c06c3fd14
commit 728e6b010a

View file

@ -232,23 +232,26 @@ void Application::display_error_dialog(StringView error_message) const
Dialogs::show_error(m_active_window->gtk_window(), error_message);
}
// GDK4 only provides an async clipboard API. Spin a nested event loop to read synchronously.
// GDK4 only provides an async clipboard API. Spin the event loop until we get a response.
static Optional<ByteString> read_clipboard_text_sync()
{
auto* clipboard = gdk_display_get_clipboard(gdk_display_get_default());
Optional<ByteString> result;
Core::EventLoop nested_loop;
struct ClipboardReadTextResult {
bool done { false };
Optional<ByteString> text;
} result;
gdk_clipboard_read_text_async(clipboard, nullptr, [](GObject* source, GAsyncResult* async_result, gpointer user_data) {
auto* result_ptr = static_cast<Optional<ByteString>*>(user_data);
auto* result_ptr = static_cast<ClipboardReadTextResult*>(user_data);
g_autofree char* text = gdk_clipboard_read_text_finish(GDK_CLIPBOARD(source), async_result, nullptr);
if (text)
*result_ptr = ByteString(text);
Core::EventLoop::current().quit(0); }, &result);
result_ptr->text = ByteString(text);
nested_loop.exec();
return result;
result_ptr->done = true; }, &result);
Core::EventLoop::current().spin_until([&] { return result.done; });
return result.text;
}
Utf16String Application::clipboard_text(ClipboardType) const