[client,x11] lock appWindow

When using xf_rail_get_window lock the hash talbe until xf_rail_return_window
This commit is contained in:
Armin Novak
2026-02-09 16:09:51 +01:00
parent b4f0f0a18f
commit 1994e98442
6 changed files with 89 additions and 35 deletions

View File

@@ -441,7 +441,9 @@ BOOL xf_generic_MotionNotify_(xfContext* xfc, int x, int y, Window window, BOOL
if (app)
{
/* make sure window exists */
if (!xf_AppWindowFromX11Window(xfc, window))
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, window);
xf_rail_return_window(appWindow);
if (!appWindow)
return TRUE;
/* Translate to desktop coordinates */
@@ -547,7 +549,9 @@ BOOL xf_generic_ButtonEvent_(xfContext* xfc, int x, int y, int button, Window wi
if (app)
{
/* make sure window exists */
if (!xf_AppWindowFromX11Window(xfc, window))
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, window);
xf_rail_return_window(appWindow);
if (!appWindow)
return TRUE;
/* Translate to desktop coordinates */
@@ -708,6 +712,7 @@ static BOOL xf_event_FocusIn(xfContext* xfc, const XFocusInEvent* event, BOOL ap
*/
if (appWindow)
xf_rail_adjust_position(xfc, appWindow);
xf_rail_return_window(appWindow);
}
xf_keyboard_focus_in(xfc);
@@ -762,12 +767,13 @@ static BOOL xf_event_ClientMessage(xfContext* xfc, const XClientMessageEvent* ev
{
if (app)
{
BOOL rc = TRUE;
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
if (appWindow)
return xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
return TRUE;
rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
xf_rail_return_window(appWindow);
return rc;
}
else
{
@@ -800,6 +806,7 @@ static BOOL xf_event_EnterNotify(xfContext* xfc, const XEnterWindowEvent* event,
/* keep track of which window has focus so that we can apply pointer updates */
xfc->appWindow = appWindow;
xf_rail_return_window(appWindow);
}
return TRUE;
@@ -821,6 +828,7 @@ static BOOL xf_event_LeaveNotify(xfContext* xfc, const XLeaveWindowEvent* event,
/* keep track of which window has focus so that we can apply pointer updates */
if (xfc->appWindow == appWindow)
xfc->appWindow = NULL;
xf_rail_return_window(appWindow);
}
return TRUE;
}
@@ -926,6 +934,7 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, const XConfigureEvent* even
xf_rail_adjust_position(xfc, appWindow);
}
}
xf_rail_return_window(appWindow);
}
return xf_pointer_update_scale(xfc);
}
@@ -949,6 +958,7 @@ static BOOL xf_event_MapNotify(xfContext* xfc, const XMapEvent* event, BOOL app)
// xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
appWindow->is_mapped = TRUE;
}
xf_rail_return_window(appWindow);
}
return TRUE;
@@ -963,13 +973,14 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, const XUnmapEvent* event, BOOL
xf_keyboard_release_all_keypress(xfc);
if (!app)
gdi_send_suppress_output(xfc->common.context.gdi, TRUE);
else
return gdi_send_suppress_output(xfc->common.context.gdi, TRUE);
{
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
if (appWindow)
appWindow->is_mapped = FALSE;
xf_rail_return_window(appWindow);
}
return TRUE;
@@ -977,6 +988,7 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, const XUnmapEvent* event, BOOL
static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event, BOOL app)
{
BOOL rc = TRUE;
WINPR_ASSERT(xfc);
WINPR_ASSERT(event);
@@ -1001,7 +1013,7 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event,
appWindow = xf_AppWindowFromX11Window(xfc, event->window);
if (!appWindow)
return TRUE;
goto fail;
}
if (event->atom == xfc->NET_WM_STATE)
@@ -1073,8 +1085,7 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event,
if (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED)
{
appWindow->rail_state = WINDOW_SHOW_MAXIMIZED;
return xf_rail_send_client_system_command(xfc, appWindow->windowId,
SC_MAXIMIZE);
rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MAXIMIZE);
}
}
else if (appWindow->minimized)
@@ -1082,8 +1093,7 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event,
if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)
{
appWindow->rail_state = WINDOW_SHOW_MINIMIZED;
return xf_rail_send_client_system_command(xfc, appWindow->windowId,
SC_MINIMIZE);
rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MINIMIZE);
}
}
else
@@ -1091,15 +1101,18 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event,
if (appWindow->rail_state != WINDOW_SHOW && appWindow->rail_state != WINDOW_HIDE)
{
appWindow->rail_state = WINDOW_SHOW;
return xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
}
}
}
else if (minimizedChanged)
gdi_send_suppress_output(xfc->common.context.gdi, minimized);
rc = gdi_send_suppress_output(xfc->common.context.gdi, minimized);
fail:
xf_rail_return_window(appWindow);
}
return TRUE;
return rc;
}
static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, const XEvent* event)
@@ -1215,7 +1228,9 @@ BOOL xf_event_process(freerdp* instance, const XEvent* event)
/* Update "current" window for cursor change orders */
xfc->appWindow = appWindow;
if (xf_event_suppress_events(xfc, appWindow, event))
const BOOL rc = xf_event_suppress_events(xfc, appWindow, event);
xf_rail_return_window(appWindow);
if (rc)
return TRUE;
}
}

