Skip to content

Commit

Permalink
Merge branch 'uli42-pr/fix_fullscreen' into 3.6.x
Browse files Browse the repository at this point in the history
  • Loading branch information
sunweaver committed Jun 27, 2019
2 parents 5858ebc + 032ed35 commit 1ebf785
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 31 deletions.
116 changes: 88 additions & 28 deletions nx-X11/programs/Xserver/hw/nxagent/Screen.c
Expand Up @@ -297,23 +297,56 @@ void nxagentSetPixmapFormats(ScreenInfo *screenInfo)
}
}

/* check if possible_parent is parent of candidate */
Bool nxagentIsParentOf(Display *d, XlibWindow possible_parent, XlibWindow candidate)
{
XlibWindow parent, root, *children = NULL;
unsigned int num_children;

if (XQueryTree(d, candidate, &root, &parent, &children, &num_children))
{
if (children)
XFree((char *)children);

#ifdef TEST
fprintf(stderr, "%s: parent of full screen window [%p] root [%p] possible_parent [%p] candidate [%p]\n", __func__, parent, root, possible_parent, candidate);
#endif
return (parent == possible_parent);
}
else
{
return False;
}
}

/*
* Pressing the minimize keystroke while in fullscreen mode will call
* this function. It will unmap the fullscreen window and iconify the
* previously created icon window immediately. The window manager may
* decide how to show an iconified window. kwin e.g. shows it in the
* task bar.
*/
void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
{
XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);

if (nxagentIpaq)
{
XMapWindow(nxagentDisplay, nxagentIconWindow);
XIconifyWindow(nxagentDisplay, nxagentIconWindow,
DefaultScreen(nxagentDisplay));
}
else
{
XIconifyWindow(nxagentDisplay, nxagentIconWindow,

XIconifyWindow(nxagentDisplay, nxagentIconWindow,
DefaultScreen(nxagentDisplay));
}
}

/*
* This is the opposite function to nxagentMinimizeFromFullscreen. It
* will map the fullscreen window and unmap the icon window. It is
* only called if fullscreen mode was active when the minimize
* keystroke was pressed.
* Some window managers tend to do 'interesting' things with the
* icon window, which we try to counterfeit here.
*/
void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
{
if (nxagentIpaq)
Expand All @@ -327,44 +360,71 @@ void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
/*
XUnmapWindow(nxagentDisplay, nxagentIconWindow);
*/

Window root = RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay));

/*
FIXME: We'll check for ReparentNotify and LeaveNotify events after XReparentWindow()
in order to avoid the session window is iconified.
We could avoid the session window is iconified when a LeaveNotify event is received,
so this check would be unnecessary.
FIXME: We'll check for ReparentNotify and LeaveNotify events after
XReparentWindow() in order to avoid the session window being
iconified. We could avoid the session window being iconified
when a LeaveNotify event is received, so this check would be
unnecessary.
*/
struct timeval timeout;
int i;
XEvent e;

XReparentWindow(nxagentDisplay, nxagentFullscreenWindow,
RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)), 0, 0);
/* only reparent if necessary. FIXME: also check if the desired coordinates match */

for (i = 0; i < 100 && nxagentWMIsRunning; i++)
if (!nxagentIsParentOf(nxagentDisplay, root, nxagentFullscreenWindow))
{
#ifdef TEST
fprintf(stderr, "nxagentMaximizeToFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
#endif
XReparentWindow(nxagentDisplay, nxagentFullscreenWindow,
root, 0, 0);

if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
for (int i = 0; i < 100 && nxagentWMIsRunning; i++)
{
break;
}
struct timeval timeout;
XEvent e;

XSync(nxagentDisplay, 0);
#ifdef TEST
fprintf(stderr, "nxagentMaximizeToFullscreen: WARNING! Going to wait for the ReparentNotify event [%d].\n", i);
#endif

timeout.tv_sec = 0;
timeout.tv_usec = 50 * 1000;
if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
{
break;
}

nxagentWaitEvents(nxagentDisplay, &timeout);
XSync(nxagentDisplay, 0);

timeout.tv_sec = 0;
timeout.tv_usec = 50 * 1000;

nxagentWaitEvents(nxagentDisplay, &timeout);
}
}
else
{
#ifdef TEST
fprintf(stderr, "%s: FullscreenWindow already is child of root window - skipping reparenting,\n", __func__);
#endif
}

XMapRaised(nxagentDisplay, nxagentFullscreenWindow);

XIconifyWindow(nxagentDisplay, nxagentIconWindow,
DefaultScreen(nxagentDisplay));

while (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, LeaveNotify, &e));
/* swallow all LeaveNotify events for the FullscreenWindow;
Normally this does not swallow anything these days, but when
using fvwm you see one of these events here. */
while (1)
{
XEvent e;
if (!XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, LeaveNotify, &e))
break;
#ifdef TEST
fprintf(stderr, "%d: swallowing LeaveNotify event\m", __func__);
#endif
}

/*
XMapWindow(nxagentDisplay, nxagentIconWindow);
*/
Expand Down Expand Up @@ -1982,7 +2042,7 @@ N/A
}
else
{
nxagentIconWindow = 0;
nxagentIconWindow = None;
}

/*
Expand Down
25 changes: 22 additions & 3 deletions nx-X11/programs/Xserver/hw/nxagent/Window.c
Expand Up @@ -831,6 +831,11 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
}

w = nxagentDefaultWindows[pScreen -> myNum];

/*
* override_redirect makes the window manager ignore the window and
* not add decorations, see ICCCM)
*/
attributes.override_redirect = switchOn;
valuemask = CWOverrideRedirect;
XUnmapWindow(nxagentDisplay, w);
Expand Down Expand Up @@ -1003,14 +1008,28 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
}
}

if (nxagentOption(WMBorderWidth) > 0 && nxagentOption(WMTitleHeight) > 0)
/*
* FIXME: These are 0 most of the time nowadays. The effect is,
* that the window is moving a bit to right/bottom every time
* fullscreen mode is left. To fix this query the frame extents
* from the window manager via _NET_REQUEST_FRAME_EXTENTS
*/

if (nxagentOption(WMBorderWidth) > 0)
{
nxagentChangeOption(X, nxagentOption(SavedX) - nxagentOption(WMBorderWidth));
nxagentChangeOption(Y, nxagentOption(SavedY) - nxagentOption(WMTitleHeight));
}
else
{
nxagentChangeOption(X, nxagentOption(SavedX));
}

if (nxagentOption(WMTitleHeight) > 0)
{
nxagentChangeOption(Y, nxagentOption(SavedY) - nxagentOption(WMTitleHeight));
}
else
{
nxagentChangeOption(Y, nxagentOption(SavedY));
}

Expand Down Expand Up @@ -2635,7 +2654,7 @@ void nxagentMapDefaultWindows(void)
* Map the icon window.
*/

if (nxagentIconWindow != 0)
if (nxagentIconWindow != None)
{
#ifdef TEST
fprintf(stderr, "nxagentMapDefaultWindows: Mapping icon window id [%ld].\n",
Expand Down

0 comments on commit 1ebf785

Please sign in to comment.