----------------------------------------------------------------------------- -- | -- Module : XMonad.Hooks.BorderPerWindow -- Description : Set border width for a window in a ManageHook. -- Copyright : (c) 2021 Xiaokui Shu -- License : BSD-style (see LICENSE) -- -- Maintainer : subbyte@gmail.com -- Stability : unstable -- Portability : unportable -- -- Want to customize border width, for each window on all layouts? Want -- specific window have no border on all layouts? Try this. ----------------------------------------------------------------------------- module XMonad.Hooks.BorderPerWindow ( -- * Usage -- $usage defineBorderWidth , actionQueue -- * Design Considerations -- $design ) where import XMonad import XMonad.Util.ActionQueue (enqueue, actionQueue) -- $usage -- -- To use this module, first import it -- -- > import XMonad.Hooks.BorderPerWindow (defineBorderWidth, actionQueue) -- -- Then specify which window to customize the border of in your -- @manageHook@: -- -- > myManageHook :: ManageHook -- > myManageHook = composeAll -- > [ className =? "firefox" --> defineBorderWidth 0 -- > , className =? "Chromium" --> defineBorderWidth 0 -- > , isDialog --> defineBorderWidth 8 -- > ] -- -- Finally, add the 'actionQueue' combinator and @myManageHook@ to your -- config: -- -- > main = xmonad $ actionQueue $ def -- > { ... -- > , manageHook = myManageHook -- > , ... -- > } -- -- Note that this module is incompatible with other ways of changing -- borders, like "XMonad.Layout.NoBorders". This is because we are -- changing the border exactly /once/ (when the window first appears) -- and not every time some condition is satisfied. -- $design -- -- 1. Keep it simple. Since the extension does not aim to change border setting -- when layout changes, only execute the border setting function once to -- avoid potential window flashing/jumping/scaling. -- -- 2. The 'ManageHook' eDSL is a nice language for specifying windows. Let's -- build on top of it and use it to specify window to define border. defineBorderWidth :: Dimension -> ManageHook defineBorderWidth :: Dimension -> Query (Endo WindowSet) defineBorderWidth Dimension bw = do Window w <- Query Window forall r (m :: * -> *). MonadReader r m => m r ask X () -> Query () forall a. X a -> Query a liftX (X () -> Query ()) -> (X () -> X ()) -> X () -> Query () forall b c a. (b -> c) -> (a -> b) -> a -> c . X () -> X () enqueue (X () -> Query ()) -> X () -> Query () forall a b. (a -> b) -> a -> b $ Window -> Dimension -> X () updateBorderWidth Window w Dimension bw Query (Endo WindowSet) forall m. Monoid m => m idHook updateBorderWidth :: Window -> Dimension -> X () updateBorderWidth :: Window -> Dimension -> X () updateBorderWidth Window w Dimension bw = do (Display -> X ()) -> X () forall a. (Display -> X a) -> X a withDisplay ((Display -> X ()) -> X ()) -> (Display -> X ()) -> X () forall a b. (a -> b) -> a -> b $ \Display d -> IO () -> X () forall (m :: * -> *) a. MonadIO m => IO a -> m a io (IO () -> X ()) -> IO () -> X () forall a b. (a -> b) -> a -> b $ Display -> Window -> Dimension -> IO () setWindowBorderWidth Display d Window w Dimension bw X () refresh