Unverified Commit 1ebf7851 authored by Mike Gabriel's avatar Mike Gabriel

Merge branch 'uli42-pr/fix_fullscreen' into 3.6.x

parents 5858ebc6 032ed351
...@@ -297,6 +297,35 @@ void nxagentSetPixmapFormats(ScreenInfo *screenInfo) ...@@ -297,6 +297,35 @@ 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) void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
{ {
XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow); XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);
...@@ -304,16 +333,20 @@ void nxagentMinimizeFromFullScreen(ScreenPtr pScreen) ...@@ -304,16 +333,20 @@ void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
if (nxagentIpaq) if (nxagentIpaq)
{ {
XMapWindow(nxagentDisplay, nxagentIconWindow); XMapWindow(nxagentDisplay, nxagentIconWindow);
XIconifyWindow(nxagentDisplay, nxagentIconWindow,
DefaultScreen(nxagentDisplay));
} }
else
{ XIconifyWindow(nxagentDisplay, nxagentIconWindow,
XIconifyWindow(nxagentDisplay, nxagentIconWindow,
DefaultScreen(nxagentDisplay)); 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) void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
{ {
if (nxagentIpaq) if (nxagentIpaq)
...@@ -327,36 +360,51 @@ void nxagentMaximizeToFullScreen(ScreenPtr pScreen) ...@@ -327,36 +360,51 @@ void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
/* /*
XUnmapWindow(nxagentDisplay, nxagentIconWindow); XUnmapWindow(nxagentDisplay, nxagentIconWindow);
*/ */
Window root = RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay));
/* /*
FIXME: We'll check for ReparentNotify and LeaveNotify events after XReparentWindow() FIXME: We'll check for ReparentNotify and LeaveNotify events after
in order to avoid the session window is iconified. XReparentWindow() in order to avoid the session window being
We could avoid the session window is iconified when a LeaveNotify event is received, iconified. We could avoid the session window being iconified
so this check would be unnecessary. when a LeaveNotify event is received, so this check would be
unnecessary.
*/ */
struct timeval timeout;
int i;
XEvent e;
XReparentWindow(nxagentDisplay, nxagentFullscreenWindow, /* only reparent if necessary. FIXME: also check if the desired coordinates match */
RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)), 0, 0);
for (i = 0; i < 100 && nxagentWMIsRunning; i++) if (!nxagentIsParentOf(nxagentDisplay, root, nxagentFullscreenWindow))
{ {
#ifdef TEST XReparentWindow(nxagentDisplay, nxagentFullscreenWindow,
fprintf(stderr, "nxagentMaximizeToFullscreen: WARNING! Going to wait for the ReparentNotify event.\n"); root, 0, 0);
#endif
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; if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
timeout.tv_usec = 50 * 1000; {
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); XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
...@@ -364,7 +412,19 @@ FIXME: We'll check for ReparentNotify and LeaveNotify events after XReparentWind ...@@ -364,7 +412,19 @@ FIXME: We'll check for ReparentNotify and LeaveNotify events after XReparentWind
XIconifyWindow(nxagentDisplay, nxagentIconWindow, XIconifyWindow(nxagentDisplay, nxagentIconWindow,
DefaultScreen(nxagentDisplay)); 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); XMapWindow(nxagentDisplay, nxagentIconWindow);
*/ */
...@@ -1982,7 +2042,7 @@ N/A ...@@ -1982,7 +2042,7 @@ N/A
} }
else else
{ {
nxagentIconWindow = 0; nxagentIconWindow = None;
} }
/* /*
......
...@@ -831,6 +831,11 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn) ...@@ -831,6 +831,11 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
} }
w = nxagentDefaultWindows[pScreen -> myNum]; w = nxagentDefaultWindows[pScreen -> myNum];
/*
* override_redirect makes the window manager ignore the window and
* not add decorations, see ICCCM)
*/
attributes.override_redirect = switchOn; attributes.override_redirect = switchOn;
valuemask = CWOverrideRedirect; valuemask = CWOverrideRedirect;
XUnmapWindow(nxagentDisplay, w); XUnmapWindow(nxagentDisplay, w);
...@@ -1003,14 +1008,28 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn) ...@@ -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(X, nxagentOption(SavedX) - nxagentOption(WMBorderWidth));
nxagentChangeOption(Y, nxagentOption(SavedY) - nxagentOption(WMTitleHeight));
} }
else else
{ {
nxagentChangeOption(X, nxagentOption(SavedX)); nxagentChangeOption(X, nxagentOption(SavedX));
}
if (nxagentOption(WMTitleHeight) > 0)
{
nxagentChangeOption(Y, nxagentOption(SavedY) - nxagentOption(WMTitleHeight));
}
else
{
nxagentChangeOption(Y, nxagentOption(SavedY)); nxagentChangeOption(Y, nxagentOption(SavedY));
} }
...@@ -2635,7 +2654,7 @@ void nxagentMapDefaultWindows(void) ...@@ -2635,7 +2654,7 @@ void nxagentMapDefaultWindows(void)
* Map the icon window. * Map the icon window.
*/ */
if (nxagentIconWindow != 0) if (nxagentIconWindow != None)
{ {
#ifdef TEST #ifdef TEST
fprintf(stderr, "nxagentMapDefaultWindows: Mapping icon window id [%ld].\n", fprintf(stderr, "nxagentMapDefaultWindows: Mapping icon window id [%ld].\n",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment