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.
After we exit there are no window decorations therefore frame extents
are meaningless.
We could be left with parts of the window being the wrong opacity if the
property is left intact and a compositing manager configured to draw
decorations with a different opacity to the rest of the window is still
running.
Remove the _NET_FRAME_EXTENTS property from all windows when we shut
down to prevent windows from being drawn incorrectly after we're gone.
Using window-supplied depth, visual and colormap information has the
side effect of causing window borders to be draw using inconsistent
colormap entries. Allocate entries from each window's colormap when
drawing its border.
Force setting the border when the window is first created so it's
guaranteed to be drawn in a consistent state.
Recalculate frame extents when the titlebar, resize bar or border are
enabled/disabled.
Account for border when calculating top and bottom frame extents.
Quoth I,
> I've just seen that _NET_FRAME_EXTENTS isn't updated when
> disabling or enabling the titlebar, resizebar and border of a window,
> so that needs to be fixed.
The attached patch fixes _NET_FRAME_EXTENTS not updating when using
the inspector to disable or enable the titlebar, resizebar or border.
It also fixes not taking the border width into account when
calculating the top and bottom extents.
With the patch the window's border is drawn for 32bpp urxvt windows
with compton. The border still isn't black, however. That's because
the border is taken from the screen's colormap rather than the
window's. I'll have a fix for that soon.
Accept windows' depth, visual and colormap instead of always using those
of the root window. Internal windows such as menus behave as before.
In conjunction with a compositing manager on a display supporting the
RENDER extension windows can now manage their own opacity.
I wrote the patch after reading the FAQ for urxvt, which says,
regarding transparency support:
"3. Use an ARGB visual:
urxvt -depth 32 -fg grey90 -bg rgba:0000/0000/4444/cccc
This requires XFT support, and the support of your X-server. If that
doesn't work for you, blame Xorg and Keith Packard. ARGB visuals
aren't there yet, no matter what they claim. Rxvt-Unicode contains the
necessary bugfixes and workarounds for Xft and Xlib to make it work,
but that doesn't mean that your WM has the required kludges in place."
In conjunction with a compositing manager (I tested compton) it does
work and urxvt draws a semi-transparent background with fully opaque
foreground text and scrollbars; much prettier than applying a blanket
transparency value over the whole window with the compositing manager.
Other application windows I tested were, as expected, drawn the same
as before.
I verified that urxvt is drawn in the same way when using xfwm4
(with builtin compositing). Since Window Maker doesn't (at time of
writing) have its own compositing manager I should clarify that one is
required to see any benefit from this patch.
Whether or not this feature is useful for any application other than
urxvt I don't know, though I assume that an application which chose an
ARGB visual in the same way would be able to draw itself prettily.
On a display without RENDER things work just as they do without the
patch. I have, however, only been able to test on a fairly standard
TrueColor display supporting multiple colour depths with 24bpp being
the default. Testing with more ... exotic ... display types would
probably be advisable.
This patch adds support for the _NET_FRAME_EXTENTS property as
described in the EWMH spec. With it I was able to use the compton
compositing manager to draw fully opaque windows with semi-transparent
titlebars and resizebars.
Set the _NET_FRAME_EXTENTS property based on border widths and
titlebar/resizebar heights.
The EWMH spec says:
"_NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32
The Window Manager MUST set _NET_FRAME_EXTENTS to the extents of the
window's frame. left, right, top and bottom are widths of the
respective borders added by the Window Manager."
Update the saved X co-ordinate of a window which was moved when
maximized (only) vertically so that unmaximizing the window restores
its dimensions without warping it back to its previous X position.
Similarly update the saved Y co-ordinate of a window which was
moved when maximized (only) horizontally.
Handle Maximus as a special case. We remember the Maximusized X and Y
co-ordinates then adjust the restored co-ordinates relative to the
delta between the window's position just after Maximusizing and its
position just before restoring. So for example if a window is
Maximusized, moved 100 pixels to the left and restored, it will end
up 100 pixels left of its original geometry.
Also fix "jumping window" bug reported by Christian Wittmer:
This "jumping window" happens only when you
1) open new xterm (STRG +n)
2) current position is (+64, +0)
3) maximize window vertically
4) undo maximizing
5) move window to the right or left (up or down as you like)
I moved right to (+450, +0)
6) maximize vertically again
7) and undo maximizing
8) window jumps back to (+64, ..) position
If you move a new opened window to a new position (e.g. +200, +200)
and then start with "3)". window is jumping back "+200, +200"
Fons Adriaensen reported that:
> WM's 'unshade' seems to use multiple Expose events [...] even when
> all animations and 'superfluous effects' are disabled.
Typo in shade_animate() could cause windows to be animated when the
no_animations preference was set. With this patch I see fewer
XMoveWindow() calls and quicker shading.
readMenuPipe() was calling freeline() on stuff which might be uninitialised, causing
a crash if no valid input was read.
readMenuPipe() was trying to snprintf() on an uninitialised pointer. We now use a
fixed-length buffer like the other readMenu*() functions.
Various memory leaks in readMenu*() functions have been fixed. There
are still some lurking around but most have been removed.
The original report from Charles Philip Chan <cpchan@bell.net> on 22 May 2012 says
that:
"Window Maker crashes when I try to open a sub-menu auto-generated by using:
xdg_menu --format WindowMaker --charset UTF-8"
There was also a report from Amadeusz Sławiński <amade@asmblr.net> on 24 May 2012
stating that wmaker crashes using:
% cat test.sh
cat << EOF
Test MENU
stuff EXEC true
Test END
EOF
% grep test GNUstep/Defaults/WMRootMenu
("Generated Submenu", OPEN_MENU, "|| /home/amade/test.sh")
Error is:
wmaker(MonitorLoop(monitor.c:134)): warning: Window Maker exited due to a crash (signal 11) and will be restarted.
Avoid some pitfalls with window maximization and make it behave more
intuitively. We now treat a window's vertical and horizontal
maximization as separate properties and only remember its original
geometry in a particular direction when it actually changes. We also
deliberately do not remember a window's geometry when it changes from
one maximized state to another. As a result windows can be more
reliably restored to their original size.
For example the "Maximize active window" hotkey followed by the
"Maximize active window vertically" hotkey will now result in the window
being maximized horizontally only, whereas previously the second hotkey
would have no effect because the window was already maximized
vertically. In addition selecting the Unmaximize window menu in the
same example will now result in the window being restored to its
original size. Previously the unmaximize attempt would have no effect
because the vertical maximization would have remembered the window's
"original" geometry when it was fully maximized.
Maximus is handled separately. The "Maximus" hotkey will now toggle
Maximus mode regardless of the window's current maximization state. For
example if two unmaximized windows are on screen and one is Maximusized
it will fill the space left by the second window, as before. But if the
first window is maximized and the "Maximus" hotkey is pressed the window
will now fill the same space as if it were Maximusized from its original
size. Previously the window would not change size from its fully
maximized state because the Maximus algorithm would consider
fully-maximized to be a valid Maximus size.
Use the gcc-specific noreturn attribute to advise the compiler that
Exit() doesn't return. This is safe because we already use preprocessor
rules to hide __attribute__ from other compilers.
Suggested independently by Christophe Curis and Brad Jorsch.
main.c: In function ‘RelaunchWindow’:
main.c:461:1: warning: control reaches end of non-void function
[-Wreturn-type]
Actually we can't reach the end of the function because the three
possible cases are Exit(-1), return False and return True. Of course if
Exit() were ever changed the above statement might become incorrect.
Some compiler food silences the warning.
Zoltan Balaton points out that Control + Doubleclick on docked app will
launch a new instance. For consistency with that behaviour we now allow
Control + Doubleclick on an undocked appicon to invoke the new
relaunching functionality.
We also now restrict doubleclick handling to the left mouse button in
order to avoid relaunching the application twice when the middle button
is used.
Use the WindowRelaunchKey shortcut to examine the WM_COMMAND property of
the active application's main window and launch a new instance of the
application using the retrieved command line.
Icons in the switchpanel are constrained to the value of the IconSize
preference but the grid in which they are arranged is fixed at 64 pixels.
If IconSize is less than 64x64 the panel will show smaller icons with a
wide spacing, which looks pretty stupid.
Fix it by forcing the switchpanel to attempt to load images at the size
it's going to use. The icon it actually gets may of course still be
smaller.
Replace the ARROWLESS_KBD #define with the ViKeyMenus preference.
When ViKeyMenus is TRUE, users can type h/j/k/l to scroll around menus.
Since ARROWLESS_KBD was previously undefined by default, ViKeyMenus is
FALSE by default.
Use height and width increment when wheel resizing if size hints are
set on a window and meaningful height and width increments are
specified.
Windows which don't care about their resize increments will have height
and width increments set to 1. For these windows - and windows without
resize hints at all - use the setting configured with ResizeIncrement.
For those not familiar with the way Macs cycle windows, the Command-Tab
sequence (Alt-Tab elsewhere) switches between DIFFERENT application windows
and Command-Grave (key above tab) switches between windows owned by the
SAME application as is currently focused. So if you had three Safari and
two Finder windows open, and Safari had focus, Command-Tab would switch to
Finder; Command-Tab would switch back to Safari; Command-Grave would switch
to a different Safari window etc.
This patch implements "something like" the above by only populating the
switchpanel with windows matching the currently-focused WWindow's wm_class
when the new cycling mode is activated. In practice this means you can
switch to The Next XTerm or The Next Firefox Window using this method.
The configuration names for these new shortcuts are GroupNext and
GroupPrev. The patch tells WPrefs.app about them. Of course switching to
The Next Window is still possible with the (unchanged) FocusNext and
FocusPrev keys.
Allow wmsetbg to revert to pre-0.90.0 behaviour when choosing a
background image that is large enough to span several heads in a
Xinerama setup. If the -X flag is passed to wmsetbg, the background
image will be stretched to fill the logical screen (as it would be by
default in older versions of wmsetbg) instead of being tiled across
screens.
Shift the workspace name, shown when switching workspaces, by 32
pixels. This is purely for aesthetic reasons. It just looks better
(IMO) than having the name flush against the screen edge.
When switching workspaces, force the name to be shown entirely within
one head of a Xinerama display. Previously the name would span heads if
set to TOP, CENTER or BOTTOM alignment, and was hence hard to read when
the display comprised an even number of heads.
This is a small patch to fix an issue with the switchpanel and a large number
of windows which happens only on a Xinerama setup.
When the number of open windows is so large that displaying all of them would
cause the switchpanel to be too wide for the screen, the panel is supposed to
shrink and scroll to accomodate them all.
In Window Maker 0.92.0 this works for single head displays but not for
Xinerama. The panel extends to the next head and gets garbled. This patch fixes
the issue by correctly constraining the panel to the head with the cursor.
Submitted-by: Gilbert Ashley <amigo@ibiblio.org>