mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Merge pull request #12392 from akallabeth/x11-rails-lock-fix
[client,x11] improve rails window locking
This commit is contained in:
@@ -410,9 +410,8 @@ static BOOL xf_event_Expose(xfContext* xfc, const XExposeEvent* event, BOOL app)
|
|||||||
{
|
{
|
||||||
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
|
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
|
||||||
if (appWindow)
|
if (appWindow)
|
||||||
{
|
|
||||||
xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
|
xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
|
||||||
}
|
xf_rail_return_window(appWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -251,12 +251,12 @@ static Window xf_Pointer_get_window(xfContext* xfc)
|
|||||||
if (xfc->remote_app)
|
if (xfc->remote_app)
|
||||||
{
|
{
|
||||||
Window w = 0;
|
Window w = 0;
|
||||||
HashTable_Lock(xfc->railWindows);
|
xf_AppWindowsLock(xfc);
|
||||||
if (!xfc->appWindow)
|
if (!xfc->appWindow)
|
||||||
WLog_WARN(TAG, "xf_Pointer: Invalid appWindow");
|
WLog_WARN(TAG, "xf_Pointer: Invalid appWindow");
|
||||||
else
|
else
|
||||||
w = xfc->appWindow->handle;
|
w = xfc->appWindow->handle;
|
||||||
HashTable_Unlock(xfc->railWindows);
|
xf_AppWindowsUnlock(xfc);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -159,9 +159,10 @@ BOOL xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
|
|||||||
|
|
||||||
WINPR_ASSERT(appWindow->windowId <= UINT32_MAX);
|
WINPR_ASSERT(appWindow->windowId <= UINT32_MAX);
|
||||||
activate.windowId = (UINT32)appWindow->windowId;
|
activate.windowId = (UINT32)appWindow->windowId;
|
||||||
|
xf_rail_return_window(appWindow);
|
||||||
|
|
||||||
activate.enabled = enabled;
|
activate.enabled = enabled;
|
||||||
const UINT rc = xfc->rail->ClientActivate(xfc->rail, &activate);
|
const UINT rc = xfc->rail->ClientActivate(xfc->rail, &activate);
|
||||||
xf_rail_return_window(appWindow);
|
|
||||||
return rc == CHANNEL_RC_OK;
|
return rc == CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,6 +382,7 @@ static void window_state_log_style_int(wLog* log, const WINDOW_STATE_ORDER* wind
|
|||||||
static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
|
static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
|
||||||
const WINDOW_STATE_ORDER* windowState)
|
const WINDOW_STATE_ORDER* windowState)
|
||||||
{
|
{
|
||||||
|
BOOL rc = FALSE;
|
||||||
xfContext* xfc = (xfContext*)context;
|
xfContext* xfc = (xfContext*)context;
|
||||||
|
|
||||||
WINPR_ASSERT(xfc);
|
WINPR_ASSERT(xfc);
|
||||||
@@ -440,7 +442,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!appWindow->title)
|
if (!appWindow->title)
|
||||||
return FALSE;
|
goto fail;
|
||||||
|
|
||||||
xf_AppWindowInit(xfc, appWindow);
|
xf_AppWindowInit(xfc, appWindow);
|
||||||
}
|
}
|
||||||
@@ -518,14 +520,14 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
|||||||
if (!(title = _strdup("")))
|
if (!(title = _strdup("")))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "failed to duplicate empty window title string");
|
WLog_ERR(TAG, "failed to duplicate empty window title string");
|
||||||
return FALSE;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(title = ConvertWCharNToUtf8Alloc(
|
else if (!(title = ConvertWCharNToUtf8Alloc(
|
||||||
cnv.wc, windowState->titleInfo.length / sizeof(WCHAR), nullptr)))
|
cnv.wc, windowState->titleInfo.length / sizeof(WCHAR), nullptr)))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "failed to convert window title");
|
WLog_ERR(TAG, "failed to convert window title");
|
||||||
return FALSE;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(appWindow->title);
|
free(appWindow->title);
|
||||||
@@ -566,7 +568,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
|||||||
(RECTANGLE_16*)calloc(appWindow->numWindowRects, sizeof(RECTANGLE_16));
|
(RECTANGLE_16*)calloc(appWindow->numWindowRects, sizeof(RECTANGLE_16));
|
||||||
|
|
||||||
if (!appWindow->windowRects)
|
if (!appWindow->windowRects)
|
||||||
return FALSE;
|
goto fail;
|
||||||
|
|
||||||
CopyMemory(appWindow->windowRects, windowState->windowRects,
|
CopyMemory(appWindow->windowRects, windowState->windowRects,
|
||||||
appWindow->numWindowRects * sizeof(RECTANGLE_16));
|
appWindow->numWindowRects * sizeof(RECTANGLE_16));
|
||||||
@@ -595,7 +597,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
|||||||
(RECTANGLE_16*)calloc(appWindow->numVisibilityRects, sizeof(RECTANGLE_16));
|
(RECTANGLE_16*)calloc(appWindow->numVisibilityRects, sizeof(RECTANGLE_16));
|
||||||
|
|
||||||
if (!appWindow->visibilityRects)
|
if (!appWindow->visibilityRects)
|
||||||
return FALSE;
|
goto fail;
|
||||||
|
|
||||||
CopyMemory(appWindow->visibilityRects, windowState->visibilityRects,
|
CopyMemory(appWindow->visibilityRects, windowState->visibilityRects,
|
||||||
appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
|
appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
|
||||||
@@ -675,7 +677,10 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
|||||||
{
|
{
|
||||||
xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects);
|
xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects);
|
||||||
}*/
|
}*/
|
||||||
return TRUE;
|
rc = TRUE;
|
||||||
|
fail:
|
||||||
|
xf_rail_return_window(appWindow);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL xf_rail_window_delete(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo)
|
static BOOL xf_rail_window_delete(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo)
|
||||||
@@ -1186,14 +1191,14 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context,
|
|||||||
x = localMoveSize->posX;
|
x = localMoveSize->posX;
|
||||||
y = localMoveSize->posY;
|
y = localMoveSize->posY;
|
||||||
/* FIXME: local keyboard moves not working */
|
/* FIXME: local keyboard moves not working */
|
||||||
return CHANNEL_RC_OK;
|
break;
|
||||||
|
|
||||||
case RAIL_WMSZ_KEYSIZE:
|
case RAIL_WMSZ_KEYSIZE:
|
||||||
direction = NET_WM_MOVERESIZE_SIZE_KEYBOARD;
|
direction = NET_WM_MOVERESIZE_SIZE_KEYBOARD;
|
||||||
x = localMoveSize->posX;
|
x = localMoveSize->posX;
|
||||||
y = localMoveSize->posY;
|
y = localMoveSize->posY;
|
||||||
/* FIXME: local keyboard moves not working */
|
/* FIXME: local keyboard moves not working */
|
||||||
return CHANNEL_RC_OK;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1375,13 +1380,16 @@ xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, INT32 x, INT32 y, UIN
|
|||||||
appWindow->width = WINPR_ASSERTING_INT_CAST(int, width);
|
appWindow->width = WINPR_ASSERTING_INT_CAST(int, width);
|
||||||
appWindow->height = WINPR_ASSERTING_INT_CAST(int, height);
|
appWindow->height = WINPR_ASSERTING_INT_CAST(int, height);
|
||||||
|
|
||||||
|
xf_AppWindowsLock(xfc);
|
||||||
if (!xf_AppWindowCreate(xfc, appWindow))
|
if (!xf_AppWindowCreate(xfc, appWindow))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!HashTable_Insert(xfc->railWindows, &appWindow->windowId, (void*)appWindow))
|
if (!HashTable_Insert(xfc->railWindows, &appWindow->windowId, (void*)appWindow))
|
||||||
goto fail;
|
goto fail;
|
||||||
return appWindow;
|
return appWindow;
|
||||||
fail:
|
fail:
|
||||||
rail_window_free(appWindow);
|
rail_window_free(appWindow);
|
||||||
|
xf_AppWindowsUnlock(xfc);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1396,26 +1404,10 @@ BOOL xf_rail_del_window(xfContext* xfc, UINT64 id)
|
|||||||
return HashTable_Remove(xfc->railWindows, &id);
|
return HashTable_Remove(xfc->railWindows, &id);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id)
|
void xf_rail_return_windowFrom(xfAppWindow* window, const char* file, const char* fkt, size_t line)
|
||||||
{
|
|
||||||
if (!xfc)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!xfc->railWindows)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
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)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
HashTable_Unlock(window->xfc->railWindows);
|
xfAppWindowsUnlockFrom(window->xfc, file, fkt, line);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,10 +125,16 @@ BOOL xf_rail_disable_remoteapp_mode(xfContext* xfc);
|
|||||||
xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, INT32 x, INT32 y, UINT32 width,
|
xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, INT32 x, INT32 y, UINT32 width,
|
||||||
UINT32 height, UINT32 surfaceId);
|
UINT32 height, UINT32 surfaceId);
|
||||||
|
|
||||||
void xf_rail_return_window(xfAppWindow* window);
|
#define xf_rail_return_window(window) \
|
||||||
|
xf_rail_return_windowFrom((window), __FILE__, __func__, __LINE__)
|
||||||
|
void xf_rail_return_windowFrom(xfAppWindow* window, const char* file, const char* fkt, size_t line);
|
||||||
|
|
||||||
WINPR_ATTR_MALLOC(xf_rail_return_window, 1)
|
#define xf_rail_get_window(xfc, id) \
|
||||||
xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id);
|
xf_rail_get_windowFrom((xfc), (id), __FILE__, __func__, __LINE__)
|
||||||
|
|
||||||
|
WINPR_ATTR_MALLOC(xf_rail_return_windowFrom, 1)
|
||||||
|
xfAppWindow* xf_rail_get_windowFrom(xfContext* xfc, UINT64 id, const char* file, const char* fkt,
|
||||||
|
size_t line);
|
||||||
|
|
||||||
BOOL xf_rail_del_window(xfContext* xfc, UINT64 id);
|
BOOL xf_rail_del_window(xfContext* xfc, UINT64 id);
|
||||||
|
|
||||||
|
|||||||
@@ -1435,7 +1435,31 @@ void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow)
|
|||||||
free(appWindow);
|
free(appWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
|
static xfAppWindow* get_windowUnlocked(xfContext* xfc, UINT64 id)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(xfc);
|
||||||
|
return HashTable_GetItemValue(xfc->railWindows, &id);
|
||||||
|
}
|
||||||
|
|
||||||
|
xfAppWindow* xf_rail_get_windowFrom(xfContext* xfc, UINT64 id, const char* file, const char* fkt,
|
||||||
|
size_t line)
|
||||||
|
{
|
||||||
|
if (!xfc)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (!xfc->railWindows)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
xfAppWindowsLockFrom(xfc, file, fkt, line);
|
||||||
|
xfAppWindow* window = get_windowUnlocked(xfc, id);
|
||||||
|
if (!window)
|
||||||
|
xfAppWindowsUnlockFrom(xfc, file, fkt, line);
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
xfAppWindow* xf_AppWindowFromX11WindowFrom(xfContext* xfc, Window wnd, const char* file,
|
||||||
|
const char* fkt, size_t line)
|
||||||
{
|
{
|
||||||
ULONG_PTR* pKeys = nullptr;
|
ULONG_PTR* pKeys = nullptr;
|
||||||
|
|
||||||
@@ -1443,29 +1467,28 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
|
|||||||
if (!xfc->railWindows)
|
if (!xfc->railWindows)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
HashTable_Lock(xfc->railWindows);
|
xfAppWindowsLockFrom(xfc, file, fkt, line);
|
||||||
size_t count = HashTable_GetKeys(xfc->railWindows, &pKeys);
|
size_t count = HashTable_GetKeys(xfc->railWindows, &pKeys);
|
||||||
|
|
||||||
for (size_t index = 0; index < count; index++)
|
for (size_t index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
xfAppWindow* appWindow = xf_rail_get_window(xfc, *(UINT64*)pKeys[index]);
|
xfAppWindow* appWindow = get_windowUnlocked(xfc, *(UINT64*)pKeys[index]);
|
||||||
|
|
||||||
if (!appWindow)
|
if (!appWindow)
|
||||||
{
|
{
|
||||||
HashTable_Unlock(xfc->railWindows);
|
xfAppWindowsUnlockFrom(xfc, file, fkt, line);
|
||||||
free(pKeys);
|
free(pKeys);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appWindow->handle == wnd)
|
if (appWindow->handle == wnd)
|
||||||
{
|
{
|
||||||
HashTable_Unlock(xfc->railWindows);
|
|
||||||
free(pKeys);
|
free(pKeys);
|
||||||
return appWindow;
|
return appWindow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HashTable_Unlock(xfc->railWindows);
|
xfAppWindowsUnlockFrom(xfc, file, fkt, line);
|
||||||
free(pKeys);
|
free(pKeys);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -1585,3 +1608,39 @@ void xf_XSetTransientForHint(xfContext* xfc, xfAppWindow* window)
|
|||||||
(void)LogDynAndXSetTransientForHint(xfc->log, xfc->display, window->handle, parent->handle);
|
(void)LogDynAndXSetTransientForHint(xfc->log, xfc->display, window->handle, parent->handle);
|
||||||
xf_rail_return_window(parent);
|
xf_rail_return_window(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xfAppWindowsLockFrom(xfContext* xfc, WINPR_ATTR_UNUSED const char* file,
|
||||||
|
WINPR_ATTR_UNUSED const char* fkt, WINPR_ATTR_UNUSED size_t line)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(xfc);
|
||||||
|
|
||||||
|
#if defined(WITH_VERBOSE_WINPR_ASSERT)
|
||||||
|
const DWORD level = WLOG_TRACE;
|
||||||
|
if (WLog_IsLevelActive(xfc->log, level))
|
||||||
|
WLog_PrintTextMessage(xfc->log, level, line, file, fkt, "[rails] locking [%s]", fkt);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HashTable_Lock(xfc->railWindows);
|
||||||
|
|
||||||
|
#if defined(WITH_VERBOSE_WINPR_ASSERT)
|
||||||
|
WINPR_ASSERT(!xfc->isRailWindowsLocked);
|
||||||
|
xfc->isRailWindowsLocked = TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void xfAppWindowsUnlockFrom(xfContext* xfc, WINPR_ATTR_UNUSED const char* file,
|
||||||
|
WINPR_ATTR_UNUSED const char* fkt, WINPR_ATTR_UNUSED size_t line)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(xfc);
|
||||||
|
|
||||||
|
#if defined(WITH_VERBOSE_WINPR_ASSERT)
|
||||||
|
const DWORD level = WLOG_TRACE;
|
||||||
|
if (WLog_IsLevelActive(xfc->log, level))
|
||||||
|
WLog_PrintTextMessage(xfc->log, level, line, file, fkt, "[rails] unocking [%s]", fkt);
|
||||||
|
|
||||||
|
WINPR_ASSERT(xfc->isRailWindowsLocked);
|
||||||
|
xfc->isRailWindowsLocked = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HashTable_Unlock(xfc->railWindows);
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,8 +122,17 @@ void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow, int maxWidth
|
|||||||
void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction, int x, int y);
|
void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction, int x, int y);
|
||||||
void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow);
|
void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow);
|
||||||
|
|
||||||
WINPR_ATTR_MALLOC(xf_rail_return_window, 1)
|
#define xf_AppWindowFromX11Window(xfc, wnd) \
|
||||||
xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd);
|
xf_AppWindowFromX11WindowFrom((xfc), (wnd), __FILE__, __func__, __LINE__)
|
||||||
|
WINPR_ATTR_MALLOC(xf_rail_return_windowFrom, 1)
|
||||||
|
xfAppWindow* xf_AppWindowFromX11WindowFrom(xfContext* xfc, Window wnd, const char* file,
|
||||||
|
const char* fkt, size_t line);
|
||||||
|
|
||||||
|
#define xf_AppWindowsLock(xfc) xfAppWindowsLockFrom((xfc), __FILE__, __func__, __LINE__)
|
||||||
|
void xfAppWindowsLockFrom(xfContext* xfc, const char* file, const char* fkt, size_t line);
|
||||||
|
|
||||||
|
#define xf_AppWindowsUnlock(xfc) xfAppWindowsUnlockFrom((xfc), __FILE__, __func__, __LINE__)
|
||||||
|
void xfAppWindowsUnlockFrom(xfContext* xfc, const char* file, const char* fkt, size_t line);
|
||||||
|
|
||||||
const char* window_styles_to_string(UINT32 style, char* buffer, size_t length);
|
const char* window_styles_to_string(UINT32 style, char* buffer, size_t length);
|
||||||
const char* window_styles_ex_to_string(UINT32 styleEx, char* buffer, size_t length);
|
const char* window_styles_ex_to_string(UINT32 styleEx, char* buffer, size_t length);
|
||||||
|
|||||||
@@ -290,6 +290,10 @@ struct xf_context
|
|||||||
wHashTable* railWindows;
|
wHashTable* railWindows;
|
||||||
xfRailIconCache* railIconCache;
|
xfRailIconCache* railIconCache;
|
||||||
|
|
||||||
|
#if defined(WITH_VERBOSE_WINPR_ASSERT)
|
||||||
|
BOOL isRailWindowsLocked;
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOL xkbAvailable;
|
BOOL xkbAvailable;
|
||||||
BOOL xrenderAvailable;
|
BOOL xrenderAvailable;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user