mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
X11: Fix fullscreen toggle
1. Fix fullscreen toggle for window managers that do not have multimonitor fullscreen extension support 2. Fix current monitor detection 3. Fix calculation of vscreen boundaries when single monitor is being used 4. Fix start up position of window when starting (used to always go to the top left corener, now centered) Still a problem: 1. Window decorations do not show when going windowed 2. Smart resizing makes i3 really sad :( 3. Moving window across monitors and going fullscreen always maximizes on startup screen (when not using /multimon)
This commit is contained in:
@@ -707,6 +707,16 @@ void xf_toggle_fullscreen(xfContext* xfc)
|
||||
WindowStateChangeEventArgs e;
|
||||
rdpContext* context = (rdpContext*) xfc;
|
||||
rdpSettings* settings = context->settings;
|
||||
|
||||
/*
|
||||
when debugging, ungrab keyboard when toggling fullscreen
|
||||
to allow keyboard usage on the debugger
|
||||
*/
|
||||
if (xfc->debug)
|
||||
{
|
||||
XUngrabKeyboard(xfc->display, CurrentTime);
|
||||
}
|
||||
|
||||
xfc->fullscreen = (xfc->fullscreen) ? FALSE : TRUE;
|
||||
xfc->decorations = (xfc->fullscreen) ? FALSE : settings->Decorations;
|
||||
xf_SetWindowFullscreen(xfc, xfc->window, xfc->fullscreen);
|
||||
@@ -1794,7 +1804,8 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
xf_PanningChangeEventHandler);
|
||||
#endif
|
||||
xfc->UseXThreads = TRUE;
|
||||
//xfc->debug = TRUE;
|
||||
/* uncomment below if debugging to prevent keyboard grap */
|
||||
/* xfc->debug = TRUE; */
|
||||
|
||||
if (xfc->UseXThreads)
|
||||
{
|
||||
|
||||
@@ -146,6 +146,7 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
Window _dummy_w;
|
||||
int current_monitor = 0;
|
||||
Screen* screen;
|
||||
MONITOR_INFO* monitor;
|
||||
#if defined WITH_XINERAMA || defined WITH_XRANDR
|
||||
int major, minor;
|
||||
#endif
|
||||
@@ -208,13 +209,6 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
vscreen->monitors[i].area.top = screenInfo[i].y_org;
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,6 +219,46 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0;
|
||||
|
||||
/* Determine which monitor that the mouse cursor is on */
|
||||
if (vscreen->monitors)
|
||||
{
|
||||
for (i = 0; i < vscreen->nmonitors; i++)
|
||||
{
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Even for a single monitor, we need to calculate the virtual screen to support
|
||||
window managers that do not implement all X window state hints.
|
||||
|
||||
If the user did not request multiple monitor or is using workarea
|
||||
without remote app, we force the number of monitors be 1 so later
|
||||
the rest of the client don't end up using more monitors than the user desires.
|
||||
*/
|
||||
if ((!settings->UseMultimon && !settings->SpanMonitors) ||
|
||||
(settings->Workarea && !settings->RemoteApplicationMode))
|
||||
{
|
||||
/* If no monitors were specified on the command-line then set the current monitor as active */
|
||||
if (!settings->NumMonitorIds)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@@ -232,10 +266,26 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
*/
|
||||
if (settings->RemoteApplicationMode || !xf_GetWorkArea(xfc))
|
||||
{
|
||||
xfc->workArea.x = 0;
|
||||
xfc->workArea.y = 0;
|
||||
xfc->workArea.width = WidthOfScreen(xfc->screen);
|
||||
xfc->workArea.height = HeightOfScreen(xfc->screen);
|
||||
/*
|
||||
if only 1 monitor is enabled, use monitor area
|
||||
this is required in case of a screen composed of more than one monitor
|
||||
but user did not enable multimonitor
|
||||
*/
|
||||
if (settings->NumMonitorIds == 1)
|
||||
{
|
||||
monitor = vscreen->monitors + current_monitor;
|
||||
xfc->workArea.x = monitor->area.left;
|
||||
xfc->workArea.y = monitor->area.top;
|
||||
xfc->workArea.width = monitor->area.right - monitor->area.left + 1;
|
||||
xfc->workArea.height = monitor->area.bottom - monitor->area.top + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xfc->workArea.x = 0;
|
||||
xfc->workArea.y = 0;
|
||||
xfc->workArea.width = WidthOfScreen(xfc->screen);
|
||||
xfc->workArea.height = HeightOfScreen(xfc->screen);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->Fullscreen)
|
||||
@@ -288,26 +338,6 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
*pMaxHeight = settings->DesktopHeight;
|
||||
}
|
||||
|
||||
if (!settings->Fullscreen && !settings->Workarea && !settings->UseMultimon)
|
||||
goto out;
|
||||
|
||||
/* If single monitor fullscreen OR workarea without remote app */
|
||||
if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) ||
|
||||
(settings->Workarea && !settings->RemoteApplicationMode))
|
||||
{
|
||||
/* If no monitors were specified on the command-line then set the current monitor as active */
|
||||
if (!settings->NumMonitorIds)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* Create array of all active monitors by taking into account monitors requested on the command-line */
|
||||
for (i = 0; i < vscreen->nmonitors; i++)
|
||||
{
|
||||
@@ -406,8 +436,6 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
vB = destB;
|
||||
}
|
||||
|
||||
settings->DesktopPosX = vX;
|
||||
settings->DesktopPosY = vY;
|
||||
vscreen->area.left = 0;
|
||||
vscreen->area.right = vR - vX - 1;
|
||||
vscreen->area.top = 0;
|
||||
@@ -489,7 +517,6 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
if (settings->MonitorCount)
|
||||
settings->SupportMonitorLayoutPdu = TRUE;
|
||||
|
||||
out:
|
||||
#ifdef USABLE_XRANDR
|
||||
|
||||
if (rrmonitors)
|
||||
|
||||
@@ -153,8 +153,11 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
int startX, startY;
|
||||
UINT32 width = window->width;
|
||||
UINT32 height = window->height;
|
||||
/* xfc->decorations is set by caller depending on settings and whether it is fullscreen or not */
|
||||
window->decorations = xfc->decorations;
|
||||
/* show/hide decorations (e.g. title bar) as guided by xfc->decorations */
|
||||
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
|
||||
DEBUG_X11(TAG, "X window decoration set to %d", (int)window->decorations);
|
||||
|
||||
if (fullscreen)
|
||||
{
|
||||
@@ -194,7 +197,12 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
startY += xfc->context.settings->MonitorLocalShiftY;
|
||||
}
|
||||
|
||||
if (xfc->_NET_WM_FULLSCREEN_MONITORS != None)
|
||||
/*
|
||||
It is safe to proceed with simply toogling _NET_WM_STATE_FULLSCREEN window state on the following conditions:
|
||||
- The window manager supports multiple monitor full screen
|
||||
- The user requested to use a single monitor to render the remote desktop
|
||||
*/
|
||||
if (xfc->_NET_WM_FULLSCREEN_MONITORS != None || settings->MonitorCount == 1)
|
||||
{
|
||||
xf_ResizeDesktopWindow(xfc, window, width, height);
|
||||
|
||||
@@ -286,6 +294,7 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
|
||||
width = xfc->vscreen.area.right - xfc->vscreen.area.left + 1;
|
||||
height = xfc->vscreen.area.bottom - xfc->vscreen.area.top + 1;
|
||||
DEBUG_X11("X window move and resize %dx%d@%dx%d", startX, startY, width, height);
|
||||
xf_ResizeDesktopWindow(xfc, window, width, height);
|
||||
XMoveWindow(xfc->display, window->handle, startX, startY);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user