From 930e59dd3142a4ceba46826183e13d67b420e3de Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Fri, 26 Oct 2012 11:40:55 -0700 Subject: [PATCH] Partially support _NET_WM_STRUT_PARTIAL. Window Maker already supports the _NET_WM_STRUT property as described in the EWMH spec. We respect client-provided struts and avoid placing or maximizing windows over those areas. An example is that we don't try to place or maximize windows where they would be obscured by an always-on-top gnome-panel. _NET_WM_STRUT is now deprecated and redefined as a special case of _NET_WM_STRUT_PARTIAL, which allows variable strut widths. A panel at the bottom of the screen, for example, does not have to reserve the whole width as a strut if it does not fill 100% of the screen width. By default the XFCE bottom panel does not extend the whole width of the screen, for instance. Our method for restricting parts of the screen from placement doesn't have a way to account for struts which are not 100% tall or 100% wide, so until now we have ignored partial struts. In the case of the XFCE panel mentioned above, the result is that a window may maximize underneath the panel and be obscured. As a partial hackaround we now query windows for _NET_WM_STRUT_PARTIAL but throw away the start and end co-ordinates, assuming instead that the struts are full-width/full-height. This trades off a small amount of wasted placement space to avoid the case where windows can be partially obscured by panels, which can be particularly annoying if the panel is at the top and the victim's titlebar becomes hidden. --- src/wmspec.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/wmspec.c b/src/wmspec.c index 1e700897..4ca8af47 100644 --- a/src/wmspec.c +++ b/src/wmspec.c @@ -859,10 +859,20 @@ static Bool updateStrut(WWindow *wwin, Bool adding) unsigned long nitems_ret, bytes_after_ret; long *data = NULL; - if (XGetWindowProperty(dpy, wwin->client_win, net_wm_strut, 0, 4, False, + if ((XGetWindowProperty(dpy, wwin->client_win, net_wm_strut, 0, 4, False, XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret, - &bytes_after_ret, (unsigned char **)&data) == Success && data) { - + &bytes_after_ret, (unsigned char **)&data) == Success && data) || + ((XGetWindowProperty(dpy, wwin->client_win, net_wm_strut_partial, 0, 12, False, + XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret, + &bytes_after_ret, (unsigned char **)&data) == Success && data))) { + + /* XXX: This is strictly incorrect in the case of net_wm_strut_partial... + * Discard the start and end properties from the partial strut and treat it as + * a (deprecated) strut. + * This means we are marking the whole width or height of the screen as + * reserved, which is not necessarily what the strut defines. However for the + * purposes of determining placement or maximization it's probably good enough. + */ area = (WReservedArea *) wmalloc(sizeof(WReservedArea)); area->area.x1 = data[0]; area->area.x2 = data[1]; @@ -1448,7 +1458,7 @@ void wNETWMCheckClientHintChange(WWindow *wwin, XPropertyEvent *event) wmessage("clientHintChange type %s\n", XGetAtomName(dpy, event->atom)); #endif - if (event->atom == net_wm_strut) { + if (event->atom == net_wm_strut || event->atom == net_wm_strut_partial) { updateStrut(wwin, False); updateStrut(wwin, True); wScreenUpdateUsableArea(wwin->screen_ptr); -- 2.11.4.GIT