diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 6d7d2125c68..5334446b224 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1317,6 +1317,10 @@ void DisplayServerWayland::process_events() { DEBUG_LOG_WAYLAND("Unsuspending from timeout."); } } + + // Since we're not rendering, nothing is committing the windows' + // surfaces. We have to do it ourselves. + wayland_thread.commit_surfaces(); } #ifdef DBUS_ENABLED diff --git a/platform/linuxbsd/wayland/wayland_thread.cpp b/platform/linuxbsd/wayland/wayland_thread.cpp index d2a9fde3ee6..14ea203735f 100644 --- a/platform/linuxbsd/wayland/wayland_thread.cpp +++ b/platform/linuxbsd/wayland/wayland_thread.cpp @@ -4298,6 +4298,16 @@ bool WaylandThread::get_reset_frame() { // Dispatches events until a frame event is received, a window is reported as // suspended or the timeout expires. bool WaylandThread::wait_frame_suspend_ms(int p_timeout) { + // This is a bit of a chicken and egg thing... Looks like the main event loop + // has to call its rightfully forever-blocking poll right in between + // `wl_display_prepare_read` and `wl_display_read`. This means, that it will + // basically be guaranteed to stay stuck in a "prepare read" state, where it + // will block any other attempt at reading the display fd, such as ours. The + // solution? Let's make sure the mutex is locked (it should) and unblock the + // main thread with a roundtrip! + MutexLock mutex_lock(mutex); + wl_display_roundtrip(wl_display); + if (main_window.suspended) { // The window is suspended! The compositor is telling us _explicitly_ that we // don't need to draw, without letting us guess through the frame event's