171 lines
4.5 KiB
Diff
171 lines
4.5 KiB
Diff
From a25a6b8c53602d2023dd0ad685000dc006179e94 Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Holy <oholy@redhat.com>
|
|
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
|
|
|