View File

@@ -253,12 +253,14 @@ static Window xf_Pointer_get_window(xfContext* xfc)
}
if (xfc->remote_app)
{
Window w = 0;
HashTable_Lock(xfc->railWindows);
if (!xfc->appWindow)
{
WLog_WARN(TAG, "xf_Pointer: Invalid appWindow");
return 0;
}
return xfc->appWindow->handle;
else
w = xfc->appWindow->handle;
HashTable_Unlock(xfc->railWindows);
return w;
}
else
{

View File

@@ -159,6 +159,7 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
activate.windowId = (UINT32)appWindow->windowId;
activate.enabled = enabled;
xfc->rail->ClientActivate(xfc->rail, &activate);
xf_rail_return_window(appWindow);
}
BOOL xf_rail_send_client_system_command(xfContext* xfc, UINT64 windowId, UINT16 command)
@@ -316,6 +317,7 @@ BOOL xf_rail_paint_surface(xfContext* xfc, UINT64 windowId, const RECTANGLE_16*
updateRect.right - updateRect.left, updateRect.bottom - updateRect.top);
}
region16_uninit(&windowInvalidRegion);
xf_rail_return_window(appWindow);
return TRUE;
}
@@ -808,6 +810,7 @@ static void xf_rail_set_window_icon(xfContext* xfc, xfAppWindow* railWindow, xfR
static BOOL xf_rail_window_icon(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
const WINDOW_ICON_ORDER* windowIcon)
{
BOOL rc = FALSE;
xfContext* xfc = (xfContext*)context;
BOOL replaceIcon = 0;
xfAppWindow* railWindow = xf_rail_get_window(xfc, orderInfo->windowId);
@@ -825,24 +828,26 @@ static BOOL xf_rail_window_icon(rdpContext* context, const WINDOW_ORDER_INFO* or
{
WLog_Print(xfc->log, WLOG_WARN, "failed to get icon from cache %02X:%04X",
windowIcon->iconInfo->cacheId, windowIcon->iconInfo->cacheEntry);
return FALSE;
}
if (!convert_rail_icon(windowIcon->iconInfo, icon))
else if (!convert_rail_icon(windowIcon->iconInfo, icon))
{
WLog_Print(xfc->log, WLOG_WARN, "failed to convert icon for window %08X",
orderInfo->windowId);
return FALSE;
}
replaceIcon = !!(orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW);
xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
return TRUE;
else
{
replaceIcon = !!(orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW);
xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
rc = TRUE;
}
xf_rail_return_window(railWindow);
return rc;
}
static BOOL xf_rail_window_cached_icon(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
const WINDOW_CACHED_ICON_ORDER* windowCachedIcon)
{
BOOL rc = FALSE;
xfContext* xfc = (xfContext*)context;
WINPR_ASSERT(orderInfo);
@@ -862,12 +867,15 @@ static BOOL xf_rail_window_cached_icon(rdpContext* context, const WINDOW_ORDER_I
{
WLog_Print(xfc->log, WLOG_WARN, "failed to get icon from cache %02X:%04X",
windowCachedIcon->cachedIcon.cacheId, windowCachedIcon->cachedIcon.cacheEntry);
return FALSE;
}
replaceIcon = !!(orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW);
xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
return TRUE;
else
{
replaceIcon = !!(orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW);
xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
rc = TRUE;
}
xf_rail_return_window(railWindow);
return rc;
}
static BOOL
@@ -1184,6 +1192,7 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context,
else
xf_EndLocalMoveSize(xfc, appWindow);
xf_rail_return_window(appWindow);
return CHANNEL_RC_OK;
}
@@ -1208,6 +1217,7 @@ static UINT xf_rail_server_min_max_info(RailClientContext* context,
minMaxInfo->minTrackHeight, minMaxInfo->maxTrackWidth,
minMaxInfo->maxTrackHeight);
}
xf_rail_return_window(appWindow);
return CHANNEL_RC_OK;
}
@@ -1381,7 +1391,20 @@ xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id)
return NULL;
if (!xfc->railWindows)
return FALSE;
return NULL;
return HashTable_GetItemValue(xfc->railWindows, &id);
HashTable_Lock(xfc->railWindows);
xfAppWindow* window = HashTable_GetItemValue(xfc->railWindows, &id);
if (!window)
HashTable_Unlock(xfc->railWindows);
return window;
}
void xf_rail_return_window(xfAppWindow* window)
{
if (!window)
return;
HashTable_Unlock(window->xfc->railWindows);
}

