Tomas Janousek f6b1e5dd88 X.U.ExtensibleConf: New helper module for extensible config
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
2021-06-01 19:07:13 +01:00

48 lines
2.2 KiB
Haskell

module Main where
import Test.Hspec
import Test.Hspec.QuickCheck
import qualified ExtensibleConf
import qualified ManageDocks
import qualified NoBorders
import qualified RotateSome
import qualified Selective
import qualified SwapWorkspaces
import qualified XPrompt
main :: IO ()
main = hspec $ do
context "ManageDocks" $ do
prop "prop_r2c_c2r" $ ManageDocks.prop_r2c_c2r
prop "prop_c2r_r2c" $ ManageDocks.prop_c2r_r2c
context "Selective" $ do
prop "prop_select_length" $ Selective.prop_select_length
prop "prop_update_idem" $ Selective.prop_update_idem
prop "prop_select_master" $ Selective.prop_select_master
prop "prop_select_focus" $ Selective.prop_select_focus
prop "prop_select_increasing" $ Selective.prop_select_increasing
prop "prop_select_two_consec" $ Selective.prop_select_two_consec
prop "prop_update_nm" $ Selective.prop_update_nm
prop "prop_update_start" $ Selective.prop_update_start
prop "prop_update_nr" $ Selective.prop_update_nr
prop "prop_update_focus_up" $ Selective.prop_update_focus_up
prop "prop_update_focus_down" $ Selective.prop_update_focus_down
context "RotateSome" $ do
prop "prop_rotate_some_length" $ RotateSome.prop_rotate_some_length
prop "prop_rotate_some_cycle" $ RotateSome.prop_rotate_some_cycle
prop "prop_rotate_some_anchors" $ RotateSome.prop_rotate_some_anchors
prop "prop_rotate_some_rotate" $ RotateSome.prop_rotate_some_rotate
prop "prop_rotate_some_focus" $ RotateSome.prop_rotate_some_focus
context "SwapWorkspaces" $ do
prop "prop_double_swap" $ SwapWorkspaces.prop_double_swap
prop "prop_invalid_swap" $ SwapWorkspaces.prop_invalid_swap
prop "prop_swap_only_two" $ SwapWorkspaces.prop_swap_only_two
prop "prop_swap_with_current" $ SwapWorkspaces.prop_swap_with_current
context "XPrompt" $ do
prop "prop_split" $ XPrompt.prop_split
prop "prop_spliInSubListsAt" $ XPrompt.prop_spliInSubListsAt
prop "prop_skipGetLastWord" $ XPrompt.prop_skipGetLastWord
context "NoBorders" $ NoBorders.spec
context "ExtensibleConf" $ ExtensibleConf.spec