xmonad-contrib/XMonad/Layout/SortedLayout.hs
Tony Zorman 3d65a6bf72 Refer to the tutorial instead of X.D.Extending more often
Essentially, whenever the tutorial actually has decent material on the
subject matter.  The replacement is roughly done as follows:

  - logHook → tutorial
  - keybindings → tutorial, as this is thoroughly covered
  - manageHook → tutorial + X.D.Extending, as the manageHook stuff the
    tutorial talks about is a little bit of an afterthought.
  - X.D.Extending (on its own) → tutorial + X.D.Extending
  - layoutHook → tutorial + X.D.Extending, as the tutorial, while
    talking about layouts, doesn't necessarily have a huge focus there.
  - mouse bindings → leave this alone, as the tutorial does not at all
    talk about them.
2022-10-21 09:17:43 +02:00

87 lines
3.2 KiB
Haskell

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeSynonymInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Layout.SortedLayout
-- Description : A layout modifier that sorts a given layout by a list of properties.
-- Copyright : (c) 2016 Kurt Dietrich
-- License : BSD-style (see xmonad/LICENSE)
--
-- Maintainer : kurto@mac.com
-- Stability : unstable
-- Portability : unportable
--
-- A 'LayoutModifier' that sorts the windows in another layout, given a
-- list of properties. The order of properties in the list determines
-- the order of windows in the final layout. Any unmatched windows
-- go to the end of the order.
-----------------------------------------------------------------------------
module XMonad.Layout.SortedLayout
( -- *Usage:
-- $usage
sorted
, Property(..)
) where
import XMonad
import XMonad.Prelude hiding (Const)
import XMonad.Layout.LayoutModifier
import XMonad.StackSet as W
import XMonad.Util.WindowProperties
-- $usage
-- You can use this module with the following in your
-- @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Layout.SortedLayout
--
-- Then edit your @layoutHook@ to sort another layout (in this case, 'XMonad.Layout.Grid.Grid'):
--
-- > myLayout = sorted [ClassName "Firefox", ClassName "URxvt"] Grid
-- > main = xmonad def { layoutHook = myLayout }
--
-- For more detailed instructions on editing the layoutHook see
-- <https://xmonad.org/TUTORIAL.html#customizing-xmonad the tutorial> and
-- "XMonad.Doc.Extending#Editing_the_layout_hook".
-- | Modify a layout using a list of properties to sort its windows.
sorted :: [Property]
-> l a
-> ModifiedLayout SortedLayout l a
sorted props = ModifiedLayout . SortedLayout $ props ++ [Const True]
data WindowDescriptor = WindowDescriptor { wdSeqn :: !Integer
, wdProp :: !Property
, wdId :: !Window
} deriving (Show, Read)
instance Eq WindowDescriptor where
(==) a b = wdId a == wdId b
instance Ord WindowDescriptor where
compare a b = compare (wdSeqn a) (wdSeqn b)
newtype SortedLayout a = SortedLayout [Property] deriving (Show, Read)
instance LayoutModifier SortedLayout Window where
modifyLayout (SortedLayout props) = sortLayout props
modifierDescription _ = "Sorted"
findMatchingWindows :: Integer -> Property -> [Window] -> X [WindowDescriptor]
findMatchingWindows seqn prop wids = fmap (fmap (WindowDescriptor seqn prop)) matching where
matching = filterM (hasProperty prop) wids
sortLayout :: (LayoutClass l Window)
=> [Property]
-> W.Workspace WorkspaceId (l Window) Window
-> Rectangle
-> X ([(Window, Rectangle)], Maybe (l Window))
sortLayout props (W.Workspace w l r) rect = do
let wids = W.integrate' r
sortedWids <- map wdId . nub . sort . concat <$> zipWithM (\s p -> findMatchingWindows s p wids) [0..] props
let sr = W.differentiate sortedWids
runLayout (W.Workspace w l sr) rect