View File

@@ -37,6 +37,10 @@ void xf_rail_disable_remoteapp_mode(xfContext* xfc);
xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, INT32 x, INT32 y, UINT32 width,
UINT32 height, UINT32 surfaceId);
void xf_rail_return_window(xfAppWindow* window);
WINPR_ATTR_MALLOC(xf_rail_return_window, 1)
xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id);
BOOL xf_rail_del_window(xfContext* xfc, UINT64 id);

View File

@@ -1436,6 +1436,7 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
if (!xfc->railWindows)
return NULL;
HashTable_Lock(xfc->railWindows);
size_t count = HashTable_GetKeys(xfc->railWindows, &pKeys);
for (size_t index = 0; index < count; index++)
@@ -1444,17 +1445,20 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
if (!appWindow)
{
HashTable_Unlock(xfc->railWindows);
free(pKeys);
return NULL;
}
if (appWindow->handle == wnd)
{
HashTable_Unlock(xfc->railWindows);
free(pKeys);
return appWindow;
}
}
HashTable_Unlock(xfc->railWindows);
free(pKeys);
return NULL;
}
@@ -1535,6 +1539,7 @@ UINT xf_AppUpdateWindowFromSurface(xfContext* xfc, gdiGfxSurface* surface)
rc = CHANNEL_RC_OK;
fail:
xf_rail_return_window(appWindow);
LogDynAndXFlush(xfc->log, xfc->display);
xf_unlock_x11(xfc);
return rc;
@@ -1571,4 +1576,5 @@ void xf_XSetTransientForHint(xfContext* xfc, xfAppWindow* window)
return;
(void)LogDynAndXSetTransientForHint(xfc->log, xfc->display, window->handle, parent->handle);
xf_rail_return_window(parent);
}

View File

@@ -202,6 +202,10 @@ void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow, int maxWidth
int maxTrackWidth, int maxTrackHeight);
void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction, int x, int y);
void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow);
void xf_rail_return_window(xfAppWindow* window);
WINPR_ATTR_MALLOC(xf_rail_return_window, 1)
xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd);
const char* window_styles_to_string(UINT32 style, char* buffer, size_t length);