From ca54fabed8e0f531b9a22691d8db1c323475107a Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Wed, 26 Jun 2019 18:49:13 +0200 Subject: Window.c: add some comments about fullscreen handling --- nx-X11/programs/Xserver/hw/nxagent/Window.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c index 78a5081f0..ec62bdd9d 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Window.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c @@ -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); @@ -1003,6 +1008,13 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn) } } + /* + * 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 && nxagentOption(WMTitleHeight) > 0) { nxagentChangeOption(X, nxagentOption(SavedX) - nxagentOption(WMBorderWidth)); -- cgit v1.2.3 From c190fd1871d00168e2db6df9b91e8bc1ef69fbf5 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Wed, 26 Jun 2019 18:49:36 +0200 Subject: Window.c: rearrange code regarding window decorations sizes --- nx-X11/programs/Xserver/hw/nxagent/Window.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c index ec62bdd9d..3e27ae566 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Window.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c @@ -1015,14 +1015,21 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn) * from the window manager via _NET_REQUEST_FRAME_EXTENTS */ - if (nxagentOption(WMBorderWidth) > 0 && nxagentOption(WMTitleHeight) > 0) + 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)); } -- cgit v1.2.3 From d32706888f83b91d6feab93067d1207c507335fa Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Wed, 26 Jun 2019 18:50:44 +0200 Subject: Screen.c: add nxagentIsParentOf helper --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 6ec4b245f..4e466b502 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -297,6 +297,28 @@ void nxagentSetPixmapFormats(ScreenInfo *screenInfo) } } +/* check if possible_parent is parent of candidate */ +Bool nxagentIsParentOf(Display *d, Window possible_parent, Window candidate) +{ + Window 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; + } +} + void nxagentMinimizeFromFullScreen(ScreenPtr pScreen) { XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow); -- cgit v1.2.3 From 6657b8cc8c8702527c9e66aaf7d999fe9240f5c3 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Wed, 26 Jun 2019 19:04:41 +0200 Subject: nxagentMaximizeToFullScreen: only reparent if necessary This fixes problems with kwin and compiz when using the switch-all-screens keystroke. The fullscreen would appear shortly and then vanish again. Fixes ArcticaProject/nx-libs#458 --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 77 +++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 21 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 4e466b502..ebc5d6ce9 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -336,6 +336,14 @@ void nxagentMinimizeFromFullScreen(ScreenPtr pScreen) } } +/* + * 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) @@ -349,36 +357,51 @@ 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; + + #ifdef TEST + fprintf(stderr, "nxagentMaximizeToFullscreen: WARNING! Going to wait for the ReparentNotify event [%d].\n", i); + #endif - XSync(nxagentDisplay, 0); + if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e)) + { + break; + } - timeout.tv_sec = 0; - timeout.tv_usec = 50 * 1000; + XSync(nxagentDisplay, 0); - nxagentWaitEvents(nxagentDisplay, &timeout); + 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); @@ -386,7 +409,19 @@ FIXME: We'll check for ReparentNotify and LeaveNotify events after XReparentWind 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); */ -- cgit v1.2.3 From ea571387b2bed7738eb686a806b1416f239b556b Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 27 Jun 2019 19:51:03 +0200 Subject: Screen.c: simplify nxagentMinimizeFromFullscreen --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index ebc5d6ce9..54aa8f4e0 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -319,6 +319,13 @@ Bool nxagentIsParentOf(Display *d, Window possible_parent, Window candidate) } } +/* + * 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); @@ -326,14 +333,10 @@ void nxagentMinimizeFromFullScreen(ScreenPtr pScreen) if (nxagentIpaq) { XMapWindow(nxagentDisplay, nxagentIconWindow); - XIconifyWindow(nxagentDisplay, nxagentIconWindow, - DefaultScreen(nxagentDisplay)); } - else - { - XIconifyWindow(nxagentDisplay, nxagentIconWindow, + + XIconifyWindow(nxagentDisplay, nxagentIconWindow, DefaultScreen(nxagentDisplay)); - } } /* -- cgit v1.2.3 From d487d5879d10211c5aa536b84073cdf9c64c2fed Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 27 Jun 2019 20:15:15 +0200 Subject: Consistently use None instead of 0 for nxagentIconWindow everywhere --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Window.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 54aa8f4e0..111fd96d4 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -2042,7 +2042,7 @@ N/A } else { - nxagentIconWindow = 0; + nxagentIconWindow = None; } /* diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c index 3e27ae566..0e5def294 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Window.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c @@ -2654,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", -- cgit v1.2.3 From 032ed3511bd6d2ef78c75e9296586ad5d469c0f1 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 27 Jun 2019 20:38:10 +0200 Subject: Screen.c: use XlibWindow so silence the compiler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a bit weird, I'd expect far more places where the compiler could complain about Window vs Window64... But it does not. Screen.c:306:32: warning: passing argument 3 of ‘XQueryTree’ from incompatible pointer type [-Wincompatible-pointer-types] if (XQueryTree(d, candidate, &root, &parent, &children, &num_children)) ^~~~~ In file included from Screen.c:60: Agent.h:85:25: note: expected ‘Window64 *’ {aka ‘long unsigned int *’} but argument is of type ‘Window *’ {aka ‘unsigned int *’} #define Window Window64 ../../../../exports/include/nx-X11/Xlib.h:3041:5: note: in expansion of macro ‘Window’ Window* /* root_return */, --- nx-X11/programs/Xserver/hw/nxagent/Screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c index 111fd96d4..44c89e03f 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c @@ -298,9 +298,9 @@ void nxagentSetPixmapFormats(ScreenInfo *screenInfo) } /* check if possible_parent is parent of candidate */ -Bool nxagentIsParentOf(Display *d, Window possible_parent, Window candidate) +Bool nxagentIsParentOf(Display *d, XlibWindow possible_parent, XlibWindow candidate) { - Window parent, root, *children = NULL; + XlibWindow parent, root, *children = NULL; unsigned int num_children; if (XQueryTree(d, candidate, &root, &parent, &children, &num_children)) -- cgit v1.2.3