Merge pull request #2426 from bjcollins/master
xfreerdp fullscreen enhancements
This commit is contained in:
commit
719a0fd3e9
@ -516,7 +516,7 @@ BOOL xf_create_window(xfContext* xfc)
|
||||
xfc->attribs.background_pixel = BlackPixelOfScreen(xfc->screen);
|
||||
xfc->attribs.border_pixel = WhitePixelOfScreen(xfc->screen);
|
||||
xfc->attribs.backing_store = xfc->primary ? NotUseful : Always;
|
||||
xfc->attribs.override_redirect = xfc->grab_keyboard ? xfc->fullscreen : False;
|
||||
xfc->attribs.override_redirect = False;
|
||||
xfc->attribs.colormap = xfc->colormap;
|
||||
xfc->attribs.bit_gravity = NorthWestGravity;
|
||||
xfc->attribs.win_gravity = NorthWestGravity;
|
||||
@ -571,7 +571,7 @@ BOOL xf_create_window(xfContext* xfc)
|
||||
}
|
||||
#endif
|
||||
|
||||
xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height, xfc->decorations);
|
||||
xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height);
|
||||
|
||||
free(windowTitle);
|
||||
|
||||
@ -579,6 +579,10 @@ BOOL xf_create_window(xfContext* xfc)
|
||||
xf_SetWindowFullscreen(xfc, xfc->window, xfc->fullscreen);
|
||||
|
||||
xfc->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
|
||||
|
||||
/* Disallow resize now that any initial fullscreen window operation is complete */
|
||||
xf_SetWindowSizeHints(xfc, xfc->window, FALSE, xfc->width, xfc->height);
|
||||
|
||||
XSetWMProtocols(xfc->display, xfc->window->handle, &(xfc->WM_DELETE_WINDOW), 1);
|
||||
xfc->drawable = xfc->window->handle;
|
||||
}
|
||||
@ -686,16 +690,12 @@ void xf_toggle_fullscreen(xfContext* xfc)
|
||||
rdpContext* context = (rdpContext*) xfc;
|
||||
rdpSettings* settings = context->settings;
|
||||
|
||||
xf_lock_x11(xfc, TRUE);
|
||||
|
||||
xf_window_free(xfc);
|
||||
|
||||
xfc->fullscreen = (xfc->fullscreen) ? FALSE : TRUE;
|
||||
xfc->decorations = (xfc->fullscreen) ? FALSE : settings->Decorations;
|
||||
|
||||
xf_create_window(xfc);
|
||||
|
||||
xf_unlock_x11(xfc, TRUE);
|
||||
xf_SetWindowSizeHints(xfc, xfc->window, TRUE, xfc->width, xfc->height);
|
||||
xf_SetWindowFullscreen(xfc, xfc->window, xfc->fullscreen);
|
||||
xf_SetWindowSizeHints(xfc, xfc->window, FALSE, xfc->width, xfc->height);
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.state = xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0;
|
||||
@ -1697,6 +1697,7 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
xfc->_NET_WORKAREA = XInternAtom(xfc->display, "_NET_WORKAREA", False);
|
||||
xfc->_NET_WM_STATE = XInternAtom(xfc->display, "_NET_WM_STATE", False);
|
||||
xfc->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfc->display, "_NET_WM_STATE_FULLSCREEN", False);
|
||||
xfc->_NET_WM_FULLSCREEN_MONITORS = XInternAtom(xfc->display, "_NET_WM_FULLSCREEN_MONITORS", False);
|
||||
xfc->_NET_WM_WINDOW_TYPE = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE", False);
|
||||
xfc->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
|
||||
xfc->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||
|
@ -118,13 +118,17 @@ BOOL xf_is_monitor_id_active(xfContext* xfc, UINT32 id)
|
||||
BOOL xf_detect_monitors(xfContext* xfc)
|
||||
{
|
||||
int i;
|
||||
int nmonitors;
|
||||
int primaryMonitor;
|
||||
int vWidth, vHeight;
|
||||
int nmonitors = 0;
|
||||
int primaryMonitorFound = FALSE;
|
||||
int vX, vY, vWidth, vHeight;
|
||||
int maxWidth, maxHeight;
|
||||
VIRTUAL_SCREEN* vscreen;
|
||||
rdpSettings* settings = xfc->settings;
|
||||
|
||||
int mouse_x, mouse_y, _dummy_i;
|
||||
Window _dummy_w;
|
||||
int current_monitor = 0;
|
||||
|
||||
#ifdef WITH_XINERAMA
|
||||
int major, minor;
|
||||
XineramaScreenInfo* screenInfo = NULL;
|
||||
@ -134,6 +138,12 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
xfc->desktopWidth = settings->DesktopWidth;
|
||||
xfc->desktopHeight = settings->DesktopHeight;
|
||||
|
||||
/* get mouse location */
|
||||
if (!XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
|
||||
&_dummy_w, &_dummy_w, &mouse_x, &mouse_y,
|
||||
&_dummy_i, &_dummy_i, (void *) &_dummy_i))
|
||||
mouse_x = mouse_y = 0;
|
||||
|
||||
#ifdef WITH_XINERAMA
|
||||
if (XineramaQueryExtension(xfc->display, &major, &minor))
|
||||
{
|
||||
@ -153,8 +163,12 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1;
|
||||
vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - 1;
|
||||
|
||||
if ((screenInfo[i].x_org == 0) && (screenInfo[i].y_org == 0))
|
||||
vscreen->monitors[i].primary = TRUE;
|
||||
/* Determine which monitor that the mouse cursor is on */
|
||||
if ((mouse_x >= vscreen->monitors[i].area.left) &&
|
||||
(mouse_x <= vscreen->monitors[i].area.right) &&
|
||||
(mouse_y >= vscreen->monitors[i].area.top) &&
|
||||
(mouse_y <= vscreen->monitors[i].area.bottom))
|
||||
current_monitor = i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,6 +177,9 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
}
|
||||
#endif
|
||||
|
||||
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0;
|
||||
|
||||
/* 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
|
||||
@ -194,6 +211,16 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
{
|
||||
xfc->desktopWidth = (xfc->workArea.width * settings->PercentScreen) / 100;
|
||||
xfc->desktopHeight = (xfc->workArea.height * settings->PercentScreen) / 100;
|
||||
|
||||
/* If we have specific monitor information then limit the PercentScreen value
|
||||
* to only affect the current monitor vs. the entire desktop
|
||||
*/
|
||||
if (vscreen->nmonitors > 0)
|
||||
{
|
||||
settings->DesktopWidth = ((vscreen->monitors[current_monitor].area.right - vscreen->monitors[current_monitor].area.left + 1) * settings->PercentScreen) / 100;
|
||||
settings->DesktopHeight = ((vscreen->monitors[current_monitor].area.bottom - vscreen->monitors[current_monitor].area.top + 1) * settings->PercentScreen) / 100;
|
||||
}
|
||||
|
||||
maxWidth = xfc->desktopWidth;
|
||||
maxHeight = xfc->desktopHeight;
|
||||
}
|
||||
@ -206,30 +233,24 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
if (!settings->Fullscreen && !settings->Workarea && !settings->UseMultimon)
|
||||
return TRUE;
|
||||
|
||||
/* If single monitor fullscreen OR workarea without remote app */
|
||||
if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) ||
|
||||
(settings->Workarea && !settings->RemoteApplicationMode))
|
||||
{
|
||||
/* Select a single monitor */
|
||||
|
||||
if (settings->NumMonitorIds != 1)
|
||||
/* If no monitors were specified on the command-line then set the current monitor as active */
|
||||
if (!settings->NumMonitorIds)
|
||||
{
|
||||
settings->NumMonitorIds = 1;
|
||||
settings->MonitorIds[0] = 0;
|
||||
|
||||
for (i = 0; i < vscreen->nmonitors; i++)
|
||||
{
|
||||
if (vscreen->monitors[i].primary)
|
||||
{
|
||||
settings->MonitorIds[0] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
settings->MonitorIds[0] = current_monitor;
|
||||
}
|
||||
|
||||
/* Always sets number of monitors from command-line to just 1.
|
||||
* If the monitor is invalid then we will default back to current monitor
|
||||
* later as a fallback. So, there is no need to validate command-line entry here.
|
||||
*/
|
||||
settings->NumMonitorIds = 1;
|
||||
}
|
||||
|
||||
nmonitors = 0;
|
||||
primaryMonitor = 0;
|
||||
|
||||
/* Create array of all active monitors by taking into account monitors requested on the command-line */
|
||||
for (i = 0; i < vscreen->nmonitors; i++)
|
||||
{
|
||||
if (!xf_is_monitor_id_active(xfc, i))
|
||||
@ -239,43 +260,114 @@ BOOL xf_detect_monitors(xfContext* xfc)
|
||||
settings->MonitorDefArray[nmonitors].y = vscreen->monitors[i].area.top;
|
||||
settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1, xfc->desktopWidth);
|
||||
settings->MonitorDefArray[nmonitors].height = MIN(vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, xfc->desktopHeight);
|
||||
settings->MonitorDefArray[nmonitors].is_primary = vscreen->monitors[i].primary;
|
||||
settings->MonitorDefArray[nmonitors].orig_screen = i;
|
||||
|
||||
primaryMonitor |= vscreen->monitors[i].primary;
|
||||
nmonitors++;
|
||||
}
|
||||
|
||||
/* If no monitor is active(bogus command-line monitor specification) - then lets try to fallback to go fullscreen on the current monitor only */
|
||||
if (nmonitors == 0 && vscreen->nmonitors > 0)
|
||||
{
|
||||
settings->MonitorDefArray[0].x = vscreen->monitors[current_monitor].area.left;
|
||||
settings->MonitorDefArray[0].y = vscreen->monitors[current_monitor].area.top;
|
||||
settings->MonitorDefArray[0].width = MIN(vscreen->monitors[current_monitor].area.right - vscreen->monitors[current_monitor].area.left + 1, xfc->desktopWidth);
|
||||
settings->MonitorDefArray[0].height = MIN(vscreen->monitors[current_monitor].area.bottom - vscreen->monitors[current_monitor].area.top + 1, xfc->desktopHeight);
|
||||
settings->MonitorDefArray[0].orig_screen = current_monitor;
|
||||
|
||||
nmonitors = 1;
|
||||
}
|
||||
|
||||
settings->MonitorCount = nmonitors;
|
||||
|
||||
vWidth = vHeight = 0;
|
||||
settings->DesktopPosX = maxWidth - 1;
|
||||
settings->DesktopPosY = maxHeight - 1;
|
||||
|
||||
for (i = 0; i < settings->MonitorCount; i++)
|
||||
{
|
||||
settings->DesktopPosX = MIN(settings->DesktopPosX, settings->MonitorDefArray[i].x);
|
||||
settings->DesktopPosY = MIN(settings->DesktopPosY, settings->MonitorDefArray[i].y);
|
||||
|
||||
vWidth += settings->MonitorDefArray[i].width;
|
||||
vHeight = MAX(vHeight, settings->MonitorDefArray[i].height);
|
||||
}
|
||||
|
||||
vscreen->area.left = 0;
|
||||
vscreen->area.right = vWidth - 1;
|
||||
vscreen->area.top = 0;
|
||||
vscreen->area.bottom = vHeight - 1;
|
||||
|
||||
if (settings->Workarea)
|
||||
{
|
||||
vscreen->area.top = xfc->workArea.y;
|
||||
vscreen->area.bottom = (vHeight - (vHeight - (xfc->workArea.height + xfc->workArea.y))) - 1;
|
||||
}
|
||||
|
||||
if (nmonitors && !primaryMonitor)
|
||||
settings->MonitorDefArray[0].is_primary = TRUE;
|
||||
|
||||
/* If we have specific monitor information */
|
||||
if (settings->MonitorCount)
|
||||
{
|
||||
/* Initialize bounding rectangle for all monitors */
|
||||
vWidth = settings->MonitorDefArray[0].width;
|
||||
vHeight = settings->MonitorDefArray[0].height;
|
||||
vX = settings->MonitorDefArray[0].x;
|
||||
vY = settings->MonitorDefArray[0].y;
|
||||
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = settings->MonitorDefArray[0].orig_screen;
|
||||
|
||||
/* Calculate bounding rectangle around all monitors to be used AND
|
||||
* also set the Xinerama indices which define left/top/right/bottom monitors.
|
||||
*/
|
||||
for (i = 1; i < settings->MonitorCount; i++)
|
||||
{
|
||||
/* does the same as gdk_rectangle_union */
|
||||
int destX = MIN(vX, settings->MonitorDefArray[i].x);
|
||||
int destY = MIN(vY, settings->MonitorDefArray[i].y);
|
||||
int destWidth = MAX(vX + vWidth, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width) - destX;
|
||||
int destHeight = MAX(vY + vHeight, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height) - destY;
|
||||
|
||||
if (vX != destX)
|
||||
xfc->fullscreenMonitors.left = settings->MonitorDefArray[i].orig_screen;
|
||||
if (vY != destY)
|
||||
xfc->fullscreenMonitors.top = settings->MonitorDefArray[i].orig_screen;
|
||||
if (vWidth != destWidth)
|
||||
xfc->fullscreenMonitors.right = settings->MonitorDefArray[i].orig_screen;
|
||||
if (vHeight != destHeight)
|
||||
xfc->fullscreenMonitors.bottom = settings->MonitorDefArray[i].orig_screen;
|
||||
|
||||
vX = destX;
|
||||
vY = destY;
|
||||
vWidth = destWidth;
|
||||
vHeight = destHeight;
|
||||
}
|
||||
|
||||
settings->DesktopPosX = vX;
|
||||
settings->DesktopPosY = vY;
|
||||
|
||||
vscreen->area.left = 0;
|
||||
vscreen->area.right = vWidth - 1;
|
||||
vscreen->area.top = 0;
|
||||
vscreen->area.bottom = vHeight - 1;
|
||||
|
||||
if (settings->Workarea)
|
||||
{
|
||||
vscreen->area.top = xfc->workArea.y;
|
||||
vscreen->area.bottom = (vHeight - (vHeight - (xfc->workArea.height + xfc->workArea.y))) - 1;
|
||||
}
|
||||
|
||||
/* If there are multiple monitors and we have not selected a primary */
|
||||
if (!primaryMonitorFound)
|
||||
{
|
||||
/* First lets try to see if there is a monitor with a 0,0 coordinate */
|
||||
for (i=0; i<settings->MonitorCount; i++)
|
||||
{
|
||||
if (!primaryMonitorFound && settings->MonitorDefArray[i].x == 0 && settings->MonitorDefArray[i].y == 0)
|
||||
{
|
||||
settings->MonitorDefArray[i].is_primary = TRUE;
|
||||
settings->MonitorLocalShiftX = settings->MonitorDefArray[i].x;
|
||||
settings->MonitorLocalShiftY = settings->MonitorDefArray[i].y;
|
||||
primaryMonitorFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we still do not have a primary monitor then just arbitrarily choose first monitor */
|
||||
if (!primaryMonitorFound)
|
||||
{
|
||||
settings->MonitorDefArray[0].is_primary = TRUE;
|
||||
settings->MonitorLocalShiftX = settings->MonitorDefArray[0].x;
|
||||
settings->MonitorLocalShiftY = settings->MonitorDefArray[0].y;
|
||||
primaryMonitorFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Subtract monitor shift from monitor variables for server-side use.
|
||||
* We maintain monitor shift value as Window requires the primary monitor to have a coordinate of 0,0
|
||||
* In some X configurations, no monitor may have a coordinate of 0,0. This can also be happen if the user
|
||||
* requests specific monitors from the command-line as well. So, we make sure to translate our primary monitor's
|
||||
* upper-left corner to 0,0 on the server.
|
||||
*/
|
||||
for (i=0; i < settings->MonitorCount; i++)
|
||||
{
|
||||
settings->MonitorDefArray[i].x = settings->MonitorDefArray[i].x - settings->MonitorLocalShiftX;
|
||||
settings->MonitorDefArray[i].y = settings->MonitorDefArray[i].y - settings->MonitorLocalShiftY;
|
||||
}
|
||||
|
||||
/* Set the desktop width and height according to the bounding rectangle around the active monitors */
|
||||
xfc->desktopWidth = vscreen->area.right - vscreen->area.left + 1;
|
||||
xfc->desktopHeight = vscreen->area.bottom - vscreen->area.top + 1;
|
||||
}
|
||||
|
@ -139,19 +139,57 @@ void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int n
|
||||
|
||||
void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
{
|
||||
if (fullscreen)
|
||||
int i;
|
||||
int startX = xfc->instance->settings->DesktopPosX;
|
||||
int startY = xfc->instance->settings->DesktopPosY;
|
||||
|
||||
window->decorations = xfc->decorations;
|
||||
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
|
||||
|
||||
/* Determine the x,y starting location for the fullscreen window */
|
||||
if (xfc->instance->settings->MonitorCount)
|
||||
{
|
||||
rdpSettings* settings = xfc->settings;
|
||||
/* Initialize startX and startY with reasonable values */
|
||||
startX = xfc->instance->settings->MonitorDefArray[0].x;
|
||||
startY = xfc->instance->settings->MonitorDefArray[0].y;
|
||||
|
||||
xf_SetWindowDecorations(xfc, window->handle, FALSE);
|
||||
/* Search all monitors to find the lowest startX and startY values */
|
||||
for (i=0; i < xfc->instance->settings->MonitorCount; i++)
|
||||
{
|
||||
startX = MIN(startX, xfc->instance->settings->MonitorDefArray[i].x);
|
||||
startY = MIN(startY, xfc->instance->settings->MonitorDefArray[i].y);
|
||||
}
|
||||
|
||||
XMoveResizeWindow(xfc->display, window->handle,
|
||||
settings->DesktopPosX, settings->DesktopPosY, window->width, window->height);
|
||||
|
||||
XMapRaised(xfc->display, window->handle);
|
||||
|
||||
window->fullscreen = TRUE;
|
||||
/* Lastly apply any monitor shift(translation from remote to local coordinate system)
|
||||
* to startX and startY values
|
||||
*/
|
||||
startX = startX + xfc->instance->settings->MonitorLocalShiftX;
|
||||
startY = startY + xfc->instance->settings->MonitorLocalShiftY;
|
||||
}
|
||||
|
||||
XMoveResizeWindow(xfc->display, window->handle, startX, startY, window->width, window->height);
|
||||
XMapRaised(xfc->display, window->handle);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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))
|
||||
{
|
||||
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5,
|
||||
xfc->fullscreenMonitors.top,
|
||||
xfc->fullscreenMonitors.bottom,
|
||||
xfc->fullscreenMonitors.left,
|
||||
xfc->fullscreenMonitors.right,
|
||||
1);
|
||||
}
|
||||
|
||||
window->fullscreen = TRUE;
|
||||
}
|
||||
|
||||
/* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */
|
||||
@ -283,7 +321,7 @@ static const char* get_shm_id()
|
||||
return shm_id;
|
||||
}
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height, BOOL decorations)
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height)
|
||||
{
|
||||
XEvent xevent;
|
||||
int input_mask;
|
||||
@ -303,7 +341,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
window->fullscreen = FALSE;
|
||||
window->decorations = decorations;
|
||||
window->decorations = xfc->decorations;
|
||||
window->is_mapped = FALSE;
|
||||
window->is_transient = FALSE;
|
||||
|
||||
@ -354,9 +392,15 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
}
|
||||
|
||||
xf_ResizeDesktopWindow(xfc, window, width, height);
|
||||
xf_SetWindowDecorations(xfc, window->handle, decorations);
|
||||
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
|
||||
xf_SetWindowPID(xfc, window->handle, 0);
|
||||
|
||||
/* Set the window hints to allow minimal resize, so fullscreen
|
||||
* changes can work in window managers that might disallow otherwise.
|
||||
* We will set back afterwards.
|
||||
*/
|
||||
xf_SetWindowSizeHints(xfc, window, TRUE, xfc->width, xfc->height);
|
||||
|
||||
input_mask =
|
||||
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
|
||||
VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
|
||||
@ -406,14 +450,20 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
}
|
||||
|
||||
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height)
|
||||
{
|
||||
xf_SetWindowSizeHints(xfc, window, FALSE, width, height);
|
||||
}
|
||||
|
||||
void xf_SetWindowSizeHints(xfContext* xfc, xfWindow *window, BOOL can_resize, int width, int height)
|
||||
{
|
||||
XSizeHints* size_hints;
|
||||
size_hints = XAllocSizeHints();
|
||||
|
||||
if (size_hints)
|
||||
{
|
||||
size_hints->flags = PMinSize | PMaxSize;
|
||||
size_hints->flags = PMinSize | PMaxSize | PWinGravity;
|
||||
|
||||
size_hints->win_gravity = NorthWestGravity;
|
||||
size_hints->min_width = size_hints->max_width = width;
|
||||
size_hints->min_height = size_hints->max_height = height;
|
||||
|
||||
@ -425,6 +475,17 @@ void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int hei
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allows the window to resize larger by 1 pixel - so we can
|
||||
* fullscreen the window with no worries about window manager disallowing based
|
||||
* on size parameters
|
||||
*/
|
||||
if (can_resize)
|
||||
{
|
||||
size_hints->width_inc = size_hints->height_inc = 1;
|
||||
size_hints->max_width = xfc->width + 1;
|
||||
size_hints->max_height = xfc->height + 1;
|
||||
}
|
||||
|
||||
XSetWMNormalHints(xfc->display, window->handle, size_hints);
|
||||
XResizeWindow(xfc->display, window->handle, width, height);
|
||||
XFree(size_hints);
|
||||
|
@ -46,6 +46,10 @@ typedef struct xf_window xfWindow;
|
||||
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
|
||||
#define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
|
||||
|
||||
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
||||
#define _NET_WM_STATE_ADD 1 /* add/set property */
|
||||
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
|
||||
|
||||
enum xf_localmove_state
|
||||
{
|
||||
LMS_NOT_ACTIVE,
|
||||
@ -143,8 +147,9 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen);
|
||||
void xf_SetWindowDecorations(xfContext* xfc, Window window, BOOL show);
|
||||
void xf_SetWindowUnlisted(xfContext* xfc, Window window);
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height, BOOL decorations);
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height);
|
||||
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height);
|
||||
void xf_SetWindowSizeHints(xfContext* xfc, xfWindow* window, BOOL can_resize, int width, int height);
|
||||
void xf_DestroyDesktopWindow(xfContext* xfc, xfWindow* window);
|
||||
|
||||
BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int length,
|
||||
|
@ -38,6 +38,15 @@ typedef struct xf_context xfContext;
|
||||
#include <freerdp/codec/progressive.h>
|
||||
#include <freerdp/codec/region.h>
|
||||
|
||||
struct xf_FullscreenMonitors
|
||||
{
|
||||
UINT32 top;
|
||||
UINT32 bottom;
|
||||
UINT32 left;
|
||||
UINT32 right;
|
||||
};
|
||||
typedef struct xf_FullscreenMonitors xfFullscreenMonitors;
|
||||
|
||||
struct xf_WorkArea
|
||||
{
|
||||
UINT32 x;
|
||||
@ -111,6 +120,7 @@ struct xf_context
|
||||
xfAppWindow* appWindow;
|
||||
xfPointer* pointer;
|
||||
xfWorkArea workArea;
|
||||
xfFullscreenMonitors fullscreenMonitors;
|
||||
int current_desktop;
|
||||
BOOL remote_app;
|
||||
BOOL disconnect;
|
||||
@ -181,6 +191,8 @@ struct xf_context
|
||||
Atom _NET_WM_STATE_SKIP_TASKBAR;
|
||||
Atom _NET_WM_STATE_SKIP_PAGER;
|
||||
|
||||
Atom _NET_WM_FULLSCREEN_MONITORS;
|
||||
|
||||
Atom _NET_WM_WINDOW_TYPE;
|
||||
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
||||
Atom _NET_WM_WINDOW_TYPE_DIALOG;
|
||||
|
@ -399,6 +399,7 @@ struct rdp_monitor
|
||||
INT32 width;
|
||||
INT32 height;
|
||||
UINT32 is_primary;
|
||||
UINT32 orig_screen;
|
||||
};
|
||||
typedef struct rdp_monitor rdpMonitor;
|
||||
|
||||
@ -897,7 +898,10 @@ struct rdp_settings
|
||||
ALIGN64 BOOL ListMonitors; /* 392 */
|
||||
ALIGN64 UINT32* MonitorIds; /* 393 */
|
||||
ALIGN64 UINT32 NumMonitorIds; /* 394 */
|
||||
UINT64 padding0448[448 - 395]; /* 395 */
|
||||
ALIGN64 UINT32 MonitorLocalShiftX; /*395 */
|
||||
ALIGN64 UINT32 MonitorLocalShiftY; /* 396 */
|
||||
UINT64 padding0448[448 - 397]; /* 397 */
|
||||
|
||||
|
||||
/* Client Message Channel Data */
|
||||
UINT64 padding0512[512 - 448]; /* 448 */
|
||||
|
@ -273,6 +273,8 @@ rdpSettings* freerdp_settings_new(DWORD flags)
|
||||
settings->MonitorCount = 0;
|
||||
settings->MonitorDefArraySize = 32;
|
||||
settings->MonitorDefArray = (rdpMonitor*) calloc(settings->MonitorDefArraySize, sizeof(rdpMonitor));
|
||||
settings->MonitorLocalShiftX = 0;
|
||||
settings->MonitorLocalShiftY = 0;
|
||||
|
||||
settings->MonitorIds = (UINT32*) calloc(16, sizeof(UINT32));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user