Entirely unnecessary for the current version of `cycleWindowSets`, but
if anyone ever wants to use `greedyView`, this shows that it's not at
all complicated to adapt `unView` to that.
To make this more "obviously correct", make it resemble the `view`
implementation, just do the exact reverse. Now the only complex bit is
the "undelete" operation.
This also fixes another issue: state was only preserved in the focused
workspace, but it may have changed in another visible workspace as well.
The property test is updated to test this.
The way that workspace cycling is implemented right now—by generating
new windowsets where the things we want happen to be true and then
replacing the old windowsets—is not safe, as workspaces and layouts may
carry state with them. That state will get lost in translation when
windowsets are simply replaced.
As an example, a conflict occurs when using `X.L.ShowWName.showWName` in
one's layoutHook. When cycling through workspaces via, e.g.,
`cycleRecentWS` the flashed workspace tag will not disappear, as the
necessary state to control this isn't present in the new windowset.
Instead, what we want to do is to keep the "current" windowset alive and
actually switch to the requested workspaces. This mostly works without
much trouble, the only hard part is maintaining the invariant that
previewed workspaces don't count towards the history of recently-viewed
workspaces. This is done by remembering the tag-order of the original
windowset and then restoring that at the end.
This is a breaking change, insofar as it changes the type signatures of
the exported functions `recentWS`, `cycleWindowSets`, and
`toggleWindowSets` to return a list of `WorkspaceId`s instead of a list
of `WindowSet`s.
Fixes: https://github.com/xmonad/xmonad-contrib/issues/504
It's often difficult to make contrib modules work together. When one
depends on a functionality of another, it is often necessary to expose
lots of low-level functions and hooks and have the user combine these
into a complex configuration that works. This is error-prone, and
arguably a bad UX in general.
This commit presents a simple solution to that problem inspired by
"extensible state": extensible config. It allows contrib modules to
store custom configuration values inside XConfig. This lets them create
custom hooks, ensure they hook into xmonad core only once, and possibly
other use cases I haven't thought of yet.
This requires changes to xmonad core: https://github.com/xmonad/xmonad/pull/294
A couple examples of what this gives us:
* [X.H.RescreenHook](https://github.com/xmonad/xmonad-contrib/pull/460)
can be made safe to apply multiple times, making it composable and
usable in other contrib modules like X.H.StatusBar
* `withSB` from X.H.StatusBar can also be made safe to apply multiple
times, and we can even provide an API [similar to what we had
before](https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Hooks-DynamicLog.html#v:statusBar)
if we want (probably not, consistency with the new dynamic status bars
of https://github.com/xmonad/xmonad-contrib/pull/463 is more important)
* The [X.H.EwmhDesktops refactor](https://github.com/xmonad/xmonad-contrib/pull/399)
can possibly be made without breaking the `ewmh`/`ewmhFullscreen` API.
And we will finally be able to have composable EWMH hooks.
Related: https://github.com/xmonad/xmonad/pull/294
Decoration windows are created using XMonad.Util.XUtils.createNewWindow
which happens to set _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_DESKTOP,
and ManageDocks considers such windows candidates for struts and
therefore requests property events, thus overriding the original event
mask requested by decorations.
The fix is to first obtain the current event mask, set the required bits
in it only then reset the mask.
Fixes: https://github.com/xmonad/xmonad-contrib/issues/517
Fixes: ec146171238b ("X.H.ManageDocks: React to strut updates of override_redirect docks")
Related: https://github.com/xmonad/X11/pull/77
command specific
- The names were awfully long. spawnStatusBar and killStatusBar are
perfectly fine alternatives.
- It's more flexible to have killStatusBar command specific. Also added
killAllStatusBars to provide the old functionality
This prevents an unnecessary refresh.
That refresh would normally be harmless but it does reset the input
focus, which happens to upset some non-conforming clients such as
https://github.com/flameshot-org/flameshot. Flameshot is an interactive
screenshot tool that creates an override-redirect fullscreen window to
let the user select a rectangle to capture and then allows drawing and
adding text and so on, but it unfortunately doesn't follow ICCCM
recommendations:
> If it is necessary for a client to receive keystrokes on an
> override-redirect window, either the client must grab the keyboard, or
> the client must have another top-level window that is not
> override-redirect and that has selected the Locally Active or Globally
> Active focus model.
Instead, it just takes input focus and hopes for the best. And it also
sends an entirely useless _NET_WM_STATE_FULLSCREEN request, which would
trigger a refresh and take that focus away.
This commit works around that by not handling that useless
_NET_WM_STATE_FULLSCREEN for unmanaged windows and thus preventing that
refresh. It's just a workaround, however: if a legitimate refresh is
necessary at any point, the focus _will_ be taken away.
Fixes: https://github.com/xmonad/xmonad-contrib/issues/550
Fixes: https://github.com/flameshot-org/flameshot/issues/773
xmobar allows you to define a list of additional fonts (additionalFonts) and to use the fn tag to choose between them. xmobarFont is essentially the same as the xmobarColor function, but for fonts.
Building xmonad-contrib benefits greatly from compiling modules in
parallel. Vanessa McHale suggested setting ghc-options in
xmonad-contrib.cabal in #431, but that's bad practice—these options
should be set by the user/environment where it's being built, not
selfishly hardcoded for specific package. In stack.yaml and
cabal.haskell-ci, we know for sure that xmonad-contrib is the terminal
(leaf) library, so we can set it there and speed up builds in our CI and
also for anyone who uses our stack.yaml (not that anyone should).
Closes: https://github.com/xmonad/xmonad-contrib/pull/431
Turns out `commit: master` doesn't really mean latest master, because
it's cached. It sometimes works, because when the GHA cache comes from
a job that depended on xmonad-0.15, then the master archive isn't cached
and is fetched. When the cache comes from a job that previously fetched
master, it's not fetched again.
The least ugly way to fix it I found is to use the `[<refname>]@{<date>}`
git revision format, and substitute current date/time before invoking
stack. To make stack-master.yaml valid without the substitution, we use
`master@{today}` which is a valid git revision that GitHub understands.
GitHub Actions writes caches on the first miss and then never updates
them again. If the CI is used frequently, the caches never expire and
as they get old, become less useful.
To avoid this, force refreshing the caches once a month.
When building with an LTS version that has exactly the dependencies we
need (xmonad-0.15), stack doesn't need to download the Hackage index. If
GitHub Actions cache locking chooses this job as the one that writes the
cache, then the "stack-pantry-Linux" cache entry stays empty, possibly
forever.
Force Hackage index update to prevent this from happening.
This further reduces our usage of cache storage by caching the metadata
only once per repo. Now the metadata cache is ~250MB and the individual
caches with built dependencies are ~10M each.
Related: cfe99998fc
Related: https://github.com/xmonad/X11/pull/75
Stack installation of GHC takes more than a gigabyte, so caching it
wastes space (GitHub docs say it will be aggressively evicted after
reaching the 5G limit) and also time (compression, decompression).
Related: 9fce3805fc
Related: a5cee9bac2
Related: https://github.com/xmonad/X11/pull/75
Drop nightly and lts-15: they don't add GHC versions to the matrix and
new deps are better tested in the haskell-ci (cabal) workflow.
There's also little point in testing against both xmonad 0.15 and xmonad
master with all LTS versions. Drop most of those, reduces GitHub cache
and CPU time usage.
Related: fd243ca1c1
Related: https://github.com/xmonad/X11/pull/75
Last released xmonad doesn't build with GHC 9.0 and haskell-ci doesn't
let us tweak the test matrix easily. Let's hope the stack.yml workflow
is sufficient to test backward compat.
Related: 2a1a18023a
Current version of Steam sends _NET_ACTIVE_WINDOW ClientMessage for
every mouse click which results in a lot of border blinking.
Ignore requests that would result in no change to get rid of the
annoying border flicker that is inevitable with the current
implementation of XMonad.Operations.windows.
(Note that Steam also sends ConfigureRequest events, and these cause
an additional refresh due to the call to `float` when handling the event
in xmonad core. Not sure if worth fixing.)
Related: https://github.com/xmonad/xmonad-contrib/pull/371
Related: https://github.com/xmonad/xmonad-contrib/pull/399