Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RubenKelevra/e55301230267c8e260daf93b170333da to your computer and use it in GitHub Desktop.
Save RubenKelevra/e55301230267c8e260daf93b170333da to your computer and use it in GitHub Desktop.
reverts broken commit which destroyes multimonitor-support. refs https://bugs.archlinux.org/task/50497?project=0 https://github.com/FreeRDP/FreeRDP/issues/2707
From 0a89047e105431ddca682f9ea7ce62d0f869f052 Mon Sep 17 00:00:00 2001
From: RubenKelevra <ruben@vfn-nrw.de>
Date: Wed, 21 Sep 2016 11:05:50 +0200
Subject: [PATCH] fix multi-monitor-support
---
client/X11/xf_window.c | 139 +++++++++++++++++++------------------------------
1 file changed, 55 insertions(+), 84 deletions(-)
diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c
index 95c29a0..ee45c23 100644
--- a/client/X11/xf_window.c
+++ b/client/X11/xf_window.c
@@ -36,7 +36,6 @@
#include <winpr/thread.h>
#include <winpr/crt.h>
-#include <winpr/string.h>
#include <freerdp/rail.h>
#include <freerdp/log.h>
@@ -141,33 +140,14 @@ void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int n
void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
{
int i;
- rdpSettings* settings = xfc->settings;
- int startX, startY;
- UINT32 width = window->width;
- UINT32 height = window->height;
+ int startX = xfc->instance->settings->DesktopPosX;
+ int startY = xfc->instance->settings->DesktopPosY;
window->decorations = xfc->decorations;
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
- if (fullscreen)
- {
- xfc->savedWidth = xfc->window->width;
- xfc->savedHeight = xfc->window->height;
- xfc->savedPosX = xfc->window->left;
- xfc->savedPosY = xfc->window->top;
- startX = settings->DesktopPosX;
- startY = settings->DesktopPosY;
- }
- else
- {
- width = xfc->savedWidth;
- height = xfc->savedHeight;
- startX = xfc->savedPosX;
- startY = xfc->savedPosY;
- }
-
/* Determine the x,y starting location for the fullscreen window */
- if (fullscreen && xfc->instance->settings->MonitorCount)
+ if (xfc->instance->settings->MonitorCount)
{
/* Initialize startX and startY with reasonable values */
startX = xfc->instance->settings->MonitorDefArray[0].x;
@@ -185,36 +165,27 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
*/
startX = startX + xfc->instance->settings->MonitorLocalShiftX;
startY = startY + xfc->instance->settings->MonitorLocalShiftY;
-
- /* Set monitor bounds */
- if (settings->MonitorCount > 1)
- {
- xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5,
- xfc->fullscreenMonitors.top,
- xfc->fullscreenMonitors.bottom,
- xfc->fullscreenMonitors.left,
- xfc->fullscreenMonitors.right,
- 1);
- }
}
- xf_ResizeDesktopWindow(xfc, window, width, height);
-
- if (fullscreen)
- {
- /* enter full screen: move the window before adding NET_WM_STATE_FULLSCREEN */
- XMoveWindow(xfc->display, window->handle, startX, startY);
- }
+ XMoveResizeWindow(xfc->display, window->handle, startX, startY, window->width, window->height);
/* Set the fullscreen state */
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
xfc->_NET_WM_STATE_FULLSCREEN, 0, 0);
- if (!fullscreen)
+ /* Only send monitor bounds if they are valid */
+ if ((xfc->fullscreenMonitors.top >= 0) &&
+ (xfc->fullscreenMonitors.bottom >= 0) &&
+ (xfc->fullscreenMonitors.left >= 0) &&
+ (xfc->fullscreenMonitors.right >= 0))
{
- /* leave full screen: move the window after removing NET_WM_STATE_FULLSCREEN */
- XMoveWindow(xfc->display, window->handle, startX, startY);
+ xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5,
+ xfc->fullscreenMonitors.top,
+ xfc->fullscreenMonitors.bottom,
+ xfc->fullscreenMonitors.left,
+ xfc->fullscreenMonitors.right,
+ 1);
}
}
@@ -239,7 +210,7 @@ BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int leng
if (actual_type == None)
{
- WLog_INFO(TAG, "Property %lu does not exist", property);
+ WLog_ERR(TAG, "Property %lu does not exist", property);
return FALSE;
}
@@ -334,7 +305,7 @@ static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid)
if (!pid)
pid = getpid();
- am_wm_pid = xfc->_NET_WM_PID;
+ am_wm_pid = XInternAtom(xfc->display, "_NET_WM_PID", False);
XChangeProperty(xfc->display, window, am_wm_pid, XA_CARDINAL,
32, PropModeReplace, (BYTE*) &pid, 1);
@@ -343,7 +314,7 @@ static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid)
static const char* get_shm_id()
{
static char shm_id[64];
- sprintf_s(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
+ snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
return shm_id;
}
@@ -376,7 +347,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
- window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE));
+ window->shmid = shm_open(get_shm_id(), O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
if (window->shmid < 0)
{
@@ -390,7 +361,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED, window->shmid, 0);
- if (mem == MAP_FAILED)
+ if (mem == ((int*) -1))
{
DEBUG_X11("xf_CreateDesktopWindow: failed to assign pointer to the memory address - shmat()\n");
}
@@ -492,14 +463,11 @@ void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int hei
if (!xfc->settings->SmartSizing)
#endif
{
- if (!xfc->fullscreen)
- {
- size_hints->min_width = size_hints->max_width = width;
- size_hints->min_height = size_hints->max_height = height;
- XSetWMNormalHints(xfc->display, window->handle, size_hints);
- }
+ size_hints->min_width = size_hints->max_width = width;
+ size_hints->min_height = size_hints->max_height = height;
}
+ XSetWMNormalHints(xfc->display, window->handle, size_hints);
XFree(size_hints);
}
@@ -574,20 +542,19 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
}
else
{
- window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
+ XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE,
+ XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
}
-
- XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE,
- XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
}
void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name)
{
+ XStoreName(xfc->display, appWindow->handle, name);
const size_t i = strlen(name);
XStoreName(xfc->display, appWindow->handle, name);
- Atom wm_Name = xfc->_NET_WM_NAME;
- Atom utf8Str = xfc->UTF8_STRING;
+ Atom wm_Name = XInternAtom(xfc->display, "_NET_WM_NAME", FALSE);
+ Atom utf8Str = XInternAtom(xfc->display, "UTF8_STRING", FALSE);
XChangeProperty(xfc->display, appWindow->handle, wm_Name, utf8Str, 8,
PropModeReplace, (unsigned char *)name, i);
@@ -668,7 +635,7 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
else
{
class = malloc(sizeof("RAIL:00000000"));
- sprintf_s(class, sizeof("RAIL:00000000"), "RAIL:%08X", appWindow->windowId);
+ snprintf(class, sizeof("RAIL:00000000"), "RAIL:%08X", appWindow->windowId);
class_hints->res_class = class;
}
@@ -676,7 +643,8 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
XSetClassHint(xfc->display, appWindow->handle, class_hints);
XFree(class_hints);
- free(class);
+ if (class)
+ free(class);
}
/* Set the input mode hint for the WM */
@@ -711,8 +679,6 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
/* Move doesn't seem to work until window is mapped. */
xf_MoveWindow(xfc, appWindow, appWindow->x, appWindow->y, appWindow->width, appWindow->height);
- xf_SetWindowText(xfc, appWindow, appWindow->title);
-
return 1;
}
@@ -830,10 +796,9 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
case WINDOW_SHOW_MAXIMIZED:
/* Set the window as maximized */
- xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4,
- _NET_WM_STATE_ADD,
- xfc->_NET_WM_STATE_MAXIMIZED_VERT,
- xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0);
+ xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, 1,
+ XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
+ XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
/*
* This is a workaround for the case where the window is maximized locally before the rail server is told to maximize
* the window, this appears to be a race condition where the local window with incomplete data and once the window is
@@ -848,10 +813,9 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
case WINDOW_SHOW:
/* Ensure the window is not maximized */
- xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4,
- _NET_WM_STATE_REMOVE,
- xfc->_NET_WM_STATE_MAXIMIZED_VERT,
- xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0);
+ xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, 0,
+ XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
+ XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
/*
* Ignore configure requests until both the Maximized properties have been processed
* to prevent condition where WM overrides size of request due to one or both of these properties
@@ -917,7 +881,6 @@ void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rec
if (nrects < 1)
return;
-#ifdef WITH_XEXT
xrects = (XRectangle*) calloc(nrects, sizeof(XRectangle));
for (i = 0; i < nrects; i++)
@@ -928,12 +891,14 @@ void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rec
xrects[i].height = rects[i].bottom - rects[i].top;
}
+#ifdef WITH_XEXT
XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
- free(xrects);
#endif
+ free(xrects);
}
+//void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects)
void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32 rectsOffsetX, UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects)
{
int i;
@@ -942,7 +907,6 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32
if (nrects < 1)
return;
-#ifdef WITH_XEXT
xrects = (XRectangle*) calloc(nrects, sizeof(XRectangle));
for (i = 0; i < nrects; i++)
@@ -953,23 +917,30 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32
xrects[i].height = rects[i].bottom - rects[i].top;
}
- XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, rectsOffsetX, rectsOffsetY, xrects, nrects, ShapeSet, 0);
- free(xrects);
+#ifdef WITH_XEXT
+ XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
#endif
+ free(xrects);
}
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height)
{
int ax, ay;
+ UINT32 translatedWindowOffsetX;
+ UINT32 translatedWindowOffsetY;
+
+ /* Translate the server rail window offset to a local offset */
+ translatedWindowOffsetX = (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX);
+ translatedWindowOffsetY = (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY);
- ax = x + appWindow->windowOffsetX;
- ay = y + appWindow->windowOffsetY;
+ ax = x + translatedWindowOffsetX;
+ ay = y + translatedWindowOffsetY;
- if (ax + width > appWindow->windowOffsetX + appWindow->width)
- width = (appWindow->windowOffsetX + appWindow->width - 1) - ax;
- if (ay + height > appWindow->windowOffsetY + appWindow->height)
- height = (appWindow->windowOffsetY + appWindow->height - 1) - ay;
+ 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);
--
2.9.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment