Doing a multi-head setup using other means than Xinerama may lead to
XineramaQueryScreens() returning the screens in an order that does not
actually represent the actual screen layout. This in turn may result
in dwm using the "wrong" monitor in monitor related
functions (focusmon(), tagmon(), applying rules, ...).
This change sorts the list of unique screens by their origin to
alleviate this problem.
This patch differentiates between inner and outer gaps as well as
horizontal and vertical gaps.
The logic of these layouts also aims to be pixel perfect by ensuring
an even split of the available space and re-distributing the remainder
among the available clients.
This patch allows the user to define layout, mfact, nmaster, showbar,
and topbar settings on a per monitor basis. An example use case could
be to have a layout with a horizontal split for a secondary vertical
monitor.
Make dwm respect _MOTIF_WM_HINTS property. Applications use this
property to notify window managers to not draw window decorations.
Not respecting this property leads to issues with applications that draw
their own borders, like chromium (with "Use system title bar and
borders" turned off) and vlc in fullscreen mode.
By default, dwm response to client requests to _NET_ACTIVE_WINDOW client
messages by setting the urgency bit on the named window.
This patch activates the window instead.
Both behaviours are legitimate according to
https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472702304
One should decide which of these one should perform based on the message
senders' untestable claims that it represents the end-user. Setting the
urgency bit is the conservative decision. This patch implements the more
trusting alternative.
It also allows dwm to work with `wmctrl -a` and other external window
management utilities.
This patch enables multiple scratchpads, each with one asigned window.
This enables the same scratchpad workflow that you have in i3.
Scratchpads are implemented as special tags, whose mask does not
apply to new spawned windows. To assign a window to a scratchpad you
have to set up a rule, as you do with regular tags.
Windows tagged with scratchpad tags can be set floating or not in the
rules array. Most users would probably want them floating (i3 style),
but having them tiled does also perfectly work and might fit better the
DWM approach. In case they are set floating, the patch moves them to the
center of the screen whenever they are shown. The patch can easily be
modified to make this last feature configurable in the rules array (see
the center patch).
The togglescratch function, borrowed from the previous scratchpad patch
and slightly modified, can be used to spawn a registered scratchpad
process or toggle its view. This function looks for a window tagged with
the selected scratchpad tag. If it is found its view is toggled. If it is
not found the corresponding registered command is spawned. The
config.def.h shows three examples of its use to spawn a terminal in the
first scratchpad tag, a second terminal running ranger on the second
scratchpad tag and the keepassxc application to manage passwords on a
third scratchpad tag.
If you prefer to spawn your scratchpad applications from the startup
script, you might opt for binding keys to toggleview instead, as
scratchpads are just special tags (you may even extend the TAGKEYS macro
to generalize the key bindings).
I noticed that a non-trivial amount of dwm's work on my machine was from
drw_text, which seemed weird, because I have the bar disabled and we
only use drw_text as part of bar drawing.
Looking more closely, I realised that while we use m->showbar when
updating the monitor bar margins, but don't skip actually drawing the
bar if it is hidden. This patch skips drawing it entirely if that is the
case.
On my machine, this takes 10% of dwm's on-CPU time, primarily from
restack() and focus().
When the bar is toggled on again, the X server will generate an Expose
event, and we'll redraw the bar as normal as part of expose().