From a25a6b8c53602d2023dd0ad685000dc006179e94 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Mon, 27 Apr 2026 20:12:42 +0000 Subject: [PATCH] [client,x11] fix deadlock on output expose Defer screen update from xf_event_Expose to after X11 lock is released, preventing a deadlock between X11 lock and railWindows lock. Backport of commit a278ff74117444c635c50ffa5084ecf517171f5a. Adjusted hunk offsets for 2.11.7. Made-with: Cursor --- client/X11/xf_client.c | 3 ++ client/X11/xf_event.c | 77 ++++++++++++++++++++++++++++-------------- client/X11/xf_event.h | 2 ++ client/X11/xfreerdp.h | 4 +++ 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index bd3eb0d..f14cb55 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -516,6 +516,9 @@ static BOOL xf_process_x_events(freerdp* instance) xf_unlock_x11(xfc); if (!status) break; + status = xf_event_update_screen(instance); + if (!status) + break; } return status; diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index e1421ad..524e5e3 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -324,45 +324,34 @@ void xf_event_adjust_coordinates(xfContext* xfc, int* x, int* y) } static BOOL xf_event_Expose(xfContext* xfc, const XExposeEvent* event, BOOL app) { - int x, y; - int w, h; + WINPR_ASSERT(xfc); + WINPR_ASSERT(event); + rdpSettings* settings = xfc->context.settings; + WINPR_ASSERT(settings); if (!app && (settings->SmartSizing || settings->MultiTouchGestures)) { - x = 0; - y = 0; - w = settings->DesktopWidth; - h = settings->DesktopHeight; + xfc->exposedArea.x = 0; + xfc->exposedArea.y = 0; + xfc->exposedArea.w = settings->DesktopWidth; + xfc->exposedArea.h = settings->DesktopHeight; } else { - x = event->x; - y = event->y; - w = event->width; - h = event->height; + xfc->exposedArea.x = event->x; + xfc->exposedArea.y = event->y; + xfc->exposedArea.w = event->width; + xfc->exposedArea.h = event->height; } - if (!app) - { - if (xfc->context.gdi->gfx) - { - xf_OutputExpose(xfc, x, y, w, h); - return TRUE; - } - xf_draw_screen(xfc, x, y, w, h); - } - else - { - xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window); - if (appWindow) - xf_UpdateWindowArea(xfc, appWindow, x, y, w, h); - xf_rail_return_window(appWindow, FALSE); - } + xfc->exposedWindow = event->window; + xfc->exposeRequested = TRUE; return TRUE; } + static BOOL xf_event_VisibilityNotify(xfContext* xfc, const XVisibilityEvent* event, BOOL app) { WINPR_UNUSED(app); @@ -1180,3 +1169,39 @@ BOOL xf_event_process(freerdp* instance, const XEvent* event) XSync(xfc->display, FALSE); return status; } + +BOOL xf_event_update_screen(freerdp* instance) +{ + WINPR_ASSERT(instance); + + xfContext* xfc = (xfContext*)instance->context; + WINPR_ASSERT(xfc); + + rdpSettings* settings = xfc->context.settings; + WINPR_ASSERT(settings); + + if (!xfc->exposeRequested) + return TRUE; + xfc->exposeRequested = FALSE; + + if (!xfc->remote_app) + { + if (xfc->context.gdi->gfx) + { + xf_OutputExpose(xfc, xfc->exposedArea.x, xfc->exposedArea.y, + xfc->exposedArea.w, xfc->exposedArea.h); + return TRUE; + } + xf_draw_screen(xfc, xfc->exposedArea.x, xfc->exposedArea.y, xfc->exposedArea.w, + xfc->exposedArea.h); + } + else + { + xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, xfc->exposedWindow); + if (appWindow) + xf_UpdateWindowArea(xfc, appWindow, xfc->exposedArea.x, xfc->exposedArea.y, + xfc->exposedArea.w, xfc->exposedArea.h); + xf_rail_return_window(appWindow, FALSE); + } + return TRUE; +} diff --git a/client/X11/xf_event.h b/client/X11/xf_event.h index 2269d3e..e025d19 100644 --- a/client/X11/xf_event.h +++ b/client/X11/xf_event.h @@ -29,6 +29,8 @@ BOOL xf_event_action_script_init(xfContext* xfc); void xf_event_action_script_free(xfContext* xfc); BOOL xf_event_process(freerdp* instance, const XEvent* event); + +BOOL xf_event_update_screen(freerdp* instance); void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...); diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 636e60a..a1a33b2 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -261,6 +261,10 @@ struct xf_context wHashTable* railWindows; xfRailIconCache* railIconCache; + BOOL exposeRequested; + GDI_RGN exposedArea; + Window exposedWindow; + BOOL xkbAvailable; BOOL xrenderAvailable; -- 2.53.0