Merge pull request #2386 from bjcollins/master

Fix remote app in xfreerdp.
This commit is contained in:
Marc-André Moreau 2015-02-12 10:14:23 -05:00
commit c817da07e1
4 changed files with 60 additions and 56 deletions

View File

@ -163,7 +163,12 @@ BOOL xf_detect_monitors(xfContext* xfc)
}
#endif
if (!xf_GetWorkArea(xfc))
/* WORKAROUND: With Remote Application Mode - using NET_WM_WORKAREA
* causes issues with the ability to fully size the window vertically
* (the bottom of the window area is never updated). So, we just set
* the workArea to match the full Screen width/height.
*/
if (settings->RemoteApplicationMode || !xf_GetWorkArea(xfc))
{
xfc->workArea.x = 0;
xfc->workArea.y = 0;

View File

@ -113,43 +113,31 @@ void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16
*/
void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow)
{
UINT32 offsetX = 0;
UINT32 offsetY = 0;
RAIL_WINDOW_MOVE_ORDER windowMove;
if (!appWindow->is_mapped || appWindow->local_move.state != LMS_NOT_ACTIVE)
return;
/* If current window position disagrees with RDP window position, send update to RDP server */
if (appWindow->x != appWindow->visibleOffsetX ||
appWindow->y != appWindow->visibleOffsetY ||
if (appWindow->x != (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) ||
appWindow->y != (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) ||
appWindow->width != appWindow->windowWidth ||
appWindow->height != appWindow->windowHeight)
{
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0
* when attempting to adjust the rail window.
*/
if (appWindow->windowOffsetX < 0)
offsetX = offsetX - appWindow->windowOffsetX;
if (appWindow->windowOffsetY < 0)
offsetY = offsetY - appWindow->windowOffsetY;
/*
* windowOffset corresponds to the window location on the rail server
* but our local window is based on the visibleOffset since using the windowOffset
* can result in blank areas for a maximized window
* but our local window is based uses a local offset since the windowOffset
* can be negative and but X does not support negative values. Not using an
* offset can result in blank areas for a maximized window
*/
windowMove.windowId = appWindow->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
* Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server
* New position is based on: Current local rail window offset +
* Local offset correction(current correction value to translate the local window offset to the server rail window offset)
*/
windowMove.left = offsetX + appWindow->windowOffsetX + (appWindow->x - appWindow->visibleOffsetX);
windowMove.top = offsetY + appWindow->windowOffsetY + (appWindow->y - appWindow->visibleOffsetY);
windowMove.left = appWindow->x + appWindow->localWindowOffsetCorrX;
windowMove.top = appWindow->y + appWindow->localWindowOffsetCorrY;
windowMove.right = windowMove.left + appWindow->width;
windowMove.bottom = windowMove.top + appWindow->height;
@ -162,37 +150,25 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
int x, y;
int child_x;
int child_y;
UINT32 offsetX = 0;
UINT32 offsetY = 0;
unsigned int mask;
Window root_window;
Window child_window;
RAIL_WINDOW_MOVE_ORDER windowMove;
rdpInput* input = xfc->instance->input;
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0 when
* attempting to adjust the rail window.
*/
if (appWindow->windowOffsetX < 0)
offsetX = offsetX - appWindow->windowOffsetX;
if (appWindow->windowOffsetY < 0)
offsetY = offsetY - appWindow->windowOffsetY;
/*
* For keyboard moves send and explicit update to RDP server
*/
windowMove.windowId = appWindow->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
* Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server
* New position is based on: Current local rail window offset +
* Local offset correction(current correction value to translate the local window offset to the server rail window offset)
*
*/
windowMove.left = offsetX + appWindow->windowOffsetX + (appWindow->x - appWindow->visibleOffsetX);
windowMove.top = offsetY + appWindow->windowOffsetY + (appWindow->y - appWindow->visibleOffsetY);
windowMove.left = appWindow->x + appWindow->localWindowOffsetCorrX;
windowMove.top = appWindow->y + appWindow->localWindowOffsetCorrY;
windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */
windowMove.bottom = windowMove.top + appWindow->height;
@ -218,8 +194,8 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
* we can start to receive GDI orders for the new window dimensions before we
* receive the RAIL ORDER for the new window size. This avoids that race condition.
*/
appWindow->windowOffsetX = offsetX + appWindow->windowOffsetX + (appWindow->x - appWindow->visibleOffsetX);
appWindow->windowOffsetY = offsetY + appWindow->windowOffsetY + (appWindow->y - appWindow->visibleOffsetY);
appWindow->windowOffsetX = windowMove.left;
appWindow->windowOffsetY = windowMove.top;
appWindow->windowWidth = appWindow->width;
appWindow->windowHeight = appWindow->height;
appWindow->local_move.state = LMS_TERMINATING;
@ -320,6 +296,9 @@ static void xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
appWindow->width = appWindow->windowWidth = windowState->windowWidth;
appWindow->height = appWindow->windowHeight = windowState->windowHeight;
appWindow->localWindowOffsetCorrX = 0;
appWindow->localWindowOffsetCorrY = 0;
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
{
char* title = NULL;
@ -358,6 +337,21 @@ static void xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
{
appWindow->windowOffsetX = windowState->windowOffsetX;
appWindow->windowOffsetY = windowState->windowOffsetY;
/*
* The rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* but we can only send unsigned integers to the rail server. Therefore, we maintain a local offset.
*/
if (appWindow->windowOffsetX < 0)
appWindow->localWindowOffsetCorrX = 0 - appWindow->windowOffsetX;
else
appWindow->localWindowOffsetCorrX = 0;
if (appWindow->windowOffsetY < 0)
appWindow->localWindowOffsetCorrY = 0 - appWindow->windowOffsetY;
else
appWindow->localWindowOffsetCorrY = 0;
}
if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
@ -491,20 +485,16 @@ static void xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
return;
/* Do nothing if window is already in the correct position */
if (appWindow->x == appWindow->visibleOffsetX &&
appWindow->y == appWindow->visibleOffsetY &&
if (appWindow->x == (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) &&
appWindow->y == (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) &&
appWindow->width == appWindow->windowWidth &&
appWindow->height == appWindow->windowHeight)
{
/*
* Just ensure entire window area is updated to handle cases where we
* have drawn locally before getting new bitmap from the server
*/
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
return;
}
xf_MoveWindow(xfc, appWindow, appWindow->visibleOffsetX, appWindow->visibleOffsetY,
xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX, appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY,
appWindow->windowWidth, appWindow->windowHeight);
}

View File

@ -886,14 +886,20 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANG
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height)
{
int ax, ay;
UINT32 translatedWindowOffsetX;
UINT32 translatedWindowOffsetY;
ax = x + appWindow->visibleOffsetX;
ay = y + appWindow->visibleOffsetY;
/* Translate the server rail window offset to a local offset */
translatedWindowOffsetX = (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX);
translatedWindowOffsetY = (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY);
if (ax + width > appWindow->visibleOffsetX + appWindow->width)
width = (appWindow->visibleOffsetX + appWindow->width - 1) - ax;
if (ay + height > appWindow->visibleOffsetY + appWindow->height)
height = (appWindow->visibleOffsetY + appWindow->height - 1) - ay;
ax = x + translatedWindowOffsetX;
ay = y + translatedWindowOffsetY;
if (ax + width > translatedWindowOffsetX + appWindow->width)
width = (translatedWindowOffsetX + appWindow->width - 1) - ax;
if (ay + height > translatedWindowOffsetY + appWindow->height)
height = (translatedWindowOffsetY + appWindow->height - 1) - ay;
xf_lock_x11(xfc, TRUE);

View File

@ -118,6 +118,9 @@ struct xf_app_window
UINT32 numVisibilityRects;
RECTANGLE_16* visibilityRects;
UINT32 localWindowOffsetCorrX;
UINT32 localWindowOffsetCorrY;
GC gc;
int shmid;
Window handle;