packages feed

xmonad-contrib-bluetilebranch 0.8.1.3 → 0.9.1.4

raw patch · 193 files changed

+7949/−2865 lines, 193 filesdep +extensible-exceptionsdep ~X11dep ~basedep ~xmonad-bluetilebranchPVP ok

version bump matches the API change (PVP)

Dependencies added: extensible-exceptions

Dependency ranges changed: X11, base, xmonad-bluetilebranch

API changes (from Hackage documentation)

- XMonad.Actions.CycleWS: data WSDirection
- XMonad.Actions.GridSelect: defaultGSSpawnConfig :: GSConfig String
- XMonad.Actions.MouseGestures: data Direction
- XMonad.Actions.Search: hasPrefix :: String -> String -> Bool
- XMonad.Actions.SpawnOn: mkSpawner :: (Functor m, MonadIO m) => m Spawner
- XMonad.Actions.SwapWorkspaces: data WSDirection
- XMonad.Actions.WindowNavigation: data Direction
- XMonad.Hooks.BluetileDock: bluetileDock :: Handle -> X ()
- XMonad.Hooks.BluetileDock: instance Read DockOutput
- XMonad.Hooks.BluetileDock: instance Show DockOutput
- XMonad.Hooks.CustomRestart: CustomRestart :: CustomRestart
- XMonad.Hooks.CustomRestart: customRestartEventHook :: String -> Event -> X All
- XMonad.Hooks.CustomRestart: data CustomRestart
- XMonad.Hooks.CustomRestart: instance Read CustomRestart
- XMonad.Hooks.CustomRestart: instance Show CustomRestart
- XMonad.Hooks.DynamicHooks: initDynamicHooks :: IO (IORef DynamicHooks)
- XMonad.Hooks.EventHook: class (Read eh, Show eh) => EventHook eh
- XMonad.Hooks.EventHook: data HandleEvent eh l a
- XMonad.Hooks.EventHook: eventHook :: (EventHook eh) => eh -> l a -> (HandleEvent eh l) a
- XMonad.Hooks.EventHook: handleEvent :: (EventHook eh) => eh -> Event -> X ()
- XMonad.Hooks.EventHook: instance (EventHook eh, LayoutClass l a) => LayoutClass (HandleEvent eh l) a
- XMonad.Hooks.EventHook: instance (Read eh, Read (l a)) => Read (HandleEvent eh l a)
- XMonad.Hooks.EventHook: instance (Show eh, Show (l a)) => Show (HandleEvent eh l a)
- XMonad.Hooks.EventHook: instance Message EventHandleMsg
- XMonad.Hooks.EventHook: instance Typeable EventHandleMsg
- XMonad.Hooks.ManageDocks: D :: Direction
- XMonad.Hooks.ManageDocks: L :: Direction
- XMonad.Hooks.ManageDocks: R :: Direction
- XMonad.Hooks.ManageDocks: U :: Direction
- XMonad.Hooks.ManageDocks: data Direction
- XMonad.Hooks.ManageDocks: instance Bounded Direction
- XMonad.Hooks.ManageDocks: instance Enum Direction
- XMonad.Hooks.ManageDocks: instance Eq Direction
- XMonad.Hooks.ManageDocks: instance Ord Direction
- XMonad.Hooks.ManageDocks: instance Read Direction
- XMonad.Hooks.ManageDocks: instance Show Direction
- XMonad.Hooks.ServerMode: serverModeEventHookCustom :: X [(String, X ())] -> Event -> X All
- XMonad.Layout.BorderResize: instance Eq BorderInfo
- XMonad.Layout.Decoration: DS :: [(OrigWin, DecoWin)] -> XMonadFont -> DecorationState
- XMonad.Layout.Decoration: data DecorationState
- XMonad.Layout.Decoration: decoFont :: DecorationState -> XMonadFont
- XMonad.Layout.Decoration: decorationAfterDraggingHookAddon :: (DecorationStyle ds a) => ds a -> (Window, Rectangle) -> Bool -> X ()
- XMonad.Layout.Decoration: decos :: DecorationState -> [(OrigWin, DecoWin)]
- XMonad.Layout.Decoration: instance Show DecoClickAction
- XMonad.Layout.Decoration: lookFor :: Window -> [(OrigWin, DecoWin)] -> Maybe (OrigWin, (Window, Maybe Rectangle))
- XMonad.Layout.DecorationUtils: CustomShrink :: CustomShrink
- XMonad.Layout.DecorationUtils: class (Read s, Show s) => Shrinker s
- XMonad.Layout.DecorationUtils: data CustomShrink
- XMonad.Layout.DecorationUtils: data DefaultShrinker
- XMonad.Layout.DecorationUtils: instance Read CustomShrink
- XMonad.Layout.DecorationUtils: instance Read DefaultShrinker
- XMonad.Layout.DecorationUtils: instance Show CustomShrink
- XMonad.Layout.DecorationUtils: instance Show DefaultShrinker
- XMonad.Layout.DecorationUtils: instance Shrinker DefaultShrinker
- XMonad.Layout.DecorationUtils: shrinkIt :: (Shrinker s) => s -> String -> [String]
- XMonad.Layout.DecorationUtils: shrinkText :: DefaultShrinker
- XMonad.Layout.DecorationUtils: shrinkWhile :: (String -> [String]) -> (String -> X Bool) -> String -> X String
- XMonad.Layout.Gaps: data Direction
- XMonad.Layout.LayoutCombinators: instance Message NoWrap
- XMonad.Layout.LayoutCombinators: instance Read NoWrap
- XMonad.Layout.LayoutCombinators: instance Show NoWrap
- XMonad.Layout.LayoutCombinators: instance Typeable NoWrap
- XMonad.Layout.LayoutHints: placeRectangle :: (RealFrac r) => (r, r) -> Rectangle -> Rectangle -> Rectangle
- XMonad.Layout.Mosaic: Mosaic :: [Rational] -> Mosaic a
- XMonad.Layout.Mosaic: data Mosaic a
- XMonad.Layout.Mosaic: growMaster :: [Rational] -> [Rational]
- XMonad.Layout.Mosaic: instance (Show a) => Show (Tree a)
- XMonad.Layout.Mosaic: shallower :: [Rational] -> [Rational]
- XMonad.Layout.Mosaic: shrinkMaster :: [Rational] -> [Rational]
- XMonad.Layout.Mosaic: steeper :: [Rational] -> [Rational]
- XMonad.Layout.MouseResizableTile: instance LayoutClass MouseResizableTile a
- XMonad.Layout.MultiToggle: instance (Show ts, Show (l a)) => Show (MultiToggle ts l a)
- XMonad.Layout.WindowNavigation: data Direction
- XMonad.Prompt: instance Eq Direction
- XMonad.Prompt: instance Read Direction
- XMonad.Prompt: instance Show Direction
- XMonad.Util.NamedScratchpad: rect :: NamedScratchpad -> Maybe RationalRect
- XMonad.Util.XSelection: putSelection :: (MonadIO m) => String -> m ()
+ XMonad.Actions.CopyWindow: wsContainingCopies :: X [WorkspaceId]
+ XMonad.Actions.CycleWS: WSTagGroup :: Char -> WSType
+ XMonad.Actions.CycleWS: data Direction1D
+ XMonad.Actions.CycleWS: doTo :: Direction1D -> WSType -> X WorkspaceSort -> (WorkspaceId -> X ()) -> X ()
+ XMonad.Actions.CycleWS: skipTags :: (Eq i) => [Workspace i l a] -> [i] -> [Workspace i l a]
+ XMonad.Actions.CycleWS: toggleOrDoSkip :: [WorkspaceId] -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()
+ XMonad.Actions.CycleWS: toggleOrView :: WorkspaceId -> X ()
+ XMonad.Actions.DynamicWorkspaceGroups: addCurrentWSGroup :: WSGroupId -> X ()
+ XMonad.Actions.DynamicWorkspaceGroups: addWSGroup :: WSGroupId -> [WorkspaceId] -> X ()
+ XMonad.Actions.DynamicWorkspaceGroups: forgetWSGroup :: WSGroupId -> X ()
+ XMonad.Actions.DynamicWorkspaceGroups: instance ExtensionClass WSGroupStorage
+ XMonad.Actions.DynamicWorkspaceGroups: instance Read WSGroupStorage
+ XMonad.Actions.DynamicWorkspaceGroups: instance Show WSGroupStorage
+ XMonad.Actions.DynamicWorkspaceGroups: instance Typeable WSGroupStorage
+ XMonad.Actions.DynamicWorkspaceGroups: instance XPrompt WSGPrompt
+ XMonad.Actions.DynamicWorkspaceGroups: promptWSGroupAdd :: XPConfig -> String -> X ()
+ XMonad.Actions.DynamicWorkspaceGroups: promptWSGroupForget :: XPConfig -> String -> X ()
+ XMonad.Actions.DynamicWorkspaceGroups: promptWSGroupView :: XPConfig -> String -> X ()
+ XMonad.Actions.DynamicWorkspaceGroups: type WSGroupId = String
+ XMonad.Actions.DynamicWorkspaceGroups: viewWSGroup :: WSGroupId -> X ()
+ XMonad.Actions.DynamicWorkspaceOrder: getSortByOrder :: X WorkspaceSort
+ XMonad.Actions.DynamicWorkspaceOrder: getWsCompareByOrder :: X WorkspaceCompare
+ XMonad.Actions.DynamicWorkspaceOrder: instance ExtensionClass WSOrderStorage
+ XMonad.Actions.DynamicWorkspaceOrder: instance Read WSOrderStorage
+ XMonad.Actions.DynamicWorkspaceOrder: instance Show WSOrderStorage
+ XMonad.Actions.DynamicWorkspaceOrder: instance Typeable WSOrderStorage
+ XMonad.Actions.DynamicWorkspaceOrder: moveTo :: Direction1D -> WSType -> X ()
+ XMonad.Actions.DynamicWorkspaceOrder: moveToGreedy :: Direction1D -> WSType -> X ()
+ XMonad.Actions.DynamicWorkspaceOrder: shiftTo :: Direction1D -> WSType -> X ()
+ XMonad.Actions.DynamicWorkspaceOrder: swapWith :: Direction1D -> WSType -> X ()
+ XMonad.Actions.DynamicWorkspaces: addWorkspacePrompt :: XPConfig -> X ()
+ XMonad.Actions.DynamicWorkspaces: removeEmptyWorkspace :: X ()
+ XMonad.Actions.DynamicWorkspaces: removeEmptyWorkspaceAfter :: X () -> X ()
+ XMonad.Actions.DynamicWorkspaces: removeEmptyWorkspaceAfterExcept :: [String] -> X () -> X ()
+ XMonad.Actions.FlexibleResize: mouseResizeEdgeWindow :: Rational -> Window -> X ()
+ XMonad.Actions.FloatSnap: D :: Direction2D
+ XMonad.Actions.FloatSnap: L :: Direction2D
+ XMonad.Actions.FloatSnap: R :: Direction2D
+ XMonad.Actions.FloatSnap: U :: Direction2D
+ XMonad.Actions.FloatSnap: data Direction2D
+ XMonad.Actions.FloatSnap: snapGrow :: Direction2D -> Maybe Int -> Window -> X ()
+ XMonad.Actions.FloatSnap: snapMagicMouseResize :: Rational -> Maybe Int -> Maybe Int -> Window -> X ()
+ XMonad.Actions.FloatSnap: snapMagicMove :: Maybe Int -> Maybe Int -> Window -> X ()
+ XMonad.Actions.FloatSnap: snapMagicResize :: [Direction2D] -> Maybe Int -> Maybe Int -> Window -> X ()
+ XMonad.Actions.FloatSnap: snapMove :: Direction2D -> Maybe Int -> Window -> X ()
+ XMonad.Actions.FloatSnap: snapShrink :: Direction2D -> Maybe Int -> Window -> X ()
+ XMonad.Actions.FocusNth: focusNth' :: Int -> Stack a -> Stack a
+ XMonad.Actions.GridSelect: class HasColorizer a
+ XMonad.Actions.GridSelect: gridselectWorkspace :: GSConfig WorkspaceId -> (WorkspaceId -> WindowSet -> WindowSet) -> X ()
+ XMonad.Actions.GridSelect: gs_navigate :: GSConfig a -> NavigateMap
+ XMonad.Actions.GridSelect: instance [overlap ok] Applicative (TwoD a)
+ XMonad.Actions.GridSelect: instance [overlap ok] Functor (TwoD a)
+ XMonad.Actions.GridSelect: instance [overlap ok] HasColorizer String
+ XMonad.Actions.GridSelect: instance [overlap ok] HasColorizer Window
+ XMonad.Actions.GridSelect: instance [overlap ok] HasColorizer a
+ XMonad.Actions.GridSelect: instance [overlap ok] Monad (TwoD a)
+ XMonad.Actions.GridSelect: instance [overlap ok] MonadState (TwoDState a) (TwoD a)
+ XMonad.Actions.GridSelect: stringColorizer :: String -> Bool -> X (String, String)
+ XMonad.Actions.GridSelect: type NavigateMap = Map (KeyMask, KeySym) (TwoDPosition -> TwoDPosition)
+ XMonad.Actions.GridSelect: type TwoDPosition = (Integer, Integer)
+ XMonad.Actions.MouseGestures: data Direction2D
+ XMonad.Actions.OnScreen: FocusCurrent :: Focus
+ XMonad.Actions.OnScreen: FocusNew :: Focus
+ XMonad.Actions.OnScreen: FocusTag :: WorkspaceId -> Focus
+ XMonad.Actions.OnScreen: FocusTagVisible :: WorkspaceId -> Focus
+ XMonad.Actions.OnScreen: data Focus
+ XMonad.Actions.OnScreen: greedyViewOnScreen :: ScreenId -> WorkspaceId -> WindowSet -> WindowSet
+ XMonad.Actions.OnScreen: onScreen :: (WindowSet -> WindowSet) -> Focus -> ScreenId -> WindowSet -> WindowSet
+ XMonad.Actions.OnScreen: onScreen' :: X () -> Focus -> ScreenId -> X ()
+ XMonad.Actions.OnScreen: onlyOnScreen :: ScreenId -> WorkspaceId -> WindowSet -> WindowSet
+ XMonad.Actions.OnScreen: toggleGreedyOnScreen :: ScreenId -> WorkspaceId -> WindowSet -> WindowSet
+ XMonad.Actions.OnScreen: toggleOnScreen :: ScreenId -> WorkspaceId -> WindowSet -> WindowSet
+ XMonad.Actions.OnScreen: viewOnScreen :: ScreenId -> WorkspaceId -> WindowSet -> WindowSet
+ XMonad.Actions.PhysicalScreens: onNextNeighbour :: (WorkspaceId -> WindowSet -> WindowSet) -> X ()
+ XMonad.Actions.PhysicalScreens: onPrevNeighbour :: (WorkspaceId -> WindowSet -> WindowSet) -> X ()
+ XMonad.Actions.RandomBackground: HSV :: Double -> Double -> RandomColor
+ XMonad.Actions.RandomBackground: RGB :: Int -> Int -> RandomColor
+ XMonad.Actions.RandomBackground: data RandomColor
+ XMonad.Actions.RandomBackground: randomBg :: RandomColor -> X ()
+ XMonad.Actions.RandomBackground: randomBg' :: (MonadIO m) => RandomColor -> m String
+ XMonad.Actions.Search: alpha :: SearchEngine
+ XMonad.Actions.Search: isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
+ XMonad.Actions.Search: lucky :: SearchEngine
+ XMonad.Actions.Search: openstreetmap :: SearchEngine
+ XMonad.Actions.Search: wiktionary :: SearchEngine
+ XMonad.Actions.SpawnOn: instance ExtensionClass Spawner
+ XMonad.Actions.SpawnOn: instance Typeable Spawner
+ XMonad.Actions.SpawnOn: spawnAndDo :: ManageHook -> String -> X ()
+ XMonad.Actions.SwapWorkspaces: data Direction1D
+ XMonad.Actions.TopicSpace: defaultTopicConfig :: TopicConfig
+ XMonad.Actions.TopicSpace: instance ExtensionClass PrevTopics
+ XMonad.Actions.TopicSpace: instance Read PrevTopics
+ XMonad.Actions.TopicSpace: instance Show PrevTopics
+ XMonad.Actions.TopicSpace: instance Typeable PrevTopics
+ XMonad.Actions.TopicSpace: shiftNthLastFocused :: Int -> X ()
+ XMonad.Actions.WindowGo: ifWindow :: Query Bool -> ManageHook -> X () -> X ()
+ XMonad.Actions.WindowGo: ifWindows :: Query Bool -> ([Window] -> X ()) -> X () -> X ()
+ XMonad.Actions.WindowGo: raiseHook :: ManageHook
+ XMonad.Actions.WindowNavigation: data Direction2D
+ XMonad.Actions.WorkspaceCursors: data WorkspaceCursors a
+ XMonad.Actions.WorkspaceCursors: focusDepth :: Cursors t -> Int
+ XMonad.Actions.WorkspaceCursors: focusNth' :: Int -> Stack a -> Stack a
+ XMonad.Actions.WorkspaceCursors: getFocus :: Cursors b -> b
+ XMonad.Actions.WorkspaceCursors: instance (Eq a) => Eq (Cursors a)
+ XMonad.Actions.WorkspaceCursors: instance (Read a) => Read (Cursors a)
+ XMonad.Actions.WorkspaceCursors: instance (Show a) => Show (Cursors a)
+ XMonad.Actions.WorkspaceCursors: instance Foldable Cursors
+ XMonad.Actions.WorkspaceCursors: instance Functor Cursors
+ XMonad.Actions.WorkspaceCursors: instance LayoutModifier WorkspaceCursors a
+ XMonad.Actions.WorkspaceCursors: instance Message ChangeCursors
+ XMonad.Actions.WorkspaceCursors: instance Read (WorkspaceCursors a)
+ XMonad.Actions.WorkspaceCursors: instance Show (WorkspaceCursors a)
+ XMonad.Actions.WorkspaceCursors: instance Typeable ChangeCursors
+ XMonad.Actions.WorkspaceCursors: instance Typeable1 Cursors
+ XMonad.Actions.WorkspaceCursors: instance Typeable1 WorkspaceCursors
+ XMonad.Actions.WorkspaceCursors: makeCursors :: [[String]] -> Cursors String
+ XMonad.Actions.WorkspaceCursors: modifyLayer :: (Stack (Cursors String) -> Stack (Cursors String)) -> Int -> X ()
+ XMonad.Actions.WorkspaceCursors: modifyLayer' :: (Stack (Cursors String) -> X (Stack (Cursors String))) -> Int -> X ()
+ XMonad.Actions.WorkspaceCursors: noWrapDown :: Stack t -> Stack t
+ XMonad.Actions.WorkspaceCursors: noWrapUp :: Stack t -> Stack t
+ XMonad.Actions.WorkspaceCursors: shiftLayer :: (Stack (Cursors String) -> Stack (Cursors WorkspaceId)) -> Int -> X ()
+ XMonad.Actions.WorkspaceCursors: shiftModifyLayer :: (Stack (Cursors String) -> Stack (Cursors WorkspaceId)) -> Int -> X ()
+ XMonad.Actions.WorkspaceCursors: toList :: (Foldable t) => t a -> [a]
+ XMonad.Actions.WorkspaceCursors: workspaceCursors :: Cursors String -> l a -> ModifiedLayout WorkspaceCursors l a
+ XMonad.Actions.WorkspaceNames: getWorkspaceNames :: X (WorkspaceId -> String)
+ XMonad.Actions.WorkspaceNames: instance ExtensionClass WorkspaceNames
+ XMonad.Actions.WorkspaceNames: instance Read WorkspaceNames
+ XMonad.Actions.WorkspaceNames: instance Show WorkspaceNames
+ XMonad.Actions.WorkspaceNames: instance Typeable WorkspaceNames
+ XMonad.Actions.WorkspaceNames: instance XPrompt Wor
+ XMonad.Actions.WorkspaceNames: renameWorkspace :: XPConfig -> X ()
+ XMonad.Actions.WorkspaceNames: setCurrentWorkspaceName :: String -> X ()
+ XMonad.Actions.WorkspaceNames: setWorkspaceName :: WorkspaceId -> String -> X ()
+ XMonad.Actions.WorkspaceNames: swapTo :: Direction1D -> X ()
+ XMonad.Actions.WorkspaceNames: swapTo' :: Direction1D -> WSType -> X ()
+ XMonad.Actions.WorkspaceNames: swapWithCurrent :: WorkspaceId -> X ()
+ XMonad.Actions.WorkspaceNames: workspaceNamesPP :: PP -> X PP
+ XMonad.Config.Arossato: arossatoConfig :: (MonadIO m) => m (XConfig (ModifiedLayout AvoidStruts (NewSelect (ModifiedLayout (Decoration SimpleDecoration DefaultShrinker) (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat))) (NewSelect (ModifiedLayout WithBorder (ModifiedLayout (Decoration TabbedDecoration DefaultShrinker) Simplest)) (ModifiedLayout WindowArranger (NewSelect (ModifiedLayout Magnifier Tall) (NewSelect (ModifiedLayout WithBorder Full) (NewSelect (Mirror Tall) Accordion))))))))
+ XMonad.Config.Azerty: azertyConfig :: XConfig (Choose Tall (Choose (Mirror Tall) Full))
+ XMonad.Config.Azerty: azertyKeys :: XConfig t -> Map (KeyMask, KeySym) (X ())
+ XMonad.Config.Bluetile: bluetileConfig :: XConfig (ModifiedLayout AvoidStruts (ModifiedLayout Minimize (ModifiedLayout BoringWindows (NewSelect (ModifiedLayout Named (ModifiedLayout (Decoration ButtonDecoration DefaultShrinker) (ModifiedLayout Maximize (ModifiedLayout BorderResize PositionStoreFloat)))) (NewSelect (ModifiedLayout Named (ModifiedLayout (Decoration WindowSwitcherDecoration DefaultShrinker) (ModifiedLayout DraggingVisualizer (ModifiedLayout Maximize MouseResizableTile)))) (NewSelect (ModifiedLayout Named (ModifiedLayout (Decoration WindowSwitcherDecoration DefaultShrinker) (ModifiedLayout DraggingVisualizer (ModifiedLayout Maximize MouseResizableTile)))) (ModifiedLayout Named (ModifiedLayout (Decoration WindowSwitcherDecoration DefaultShrinker) (ModifiedLayout DraggingVisualizer (ModifiedLayout Maximize (ModifiedLayout SmartBorder Full)))))))))))
+ XMonad.Config.Desktop: desktopConfig :: XConfig (ModifiedLayout AvoidStruts (Choose Tall (Choose (Mirror Tall) Full)))
+ XMonad.Config.Desktop: desktopLayoutModifiers :: (LayoutClass l a) => l a -> ModifiedLayout AvoidStruts l a
+ XMonad.Config.Droundy: config :: XConfig (ModifiedLayout ShowWName (ModifiedLayout WorkspaceDir (ModifiedLayout BoringWindows (ModifiedLayout SmartBorder (ModifiedLayout WindowNavigation (ModifiedLayout Magnifier (ToggleLayouts Full (ModifiedLayout AvoidStruts (NewSelect (ModifiedLayout Named (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest)) (NewSelect (ModifiedLayout Named (CombineTwo (DragPane ()) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest) (CombineTwo (Square ()) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest)))) (NewSelect (ModifiedLayout Named (CombineTwo (DragPane ()) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest) (CombineTwo (DragPane ()) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest) (CombineTwo (Square ()) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest))))) (ModifiedLayout Named (CombineTwo (DragPane ()) (CombineTwo (DragPane ()) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest)) (CombineTwo (Square ()) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest) (ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest)))))))))))))))
+ XMonad.Config.Droundy: mytab :: ModifiedLayout (Decoration TabbedDecoration CustomShrink) Simplest Window
+ XMonad.Config.Gnome: gnomeConfig :: XConfig (ModifiedLayout AvoidStruts (Choose Tall (Choose (Mirror Tall) Full)))
+ XMonad.Config.Gnome: gnomeRegister :: (MonadIO m) => m ()
+ XMonad.Config.Kde: kde4Config :: XConfig (ModifiedLayout AvoidStruts (Choose Tall (Choose (Mirror Tall) Full)))
+ XMonad.Config.Kde: kdeConfig :: XConfig (ModifiedLayout AvoidStruts (Choose Tall (Choose (Mirror Tall) Full)))
+ XMonad.Config.Sjanssen: sjanssenConfig :: XConfig (ModifiedLayout AvoidStruts (ModifiedLayout SmartBorder (Choose (Choose HintedTile (Choose HintedTile Full)) (ModifiedLayout (Decoration TabbedDecoration DefaultShrinker) Simplest))))
+ XMonad.Config.Xfce: xfceConfig :: XConfig (ModifiedLayout AvoidStruts (Choose Tall (Choose (Mirror Tall) Full)))
+ XMonad.Hooks.CurrentWorkspaceOnTop: currentWorkspaceOnTop :: X ()
+ XMonad.Hooks.CurrentWorkspaceOnTop: instance ExtensionClass CWOTState
+ XMonad.Hooks.CurrentWorkspaceOnTop: instance Typeable CWOTState
+ XMonad.Hooks.DynamicHooks: instance ExtensionClass DynamicHooks
+ XMonad.Hooks.DynamicHooks: instance Typeable DynamicHooks
+ XMonad.Hooks.DynamicLog: xmonadPropLog :: String -> X ()
+ XMonad.Hooks.EwmhDesktops: ewmh :: XConfig a -> XConfig a
+ XMonad.Hooks.EwmhDesktops: ewmhDesktopsStartup :: X ()
+ XMonad.Hooks.EwmhDesktops: fullscreenEventHook :: Event -> X All
+ XMonad.Hooks.FadeInactive: fadeIf :: Query Bool -> Rational -> Query Rational
+ XMonad.Hooks.FloatNext: instance ExtensionClass FloatMode
+ XMonad.Hooks.FloatNext: instance Typeable FloatMode
+ XMonad.Hooks.ManageDocks: SetStruts :: [Direction2D] -> [Direction2D] -> SetStruts
+ XMonad.Hooks.ManageDocks: addedStruts :: SetStruts -> [Direction2D]
+ XMonad.Hooks.ManageDocks: data SetStruts
+ XMonad.Hooks.ManageDocks: instance Message SetStruts
+ XMonad.Hooks.ManageDocks: instance Read SetStruts
+ XMonad.Hooks.ManageDocks: instance Show SetStruts
+ XMonad.Hooks.ManageDocks: instance Typeable SetStruts
+ XMonad.Hooks.ManageDocks: removedStruts :: SetStruts -> [Direction2D]
+ XMonad.Hooks.ManageHelpers: currentWs :: Query WorkspaceId
+ XMonad.Hooks.ManageHelpers: doFloatAt :: Rational -> Rational -> ManageHook
+ XMonad.Hooks.ManageHelpers: doFloatDep :: (RationalRect -> RationalRect) -> ManageHook
+ XMonad.Hooks.PositionStoreHooks: positionStoreEventHook :: Event -> X All
+ XMonad.Hooks.PositionStoreHooks: positionStoreManageHook :: ManageHook
+ XMonad.Hooks.ScreenCorners: SCLowerLeft :: ScreenCorner
+ XMonad.Hooks.ScreenCorners: SCLowerRight :: ScreenCorner
+ XMonad.Hooks.ScreenCorners: SCUpperLeft :: ScreenCorner
+ XMonad.Hooks.ScreenCorners: SCUpperRight :: ScreenCorner
+ XMonad.Hooks.ScreenCorners: addScreenCorner :: ScreenCorner -> X () -> X ()
+ XMonad.Hooks.ScreenCorners: addScreenCorners :: [(ScreenCorner, X ())] -> X ()
+ XMonad.Hooks.ScreenCorners: data ScreenCorner
+ XMonad.Hooks.ScreenCorners: instance Eq ScreenCorner
+ XMonad.Hooks.ScreenCorners: instance ExtensionClass ScreenCornerState
+ XMonad.Hooks.ScreenCorners: instance Ord ScreenCorner
+ XMonad.Hooks.ScreenCorners: instance Show ScreenCorner
+ XMonad.Hooks.ScreenCorners: instance Typeable ScreenCornerState
+ XMonad.Hooks.ScreenCorners: screenCornerEventHook :: Event -> X All
+ XMonad.Hooks.ServerMode: serverModeEventHook' :: X [(String, X ())] -> Event -> X All
+ XMonad.Hooks.UrgencyHook: instance ExtensionClass Urgents
+ XMonad.Hooks.UrgencyHook: instance ExtensionClass [Reminder]
+ XMonad.Hooks.UrgencyHook: instance Read Reminder
+ XMonad.Hooks.UrgencyHook: instance Read Urgents
+ XMonad.Hooks.UrgencyHook: instance Show Reminder
+ XMonad.Hooks.UrgencyHook: instance Show Urgents
+ XMonad.Hooks.UrgencyHook: instance Typeable Reminder
+ XMonad.Hooks.UrgencyHook: instance Typeable Urgents
+ XMonad.Layout.AutoMaster: autoMaster :: (LayoutClass l a) => Int -> Float -> l a -> ModifiedLayout AutoMaster l a
+ XMonad.Layout.AutoMaster: instance LayoutModifier AutoMaster Window
+ XMonad.Layout.AutoMaster: instance Read (AutoMaster a)
+ XMonad.Layout.AutoMaster: instance Show (AutoMaster a)
+ XMonad.Layout.BorderResize: instance Eq BorderType
+ XMonad.Layout.BorderResize: instance Read BorderType
+ XMonad.Layout.BorderResize: instance Show BorderType
+ XMonad.Layout.ButtonDecoration: buttonDeco :: (Eq a, Shrinker s) => s -> Theme -> l a -> ModifiedLayout (Decoration ButtonDecoration s) l a
+ XMonad.Layout.ButtonDecoration: instance (Eq a) => DecorationStyle ButtonDecoration a
+ XMonad.Layout.ButtonDecoration: instance Read (ButtonDecoration a)
+ XMonad.Layout.ButtonDecoration: instance Show (ButtonDecoration a)
+ XMonad.Layout.Column: Column :: Float -> Column a
+ XMonad.Layout.Column: data Column a
+ XMonad.Layout.Column: instance LayoutClass Column a
+ XMonad.Layout.Column: instance Read (Column a)
+ XMonad.Layout.Column: instance Show (Column a)
+ XMonad.Layout.ComboP: Machine :: String -> Property
+ XMonad.Layout.Decoration: CustomShrink :: CustomShrink
+ XMonad.Layout.Decoration: class (Read s, Show s) => Shrinker s
+ XMonad.Layout.Decoration: data CustomShrink
+ XMonad.Layout.Decoration: data DefaultShrinker
+ XMonad.Layout.Decoration: decorationCatchClicksHook :: (DecorationStyle ds a) => ds a -> Window -> Int -> Int -> X Bool
+ XMonad.Layout.Decoration: findWindowByDecoration :: Window -> DecorationState -> Maybe (OrigWin, (Window, Maybe Rectangle))
+ XMonad.Layout.Decoration: instance Read CustomShrink
+ XMonad.Layout.Decoration: instance Read DefaultShrinker
+ XMonad.Layout.Decoration: instance Show CustomShrink
+ XMonad.Layout.Decoration: instance Show DefaultShrinker
+ XMonad.Layout.Decoration: instance Shrinker DefaultShrinker
+ XMonad.Layout.Decoration: shrinkIt :: (Shrinker s) => s -> String -> [String]
+ XMonad.Layout.Decoration: shrinkText :: DefaultShrinker
+ XMonad.Layout.Decoration: shrinkWhile :: (String -> [String]) -> (String -> X Bool) -> String -> X String
+ XMonad.Layout.Decoration: windowTitleAddons :: Theme -> [(String, Align)]
+ XMonad.Layout.DecorationAddons: defaultThemeWithButtons :: Theme
+ XMonad.Layout.DecorationAddons: handleScreenCrossing :: Window -> Window -> X Bool
+ XMonad.Layout.DecorationAddons: titleBarButtonHandler :: Window -> Int -> Int -> X Bool
+ XMonad.Layout.Drawer: drawer :: Rational -> Rational -> Property -> (l a) -> Drawer l a
+ XMonad.Layout.Drawer: instance (LayoutClass l Window, Read (l Window)) => LayoutModifier (Drawer l) Window
+ XMonad.Layout.Drawer: instance (Read (l a)) => Read (Drawer l a)
+ XMonad.Layout.Drawer: instance (Show (l a)) => Show (Drawer l a)
+ XMonad.Layout.Drawer: onBottom :: Drawer l a -> l' a -> Reflected (Mirror (ModifiedLayout (Drawer l) (Mirror (Reflected l')))) a
+ XMonad.Layout.Drawer: onLeft :: Drawer l a -> l' a -> ModifiedLayout (Drawer l) l' a
+ XMonad.Layout.Drawer: onRight :: Drawer l a -> l' a -> Reflected (ModifiedLayout (Drawer l) (Reflected l')) a
+ XMonad.Layout.Drawer: onTop :: Drawer l a -> l' a -> Mirror (ModifiedLayout (Drawer l) (Mirror l')) a
+ XMonad.Layout.Drawer: simpleDrawer :: Rational -> Rational -> Property -> Drawer Tall a
+ XMonad.Layout.DwmStyle: windowTitleAddons :: Theme -> [(String, Align)]
+ XMonad.Layout.Gaps: data Direction2D
+ XMonad.Layout.IM: Machine :: String -> Property
+ XMonad.Layout.IndependentScreens: marshallPP :: ScreenId -> PP -> PP
+ XMonad.Layout.IndependentScreens: marshallWindowSpace :: ScreenId -> WindowSpace -> WindowSpace
+ XMonad.Layout.IndependentScreens: unmarshallS :: PhysicalWorkspace -> ScreenId
+ XMonad.Layout.IndependentScreens: unmarshallW :: PhysicalWorkspace -> VirtualWorkspace
+ XMonad.Layout.IndependentScreens: unmarshallWindowSpace :: WindowSpace -> WindowSpace
+ XMonad.Layout.LayoutCombinators: NextLayoutNoWrap :: JumpToLayout
+ XMonad.Layout.LayoutCombinators: Wrap :: JumpToLayout
+ XMonad.Layout.LayoutHints: instance LayoutModifier LayoutHintsToCenter Window
+ XMonad.Layout.LayoutHints: instance Read (LayoutHintsToCenter a)
+ XMonad.Layout.LayoutHints: instance Show (LayoutHintsToCenter a)
+ XMonad.Layout.LayoutHints: layoutHintsToCenter :: (LayoutClass l a) => l a -> ModifiedLayout LayoutHintsToCenter l a
+ XMonad.Layout.LayoutScreens: layoutSplitScreen :: (LayoutClass l Int) => Int -> l Int -> X ()
+ XMonad.Layout.LimitWindows: decreaseLimit :: X ()
+ XMonad.Layout.LimitWindows: increaseLimit :: X ()
+ XMonad.Layout.LimitWindows: instance Eq (Selection a)
+ XMonad.Layout.LimitWindows: instance LayoutModifier LimitWindows a
+ XMonad.Layout.LimitWindows: instance LayoutModifier Selection a
+ XMonad.Layout.LimitWindows: instance Message LimitChange
+ XMonad.Layout.LimitWindows: instance Read (LimitWindows a)
+ XMonad.Layout.LimitWindows: instance Read (Selection a)
+ XMonad.Layout.LimitWindows: instance Read SliceStyle
+ XMonad.Layout.LimitWindows: instance Show (LimitWindows a)
+ XMonad.Layout.LimitWindows: instance Show (Selection a)
+ XMonad.Layout.LimitWindows: instance Show SliceStyle
+ XMonad.Layout.LimitWindows: instance Typeable LimitChange
+ XMonad.Layout.LimitWindows: limitSelect :: Int -> Int -> l a -> ModifiedLayout Selection l a
+ XMonad.Layout.LimitWindows: limitSlice :: Int -> l a -> ModifiedLayout LimitWindows l a
+ XMonad.Layout.LimitWindows: limitWindows :: Int -> l a -> ModifiedLayout LimitWindows l a
+ XMonad.Layout.LimitWindows: setLimit :: Int -> X ()
+ XMonad.Layout.MagicFocus: disableFollowOnWS :: [WorkspaceId] -> X Bool
+ XMonad.Layout.MagicFocus: followOnlyIf :: X Bool -> Event -> X All
+ XMonad.Layout.MessageControl: Escape :: SomeMessage -> EscapedMessage
+ XMonad.Layout.MessageControl: data Ignore m l w
+ XMonad.Layout.MessageControl: data UnEscape w
+ XMonad.Layout.MessageControl: escape :: (Message m) => m -> EscapedMessage
+ XMonad.Layout.MessageControl: ignore :: (Message m, LayoutClass l w) => m -> l w -> (Ignore m l w)
+ XMonad.Layout.MessageControl: instance (Message m, LayoutClass l w) => LayoutClass (Ignore m l) w
+ XMonad.Layout.MessageControl: instance (Read (l w)) => Read (Ignore m l w)
+ XMonad.Layout.MessageControl: instance (Show (l w)) => Show (Ignore m l w)
+ XMonad.Layout.MessageControl: instance LayoutModifier UnEscape a
+ XMonad.Layout.MessageControl: instance Message EscapedMessage
+ XMonad.Layout.MessageControl: instance Read (UnEscape w)
+ XMonad.Layout.MessageControl: instance Show (UnEscape w)
+ XMonad.Layout.MessageControl: instance Typeable EscapedMessage
+ XMonad.Layout.MessageControl: newtype EscapedMessage
+ XMonad.Layout.MessageControl: unEscape :: (LayoutClass l w) => l w -> ModifiedLayout UnEscape l w
+ XMonad.Layout.Monitor: Machine :: String -> Property
+ XMonad.Layout.Mosaic: changeFocused :: (Rational -> Rational) -> X ()
+ XMonad.Layout.Mosaic: instance Functor Tree
+ XMonad.Layout.Mosaic: mosaic :: Rational -> [Rational] -> Mosaic a
+ XMonad.Layout.MouseResizableTile: instance LayoutClass MouseResizableTile Window
+ XMonad.Layout.MultiColumns: instance Eq (MultiCol a)
+ XMonad.Layout.MultiColumns: instance LayoutClass MultiCol a
+ XMonad.Layout.MultiColumns: instance Read (MultiCol a)
+ XMonad.Layout.MultiColumns: instance Show (MultiCol a)
+ XMonad.Layout.MultiColumns: multiCol :: [Int] -> Int -> Rational -> Rational -> MultiCol a
+ XMonad.Layout.MultiToggle: instance (Show ts, Show (l a), LayoutClass l a) => Show (MultiToggle ts l a)
+ XMonad.Layout.Reflect: data Reflect a
+ XMonad.Layout.ResizableTile: _delta :: ResizableTall a -> Rational
+ XMonad.Layout.ResizableTile: _frac :: ResizableTall a -> Rational
+ XMonad.Layout.ResizableTile: _nmaster :: ResizableTall a -> Int
+ XMonad.Layout.ResizableTile: _slaves :: ResizableTall a -> [Rational]
+ XMonad.Layout.SimpleDecoration: windowTitleAddons :: Theme -> [(String, Align)]
+ XMonad.Layout.Spacing: instance LayoutModifier Spacing a
+ XMonad.Layout.Spacing: instance Read (Spacing a)
+ XMonad.Layout.Spacing: instance Show (Spacing a)
+ XMonad.Layout.Spacing: spacing :: Int -> l a -> ModifiedLayout Spacing l a
+ XMonad.Layout.SubLayouts: Migrate :: a -> a -> GroupMsg a
+ XMonad.Layout.Tabbed: windowTitleAddons :: Theme -> [(String, Align)]
+ XMonad.Layout.WindowNavigation: data Direction2D
+ XMonad.Layout.WindowSwitcherDecoration: windowSwitcherDecorationWithButtons :: (Eq a, Shrinker s) => s -> Theme -> l a -> ModifiedLayout (Decoration WindowSwitcherDecoration s) l a
+ XMonad.Prompt: Next :: Direction1D
+ XMonad.Prompt: Prev :: Direction1D
+ XMonad.Prompt: completionKey :: XPConfig -> KeySym
+ XMonad.Prompt: data Direction1D
+ XMonad.Prompt: data HistoryMatches
+ XMonad.Prompt: defaultXPKeymap :: Map (KeyMask, KeySym) (XP ())
+ XMonad.Prompt: deleteString :: Direction1D -> XP ()
+ XMonad.Prompt: endOfLine :: XP ()
+ XMonad.Prompt: getInput :: XP String
+ XMonad.Prompt: historyCompletionP :: (String -> Bool) -> ComplFunction
+ XMonad.Prompt: historyDownMatching :: HistoryMatches -> XP ()
+ XMonad.Prompt: historyUpMatching :: HistoryMatches -> XP ()
+ XMonad.Prompt: initMatches :: (Functor m, MonadIO m) => m HistoryMatches
+ XMonad.Prompt: killAfter :: XP ()
+ XMonad.Prompt: killBefore :: XP ()
+ XMonad.Prompt: killWord :: Direction1D -> XP ()
+ XMonad.Prompt: moveCursor :: Direction1D -> XP ()
+ XMonad.Prompt: moveHistory :: (Stack String -> Stack String) -> XP ()
+ XMonad.Prompt: moveWord :: Direction1D -> XP ()
+ XMonad.Prompt: pasteString :: XP ()
+ XMonad.Prompt: promptKeymap :: XPConfig -> Map (KeyMask, KeySym) (XP ())
+ XMonad.Prompt: quit :: XP ()
+ XMonad.Prompt: searchPredicate :: XPConfig -> String -> String -> Bool
+ XMonad.Prompt: setDone :: Bool -> XP ()
+ XMonad.Prompt: setInput :: String -> XP ()
+ XMonad.Prompt: setSuccess :: Bool -> XP ()
+ XMonad.Prompt: startOfLine :: XP ()
+ XMonad.Prompt: type XP = StateT XPState IO
+ XMonad.Util.Cursor: setDefaultCursor :: Glyph -> X ()
+ XMonad.Util.Dmenu: menuArgs :: String -> [String] -> [String] -> X String
+ XMonad.Util.Dmenu: menuMapArgs :: String -> [String] -> Map String a -> X (Maybe a)
+ XMonad.Util.Dzen: (>=>) :: (Monad m) => (a -> m b) -> (b -> m c) -> a -> m c
+ XMonad.Util.Dzen: addArgs :: [String] -> DzenConfig
+ XMonad.Util.Dzen: center :: Int -> Int -> ScreenId -> DzenConfig
+ XMonad.Util.Dzen: chomp :: String -> String
+ XMonad.Util.Dzen: dzenConfig :: DzenConfig -> String -> X ()
+ XMonad.Util.Dzen: font :: String -> DzenConfig
+ XMonad.Util.Dzen: hCenter :: Int -> ScreenId -> DzenConfig
+ XMonad.Util.Dzen: onCurr :: (ScreenId -> DzenConfig) -> DzenConfig
+ XMonad.Util.Dzen: timeout :: Rational -> DzenConfig
+ XMonad.Util.Dzen: vCenter :: Int -> ScreenId -> DzenConfig
+ XMonad.Util.Dzen: x :: Int -> DzenConfig
+ XMonad.Util.Dzen: xScreen :: ScreenId -> DzenConfig
+ XMonad.Util.Dzen: y :: Int -> DzenConfig
+ XMonad.Util.EZConfig: mkNamedKeymap :: XConfig l -> [(String, NamedAction)] -> [((KeyMask, KeySym), NamedAction)]
+ XMonad.Util.EZConfig: parseKey :: ReadP KeySym
+ XMonad.Util.ExtensibleState: get :: (ExtensionClass a) => X a
+ XMonad.Util.ExtensibleState: gets :: (ExtensionClass a) => (a -> b) -> X b
+ XMonad.Util.ExtensibleState: modify :: (ExtensionClass a) => (a -> a) -> X ()
+ XMonad.Util.ExtensibleState: put :: (ExtensionClass a) => a -> X ()
+ XMonad.Util.ExtensibleState: remove :: (ExtensionClass a) => a -> X ()
+ XMonad.Util.Font: instance Read Align
+ XMonad.Util.Font: instance Show Align
+ XMonad.Util.Loggers: (<$>) :: (Functor f) => (a -> b) -> f a -> f b
+ XMonad.Util.NamedActions: (^++^) :: (HasName b, HasName b1) => [(d, b)] -> [(d, b1)] -> [(d, NamedAction)]
+ XMonad.Util.NamedActions: NamedAction :: a -> NamedAction
+ XMonad.Util.NamedActions: addDescrKeys :: (HasName b1, HasName b) => ((KeyMask, KeySym), [((KeyMask, KeySym), NamedAction)] -> b) -> (XConfig Layout -> [((KeyMask, KeySym), b1)]) -> XConfig l -> XConfig l
+ XMonad.Util.NamedActions: addName :: String -> X () -> NamedAction
+ XMonad.Util.NamedActions: class HasName a
+ XMonad.Util.NamedActions: data NamedAction
+ XMonad.Util.NamedActions: defaultKeysDescr :: XConfig Layout -> [((KeyMask, KeySym), NamedAction)]
+ XMonad.Util.NamedActions: instance HasName (IO ())
+ XMonad.Util.NamedActions: instance HasName (NamedAction, String)
+ XMonad.Util.NamedActions: instance HasName (X ())
+ XMonad.Util.NamedActions: instance HasName (X (), String)
+ XMonad.Util.NamedActions: instance HasName (X (), [String])
+ XMonad.Util.NamedActions: instance HasName NamedAction
+ XMonad.Util.NamedActions: instance HasName [Char]
+ XMonad.Util.NamedActions: instance Show IncMasterN
+ XMonad.Util.NamedActions: instance Show Resize
+ XMonad.Util.NamedActions: noName :: X () -> NamedAction
+ XMonad.Util.NamedActions: oneName :: (X (), String) -> NamedAction
+ XMonad.Util.NamedActions: sendMessage' :: (Message a, Show a) => a -> NamedAction
+ XMonad.Util.NamedActions: separator :: ((KeyMask, KeySym), NamedAction)
+ XMonad.Util.NamedActions: showKm :: [((KeyMask, KeySym), NamedAction)] -> [String]
+ XMonad.Util.NamedActions: showKmSimple :: [((KeyMask, KeySym), NamedAction)] -> [[Char]]
+ XMonad.Util.NamedActions: spawn' :: String -> NamedAction
+ XMonad.Util.NamedActions: submapName :: (HasName a) => [((KeyMask, KeySym), a)] -> NamedAction
+ XMonad.Util.NamedActions: subtitle :: String -> ((KeyMask, KeySym), NamedAction)
+ XMonad.Util.NamedActions: xMessage :: [((KeyMask, KeySym), NamedAction)] -> NamedAction
+ XMonad.Util.NamedScratchpad: customFloating :: RationalRect -> ManageHook
+ XMonad.Util.NamedScratchpad: defaultFloating :: ManageHook
+ XMonad.Util.NamedScratchpad: hook :: NamedScratchpad -> ManageHook
+ XMonad.Util.NamedScratchpad: nonFloating :: ManageHook
+ XMonad.Util.PositionStore: getPosStore :: X (PositionStore)
+ XMonad.Util.PositionStore: instance ExtensionClass PositionStore
+ XMonad.Util.PositionStore: instance Read PosStoreRectangle
+ XMonad.Util.PositionStore: instance Read PositionStore
+ XMonad.Util.PositionStore: instance Show PosStoreRectangle
+ XMonad.Util.PositionStore: instance Show PositionStore
+ XMonad.Util.PositionStore: instance Typeable PosStoreRectangle
+ XMonad.Util.PositionStore: instance Typeable PositionStore
+ XMonad.Util.PositionStore: modifyPosStore :: (PositionStore -> PositionStore) -> X ()
+ XMonad.Util.PositionStore: posStoreInsert :: PositionStore -> Window -> Rectangle -> Rectangle -> PositionStore
+ XMonad.Util.PositionStore: posStoreMove :: PositionStore -> Window -> Position -> Position -> Rectangle -> Rectangle -> PositionStore
+ XMonad.Util.PositionStore: posStoreQuery :: PositionStore -> Window -> Rectangle -> Maybe Rectangle
+ XMonad.Util.PositionStore: posStoreRemove :: PositionStore -> Window -> PositionStore
+ XMonad.Util.Replace: replace :: IO ()
+ XMonad.Util.Run: hPutStr :: Handle -> String -> IO ()
+ XMonad.Util.Run: hPutStrLn :: Handle -> String -> IO ()
+ XMonad.Util.Run: safeSpawnProg :: (MonadIO m) => FilePath -> m ()
+ XMonad.Util.SpawnOnce: instance ExtensionClass SpawnOnce
+ XMonad.Util.SpawnOnce: instance Read SpawnOnce
+ XMonad.Util.SpawnOnce: instance Show SpawnOnce
+ XMonad.Util.SpawnOnce: instance Typeable SpawnOnce
+ XMonad.Util.SpawnOnce: spawnOnce :: String -> X ()
+ XMonad.Util.StringProp: getStringListProp :: (MonadIO m) => Display -> StringProp -> m [String]
+ XMonad.Util.StringProp: getStringProp :: (MonadIO m) => Display -> StringProp -> m (Maybe [Char])
+ XMonad.Util.StringProp: setStringListProp :: (MonadIO m) => Display -> StringProp -> [String] -> m ()
+ XMonad.Util.StringProp: setStringProp :: (MonadIO m) => Display -> StringProp -> [Char] -> m ()
+ XMonad.Util.StringProp: type StringProp = String
+ XMonad.Util.Types: D :: Direction2D
+ XMonad.Util.Types: L :: Direction2D
+ XMonad.Util.Types: Next :: Direction1D
+ XMonad.Util.Types: Prev :: Direction1D
+ XMonad.Util.Types: R :: Direction2D
+ XMonad.Util.Types: U :: Direction2D
+ XMonad.Util.Types: data Direction1D
+ XMonad.Util.Types: data Direction2D
+ XMonad.Util.Types: instance Bounded Direction2D
+ XMonad.Util.Types: instance Enum Direction2D
+ XMonad.Util.Types: instance Eq Direction1D
+ XMonad.Util.Types: instance Eq Direction2D
+ XMonad.Util.Types: instance Ord Direction2D
+ XMonad.Util.Types: instance Read Direction1D
+ XMonad.Util.Types: instance Read Direction2D
+ XMonad.Util.Types: instance Show Direction1D
+ XMonad.Util.Types: instance Show Direction2D
+ XMonad.Util.Types: instance Typeable Direction1D
+ XMonad.Util.Types: instance Typeable Direction2D
+ XMonad.Util.WindowProperties: Machine :: String -> Property
+ XMonad.Util.WorkspaceCompare: getSortByXineramaPhysicalRule :: X WorkspaceSort
+ XMonad.Util.WorkspaceCompare: getXineramaPhysicalWsCompare :: X WorkspaceCompare
- XMonad.Actions.CycleWS: Next :: WSDirection
+ XMonad.Actions.CycleWS: Next :: Direction1D
- XMonad.Actions.CycleWS: Prev :: WSDirection
+ XMonad.Actions.CycleWS: Prev :: Direction1D
- XMonad.Actions.CycleWS: findWorkspace :: X WorkspaceSort -> WSDirection -> WSType -> Int -> X WorkspaceId
+ XMonad.Actions.CycleWS: findWorkspace :: X WorkspaceSort -> Direction1D -> WSType -> Int -> X WorkspaceId
- XMonad.Actions.CycleWS: moveTo :: WSDirection -> WSType -> X ()
+ XMonad.Actions.CycleWS: moveTo :: Direction1D -> WSType -> X ()
- XMonad.Actions.CycleWS: shiftTo :: WSDirection -> WSType -> X ()
+ XMonad.Actions.CycleWS: shiftTo :: Direction1D -> WSType -> X ()
- XMonad.Actions.GridSelect: GSConfig :: Integer -> Integer -> Integer -> (a -> Bool -> X (String, String)) -> String -> Double -> Double -> GSConfig a
+ XMonad.Actions.GridSelect: GSConfig :: Integer -> Integer -> Integer -> (a -> Bool -> X (String, String)) -> String -> NavigateMap -> Double -> Double -> GSConfig a
- XMonad.Actions.GridSelect: defaultColorizer :: String -> Bool -> X (String, String)
+ XMonad.Actions.GridSelect: defaultColorizer :: (HasColorizer a) => a -> Bool -> X (String, String)
- XMonad.Actions.GridSelect: defaultGSConfig :: GSConfig Window
+ XMonad.Actions.GridSelect: defaultGSConfig :: (HasColorizer a) => GSConfig a
- XMonad.Actions.MouseGestures: D :: Direction
+ XMonad.Actions.MouseGestures: D :: Direction2D
- XMonad.Actions.MouseGestures: L :: Direction
+ XMonad.Actions.MouseGestures: L :: Direction2D
- XMonad.Actions.MouseGestures: R :: Direction
+ XMonad.Actions.MouseGestures: R :: Direction2D
- XMonad.Actions.MouseGestures: U :: Direction
+ XMonad.Actions.MouseGestures: U :: Direction2D
- XMonad.Actions.MouseGestures: mkCollect :: (MonadIO m, MonadIO m') => m (Direction -> m' [Direction], m' [Direction])
+ XMonad.Actions.MouseGestures: mkCollect :: (MonadIO m, MonadIO m') => m (Direction2D -> m' [Direction2D], m' [Direction2D])
- XMonad.Actions.MouseGestures: mouseGesture :: Map [Direction] (Window -> X ()) -> Window -> X ()
+ XMonad.Actions.MouseGestures: mouseGesture :: Map [Direction2D] (Window -> X ()) -> Window -> X ()
- XMonad.Actions.MouseGestures: mouseGestureH :: (Direction -> X ()) -> X () -> X ()
+ XMonad.Actions.MouseGestures: mouseGestureH :: (Direction2D -> X ()) -> X () -> X ()
- XMonad.Actions.SpawnOn: manageSpawn :: Spawner -> ManageHook
+ XMonad.Actions.SpawnOn: manageSpawn :: ManageHook
- XMonad.Actions.SpawnOn: shellPromptHere :: Spawner -> XPConfig -> X ()
+ XMonad.Actions.SpawnOn: shellPromptHere :: XPConfig -> X ()
- XMonad.Actions.SpawnOn: shellPromptOn :: Spawner -> WorkspaceId -> XPConfig -> X ()
+ XMonad.Actions.SpawnOn: shellPromptOn :: WorkspaceId -> XPConfig -> X ()
- XMonad.Actions.SpawnOn: spawnHere :: Spawner -> String -> X ()
+ XMonad.Actions.SpawnOn: spawnHere :: String -> X ()
- XMonad.Actions.SpawnOn: spawnOn :: Spawner -> WorkspaceId -> String -> X ()
+ XMonad.Actions.SpawnOn: spawnOn :: WorkspaceId -> String -> X ()
- XMonad.Actions.SwapWorkspaces: Next :: WSDirection
+ XMonad.Actions.SwapWorkspaces: Next :: Direction1D
- XMonad.Actions.SwapWorkspaces: Prev :: WSDirection
+ XMonad.Actions.SwapWorkspaces: Prev :: Direction1D
- XMonad.Actions.SwapWorkspaces: swapTo :: WSDirection -> X ()
+ XMonad.Actions.SwapWorkspaces: swapTo :: Direction1D -> X ()
- XMonad.Actions.WindowNavigation: D :: Direction
+ XMonad.Actions.WindowNavigation: D :: Direction2D
- XMonad.Actions.WindowNavigation: L :: Direction
+ XMonad.Actions.WindowNavigation: L :: Direction2D
- XMonad.Actions.WindowNavigation: R :: Direction
+ XMonad.Actions.WindowNavigation: R :: Direction2D
- XMonad.Actions.WindowNavigation: U :: Direction
+ XMonad.Actions.WindowNavigation: U :: Direction2D
- XMonad.Actions.WindowNavigation: WNGo :: Direction -> WNAction
+ XMonad.Actions.WindowNavigation: WNGo :: Direction2D -> WNAction
- XMonad.Actions.WindowNavigation: WNSwap :: Direction -> WNAction
+ XMonad.Actions.WindowNavigation: WNSwap :: Direction2D -> WNAction
- XMonad.Actions.WindowNavigation: go :: IORef WNState -> Direction -> X ()
+ XMonad.Actions.WindowNavigation: go :: IORef WNState -> Direction2D -> X ()
- XMonad.Actions.WindowNavigation: swap :: IORef WNState -> Direction -> X ()
+ XMonad.Actions.WindowNavigation: swap :: IORef WNState -> Direction2D -> X ()
- XMonad.Hooks.DynamicHooks: addDynamicHook :: IORef DynamicHooks -> ManageHook -> X ()
+ XMonad.Hooks.DynamicHooks: addDynamicHook :: ManageHook -> X ()
- XMonad.Hooks.DynamicHooks: dynamicMasterHook :: IORef DynamicHooks -> ManageHook
+ XMonad.Hooks.DynamicHooks: dynamicMasterHook :: ManageHook
- XMonad.Hooks.DynamicHooks: oneShotHook :: IORef DynamicHooks -> Query Bool -> ManageHook -> X ()
+ XMonad.Hooks.DynamicHooks: oneShotHook :: Query Bool -> ManageHook -> X ()
- XMonad.Hooks.DynamicHooks: updateDynamicHook :: IORef DynamicHooks -> (ManageHook -> ManageHook) -> X ()
+ XMonad.Hooks.DynamicHooks: updateDynamicHook :: (ManageHook -> ManageHook) -> X ()
- XMonad.Hooks.FadeInactive: fadeInactiveLogHook :: Integer -> X ()
+ XMonad.Hooks.FadeInactive: fadeInactiveLogHook :: Rational -> X ()
- XMonad.Hooks.FadeInactive: fadeOut :: Integer -> Window -> X ()
+ XMonad.Hooks.FadeInactive: fadeOut :: Rational -> Window -> X ()
- XMonad.Hooks.FadeInactive: fadeOutLogHook :: (Window -> X Bool) -> Integer -> X ()
+ XMonad.Hooks.FadeInactive: fadeOutLogHook :: Query Rational -> X ()
- XMonad.Hooks.FadeInactive: isUnfocused :: Window -> X Bool
+ XMonad.Hooks.FadeInactive: isUnfocused :: Query Bool
- XMonad.Hooks.FadeInactive: setOpacity :: Window -> Integer -> X ()
+ XMonad.Hooks.FadeInactive: setOpacity :: Window -> Rational -> X ()
- XMonad.Hooks.ManageDocks: ToggleStrut :: Direction -> ToggleStruts
+ XMonad.Hooks.ManageDocks: ToggleStrut :: Direction2D -> ToggleStruts
- XMonad.Hooks.ManageDocks: avoidStrutsOn :: (LayoutClass l a) => [Direction] -> l a -> ModifiedLayout AvoidStruts l a
+ XMonad.Hooks.ManageDocks: avoidStrutsOn :: (LayoutClass l a) => [Direction2D] -> l a -> ModifiedLayout AvoidStruts l a
- XMonad.Hooks.ManageDocks: calcGap :: [Direction] -> X (Rectangle -> Rectangle)
+ XMonad.Hooks.ManageDocks: calcGap :: Set Direction2D -> X (Rectangle -> Rectangle)
- XMonad.Layout.BorderResize: BR :: [BorderWithWin] -> BorderResize a
+ XMonad.Layout.BorderResize: BR :: (Map Window RectWithBorders) -> BorderResize a
- XMonad.Layout.Decoration: Theme :: String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Dimension -> Dimension -> Theme
+ XMonad.Layout.Decoration: Theme :: String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Dimension -> Dimension -> [(String, Align)] -> Theme
- XMonad.Layout.DwmStyle: Theme :: String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Dimension -> Dimension -> Theme
+ XMonad.Layout.DwmStyle: Theme :: String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Dimension -> Dimension -> [(String, Align)] -> Theme
- XMonad.Layout.Gaps: D :: Direction
+ XMonad.Layout.Gaps: D :: Direction2D
- XMonad.Layout.Gaps: DecGap :: !Int -> !Direction -> GapMessage
+ XMonad.Layout.Gaps: DecGap :: !Int -> !Direction2D -> GapMessage
- XMonad.Layout.Gaps: IncGap :: !Int -> !Direction -> GapMessage
+ XMonad.Layout.Gaps: IncGap :: !Int -> !Direction2D -> GapMessage
- XMonad.Layout.Gaps: L :: Direction
+ XMonad.Layout.Gaps: L :: Direction2D
- XMonad.Layout.Gaps: R :: Direction
+ XMonad.Layout.Gaps: R :: Direction2D
- XMonad.Layout.Gaps: ToggleGap :: !Direction -> GapMessage
+ XMonad.Layout.Gaps: ToggleGap :: !Direction2D -> GapMessage
- XMonad.Layout.Gaps: U :: Direction
+ XMonad.Layout.Gaps: U :: Direction2D
- XMonad.Layout.Gaps: type GapSpec = [(Direction, Int)]
+ XMonad.Layout.Gaps: type GapSpec = [(Direction2D, Int)]
- XMonad.Layout.Monitor: Monitor :: Property -> Rectangle -> Bool -> String -> Bool -> Integer -> Monitor a
+ XMonad.Layout.Monitor: Monitor :: Property -> Rectangle -> Bool -> String -> Bool -> Rational -> Monitor a
- XMonad.Layout.Monitor: opacity :: Monitor a -> Integer
+ XMonad.Layout.Monitor: opacity :: Monitor a -> Rational
- XMonad.Layout.Mosaic: changeMaster :: Rational -> [Rational] -> [Rational]
+ XMonad.Layout.Mosaic: changeMaster :: (Rational -> Rational) -> X ()
- XMonad.Layout.MultiToggle: transform :: (Transformer t a, LayoutClass l a) => t -> l a -> (forall l'. (LayoutClass l' a) => l' a -> b) -> b
+ XMonad.Layout.MultiToggle: transform :: (Transformer t a, LayoutClass l a) => t -> l a -> (forall l'. (LayoutClass l' a) => l' a -> (l' a -> l a) -> b) -> b
- XMonad.Layout.SimpleDecoration: Theme :: String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Dimension -> Dimension -> Theme
+ XMonad.Layout.SimpleDecoration: Theme :: String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Dimension -> Dimension -> [(String, Align)] -> Theme
- XMonad.Layout.SubLayouts: pullGroup :: Direction -> Navigate
+ XMonad.Layout.SubLayouts: pullGroup :: Direction2D -> Navigate
- XMonad.Layout.SubLayouts: pullWindow :: Direction -> Navigate
+ XMonad.Layout.SubLayouts: pullWindow :: Direction2D -> Navigate
- XMonad.Layout.SubLayouts: pushGroup :: Direction -> Navigate
+ XMonad.Layout.SubLayouts: pushGroup :: Direction2D -> Navigate
- XMonad.Layout.SubLayouts: pushWindow :: Direction -> Navigate
+ XMonad.Layout.SubLayouts: pushWindow :: Direction2D -> Navigate
- XMonad.Layout.Tabbed: Theme :: String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Dimension -> Dimension -> Theme
+ XMonad.Layout.Tabbed: Theme :: String -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Dimension -> Dimension -> [(String, Align)] -> Theme
- XMonad.Layout.WindowNavigation: Apply :: (Window -> X ()) -> Direction -> Navigate
+ XMonad.Layout.WindowNavigation: Apply :: (Window -> X ()) -> Direction2D -> Navigate
- XMonad.Layout.WindowNavigation: D :: Direction
+ XMonad.Layout.WindowNavigation: D :: Direction2D
- XMonad.Layout.WindowNavigation: Go :: Direction -> Navigate
+ XMonad.Layout.WindowNavigation: Go :: Direction2D -> Navigate
- XMonad.Layout.WindowNavigation: L :: Direction
+ XMonad.Layout.WindowNavigation: L :: Direction2D
- XMonad.Layout.WindowNavigation: Move :: Direction -> Navigate
+ XMonad.Layout.WindowNavigation: Move :: Direction2D -> Navigate
- XMonad.Layout.WindowNavigation: R :: Direction
+ XMonad.Layout.WindowNavigation: R :: Direction2D
- XMonad.Layout.WindowNavigation: Swap :: Direction -> Navigate
+ XMonad.Layout.WindowNavigation: Swap :: Direction2D -> Navigate
- XMonad.Layout.WindowNavigation: U :: Direction
+ XMonad.Layout.WindowNavigation: U :: Direction2D
- XMonad.Prompt: XPC :: String -> String -> String -> String -> String -> String -> !Dimension -> XPPosition -> !Dimension -> !Int -> ([String] -> [String]) -> String -> Maybe Int -> Bool -> XPConfig
+ XMonad.Prompt: XPC :: String -> String -> String -> String -> String -> String -> !Dimension -> XPPosition -> !Dimension -> !Int -> ([String] -> [String]) -> Map (KeyMask, KeySym) (XP ()) -> KeySym -> String -> Maybe Int -> Bool -> (String -> String -> Bool) -> XPConfig
- XMonad.Util.NamedScratchpad: NS :: String -> String -> Query Bool -> Maybe RationalRect -> NamedScratchpad
+ XMonad.Util.NamedScratchpad: NS :: String -> String -> Query Bool -> ManageHook -> NamedScratchpad
- XMonad.Util.Run: runProcessWithInput :: FilePath -> [String] -> String -> IO String
+ XMonad.Util.Run: runProcessWithInput :: (MonadIO m) => FilePath -> [String] -> String -> m String
- XMonad.Util.Run: runProcessWithInputAndWait :: FilePath -> [String] -> String -> Int -> IO ()
+ XMonad.Util.Run: runProcessWithInputAndWait :: (MonadIO m) => FilePath -> [String] -> String -> Int -> m ()
- XMonad.Util.Run: safeSpawn :: (MonadIO m) => FilePath -> String -> m ()
+ XMonad.Util.Run: safeSpawn :: (MonadIO m) => FilePath -> [String] -> m ()
- XMonad.Util.Run: spawnPipe :: String -> IO Handle
+ XMonad.Util.Run: spawnPipe :: (MonadIO m) => String -> m Handle

Files

README view
@@ -1,28 +1,82 @@-3rd party xmonad extensions and contributions.+  xmonad-contrib : third party extensions to the xmonad window manager -Build and install through Cabal as for other Haskell packages:+                           http://xmonad.org -        runhaskell Setup configure --user --prefix=$HOME-        runhaskell Setup build-        runhaskell Setup install --user+    You need the ghc compiler and xmonad window manager installed in+    order to use these extensions. -(You may want to remove the --user flag when installing as root.)+    For installation and configuration instructions, please see the+    xmonad website, the documents included with the xmonad source+    distribution, and online haddock documentation: -scripts/ contains further external programs useful with xmonad.+    http://www.xmonad.org/xmonad-docs -Haskell code contributed to this repo should live under the-appropriate subdivision of the 'XMonad.' namespace (currently includes-Actions, Config, Hooks, Layout, Prompt, and Util). For example, to use-the Mosaic layout, one would import:+------------------------------------------------------------------------ - XMonad.Layout.Mosaic+Changelogs +    For a list of changes since the 0.8.x releases, see:++http://www.haskell.org/haskellwiki/Xmonad/Notable_changes_since_0.8+ ------------------------------------------------------------------------ +Updates to XMonadContrib-0.9 that may Require Changes to ~/.xmonad/xmonad.hs++    Please see the Changelogs and xmonad-contrib haddock documentation+    links for further details regarding the following changes.++    * XMonad.Hooks.EwmhDesktops no longer uses layoutHook, the+    ewmhDesktopsLayout modifier has been removed from xmonad-contrib. It+    uses logHook, handleEventHook, and startupHook instead and provides+    a convenient function 'ewmh' to add EWMH support to a defaultConfig.++    * Most DynamicLog users can continue with configs unchanged, but users+    of the quickbar functions 'xmobar' or 'dzen' will need to change+    xmonad.hs: their types have changed to allow easier composition with+    other XConfig modifiers. The 'dynamicLogDzen' and 'dynamicLogXmobar'+    functions have been removed.++    * WindowGo or safeSpawn users may need to change command lines due to+    safeSpawn changes.++    * People explicitly referencing the "SP" scratchpad workspace should+    change it to "NSP" which is also used by the new Util.NamedScratchpad.++    * (Optional) People who explicitly use swapMaster in key or mouse+    bindings should change it to shiftMaster. It's the current default+    used where swapMaster had been used previously. It works better than+    swapMaster when using floating and tiled windows together on the+    same workspace.++------------------------------------------------------------------------++Getting or updating XMonadContrib++    latest release: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmonad-contrib++    darcs version:  darcs get http://code.haskell.org/XMonadContrib++    (To use darcs xmonad-contrib you must also use the darcs version+    of xmonad.)++------------------------------------------------------------------------++Contributing++    Haskell code contributed to this repo should live under the+    appropriate subdivision of the 'XMonad.' namespace (currently+    includes Actions, Config, Hooks, Layout, Prompt, and Util). For+    example, to use the Grid layout, one would import:++        XMonad.Layout.Grid++    For further details, see the documentation for the+    XMonad.Doc.Developing module and http://xmonad.org website.++------------------------------------------------------------------------+ Code submitted to the contrib repo is licensed under the same license as xmonad itself, with copyright held by the authors.  --------------------------------------------------------------------------Documentation for the extensions and configuration system is available-in Haddock form in the XMonad.Doc module and submodules.
XMonad/Actions/BluetileCommands.hs view
@@ -8,18 +8,39 @@ -- Stability   :  unstable -- Portability :  not portable --+-- This is a list of selected commands that can be made available using+-- "XMonad.Hooks.ServerMode" to allow external programs to control+-- the window manager. Bluetile (<http://projects.haskell.org/bluetile/>)+-- uses this to enable its dock application to do things like changing+-- workspaces and layouts.+-- -----------------------------------------------------------------------------  module XMonad.Actions.BluetileCommands (-                             bluetileCommands-                              ) where+    -- * Usage+    -- $usage+    bluetileCommands+    ) where  import XMonad import qualified XMonad.StackSet as W import XMonad.Layout.LayoutCombinators import System.Exit --- | Generate a list of commands to switch to workspaces (on the given screen).+-- $usage+--+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- >    import XMonad.Hooks.ServerMode+-- >    import XMonad.Actions.BluetileCommands+--+-- Then edit your @handleEventHook@:+--+-- > main = xmonad defaultConfig { handleEventHook = serverModeEventHook' bluetileCommands }+--+-- See the documentation of "XMonad.Hooks.ServerMode" for details on+-- how to actually invoke the commands from external programs.+ workspaceCommands :: Int -> X [(String, X ())] workspaceCommands sid = asks (workspaces . config) >>= \spaces -> return                             [(("greedyView" ++ show i),@@ -51,9 +72,11 @@  bluetileCommands :: X [(String, X ())] bluetileCommands = do+    let restartCommand = [ ("restart bluetile", restart "bluetile" True) ]     wscmds0 <- workspaceCommands 0     wscmds1 <- workspaceCommands 1-    return $ wscmds0 ++ layoutCommands 0 ++ masterAreaCommands 0 ++ quitCommands+    return $ restartCommand+                ++ wscmds0 ++ layoutCommands 0 ++ masterAreaCommands 0 ++ quitCommands                 ++ wscmds1 ++ layoutCommands 1 ++ masterAreaCommands 1 ++ quitCommands  activateScreen :: Int -> X ()
XMonad/Actions/Commands.hs view
@@ -41,7 +41,7 @@ -- -- Then add a keybinding to the runCommand action: ----- >    , ((modMask x .|. controlMask, xK_y), commands >>= runCommand)+-- >    , ((modm .|. controlMask, xK_y), commands >>= runCommand) -- -- and define the list of commands you want to use: --@@ -82,23 +82,22 @@     wscmds <- workspaceCommands     return $ wscmds ++ screenCommands ++ otherCommands  where-    sr = broadcastMessage ReleaseResources     otherCommands =         [ ("shrink"              , sendMessage Shrink                               )         , ("expand"              , sendMessage Expand                               )         , ("next-layout"         , sendMessage NextLayout                           )         , ("default-layout"      , asks (layoutHook . config) >>= setLayout         )-        , ("restart-wm"          , sr >> restart "xmonad" True                       )-        , ("restart-wm-no-resume", sr >> restart "xmonad" False                      )+        , ("restart-wm"          , restart "xmonad" True                            )+        , ("restart-wm-no-resume", restart "xmonad" False                           )         , ("xterm"               , spawn =<< asks (terminal .  config)              )         , ("run"                 , spawn "exe=`dmenu_path | dmenu -b` && exec $exe" )         , ("kill"                , kill                                             )         , ("refresh"             , refresh                                          )-        , ("focus-up"            , windows $ focusUp                                )-        , ("focus-down"          , windows $ focusDown                              )-        , ("swap-up"             , windows $ swapUp                                 )-        , ("swap-down"           , windows $ swapDown                               )-        , ("swap-master"         , windows $ swapMaster                             )+        , ("focus-up"            , windows focusUp                                  )+        , ("focus-down"          , windows focusDown                                )+        , ("swap-up"             , windows swapUp                                   )+        , ("swap-down"           , windows swapDown                                 )+        , ("swap-master"         , windows swapMaster                               )         , ("sink"                , withFocused $ windows . sink                     )         , ("quit-wm"             , io $ exitWith ExitSuccess                        )         ]
XMonad/Actions/ConstrainedResize.hs view
@@ -5,7 +5,7 @@ -- License     :  BSD3-style (see LICENSE) -- -- Maintainer  :  <dougal@dougalstanton.net>--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- Lets you constrain the aspect ratio of a floating@@ -31,8 +31,8 @@ -- -- Then add something like the following to your mouse bindings: ----- >     , ((modMask x, button3),               (\w -> focus w >> Sqr.mouseResizeWindow w False))--- >     , ((modMask x .|. shiftMask, button3), (\w -> focus w >> Sqr.mouseResizeWindow w True ))+-- >     , ((modm, button3),               (\w -> focus w >> Sqr.mouseResizeWindow w False))+-- >     , ((modm .|. shiftMask, button3), (\w -> focus w >> Sqr.mouseResizeWindow w True )) -- -- The line without the shiftMask replaces the standard mouse resize -- function call, so it's not completely necessary but seems neater
XMonad/Actions/CopyWindow.hs view
@@ -9,7 +9,7 @@ -- Stability   :  unstable -- Portability :  unportable ----- Provides a binding to duplicate a window on multiple workspaces,+-- Provides bindings to duplicate a window on multiple workspaces, -- providing dwm-like tagging functionality. -- -----------------------------------------------------------------------------@@ -19,12 +19,16 @@                                  -- $usage                                  copy, copyToAll, copyWindow, runOrCopy                                  , killAllOtherCopies, kill1+                                 -- * Highlight workspaces containing copies in logHook+                                 -- $logHook+                                 , wsContainingCopies                                 ) where -import Prelude hiding (filter)-import Control.Monad (filterM)+import XMonad+import Control.Arrow ((&&&)) import qualified Data.List as L-import XMonad hiding (modify, workspaces)++import XMonad.Actions.WindowGo import qualified XMonad.StackSet as W  -- $usage@@ -38,7 +42,7 @@ -- > -- mod-[1..9] @@ Switch to workspace N -- > -- mod-shift-[1..9] @@ Move client to workspace N -- > -- mod-control-shift-[1..9] @@ Copy client to workspace N--- > [((m .|. modMask x, k), windows $ f i)+-- > [((m .|. modm, k), windows $ f i) -- >     | (i, k) <- zip (workspaces x) [xK_1 ..] -- >     , (f, m) <- [(W.view, 0), (W.shift, shiftMask), (copy, shiftMask .|. controlMask)]] --@@ -50,12 +54,12 @@ -- You may also wish to redefine the binding to kill a window so it only -- removes it from the current workspace, if it's present elsewhere: ----- >  , ((modMask x .|. shiftMask, xK_c     ), kill1) -- @@ Close the focused window+-- >  , ((modm .|. shiftMask, xK_c     ), kill1) -- @@ Close the focused window ----- Instead of copying a window from a workset to a workset maybe you don't+-- Instead of copying a window from one workspace to another maybe you don't -- want to have to remember where you placed it.  For that consider: ----- >  , ((modMask x, xK_b    ), runOrCopy "firefox" (className =? "Firefox")) -- @@ run or copy firefox+-- >  , ((modm, xK_b    ), runOrCopy "firefox" (className =? "Firefox")) -- @@ run or copy firefox -- -- Another possibility which this extension provides is 'making window -- always visible' (i.e. always on current workspace), similar to corresponding@@ -65,22 +69,36 @@ -- -- Here is the example of keybindings which provide these actions: ----- >  , ((modMask x, xK_v ), windows copyToAll) -- @@ Make focused window always visible--- >  , ((modMask x .|. shiftMask, xK_v ),  killAllOtherCopies) -- @@ Toggle window state back+-- >  , ((modm, xK_v ), windows copyToAll) -- @@ Make focused window always visible+-- >  , ((modm .|. shiftMask, xK_v ),  killAllOtherCopies) -- @@ Toggle window state back -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings". --- | copy. Copy the focused window to a new workspace.+-- $logHook+-- To distinguish workspaces containing copies of the focused window use+-- something like:+--+-- > sampleLogHook h = do+-- >    copies <- wsContainingCopies+-- >    let check ws | ws `elem` copies = pad . xmobarColor "red" "black" $ ws+-- >                 | otherwise = pad ws+-- >    dynamicLogWithPP myPP {ppHidden = check, ppOutput = hPutStrLn h}+-- >+-- > main = do+-- >    h <- spawnPipe "xmobar"+-- >    xmonad defaultConfig { logHook = sampleLogHook h }++-- | Copy the focused window to a workspace. copy :: (Eq s, Eq i, Eq a) => i -> W.StackSet i l a s sd -> W.StackSet i l a s sd copy n s | Just w <- W.peek s = copyWindow w n s          | otherwise = s --- | copyToAll. Copy the focused window to all of workspaces.+-- | Copy the focused window to all workspaces. copyToAll :: (Eq s, Eq i, Eq a) => W.StackSet i l a s sd -> W.StackSet i l a s sd copyToAll s = foldr copy s $ map W.tag (W.workspaces s) --- | copyWindow.  Copy a window to a new workspace+-- | Copy an arbitrary window to a workspace. copyWindow :: (Eq a, Eq i, Eq s) => a -> i -> W.StackSet i l a s sd -> W.StackSet i l a s sd copyWindow w n = copy'     where copy' s = if n `W.tagMember` s@@ -92,28 +110,23 @@                                              else Just $ W.Stack a (L.delete a l) (L.delete a (t:r))) s  --- | runOrCopy .  runOrCopy will run the provided shell command unless it can+-- | runOrCopy will run the provided shell command unless it can --  find a specified window in which case it will copy the window to --  the current workspace.  Similar to (i.e., stolen from) "XMonad.Actions.WindowGo". runOrCopy :: String -> Query Bool -> X () runOrCopy = copyMaybe . spawn --- | copyMaybe. Copies "XMonad.Actions.WindowGo" ('raiseMaybe')---   TODO: Factor out and improve with regard to WindowGo.+-- | Copy a window if it exists, run the first argument otherwise. copyMaybe :: X () -> Query Bool -> X ()-copyMaybe f thatUserQuery = withWindowSet $ \s -> do-    maybeResult <- filterM (runQuery thatUserQuery) (W.allWindows s)-    case maybeResult of-        []    -> f-        (x:_) -> windows $ copyWindow x (W.currentTag s)-+copyMaybe f qry = ifWindow qry copyWin f+    where copyWin = ask >>= \w -> doF (\ws -> copyWindow w (W.currentTag ws) ws)  -- | Remove the focused window from this workspace.  If it's present in no -- other workspace, then kill it instead. If we do kill it, we'll get a -- delete notify back from X. -- -- There are two ways to delete a window. Either just kill it, or if it--- supports the delete protocol, send a delete event (e.g. firefox)+-- supports the delete protocol, send a delete event (e.g. firefox). kill1 :: X () kill1 = do ss <- gets windowset            whenJust (W.peek ss) $ \w -> if W.member w $ delete'' w ss@@ -121,10 +134,8 @@                                       else kill     where delete'' w = W.modify Nothing (W.filter (/= w)) --- | Kill all other copies of focused window (if they're present)--- 'All other' means here 'copies, which are not on current workspace'------ TODO: Call this function after 'copyToAll'?+-- | Kill all other copies of focused window (if they're present).+-- 'All other' means here 'copies which are not on the current workspace'. killAllOtherCopies :: X () killAllOtherCopies = do ss <- gets windowset                         whenJust (W.peek ss) $ \w -> windows $@@ -135,3 +146,18 @@                                   map (delWinFromWorkspace w . W.tag) $                                   W.hidden ss ++ map W.workspace (W.visible ss)       delWinFromWorkspace w wid = W.modify Nothing (W.filter (/= w)) . W.view wid++-- | A list of hidden workspaces containing a copy of the focused window.+wsContainingCopies :: X [WorkspaceId]+wsContainingCopies = do+    ws <- gets windowset+    return $ copiesOfOn (W.peek ws) (taggedWindows $ W.hidden ws)++-- | Get a list of tuples (tag, [Window]) for each workspace.+taggedWindows :: [W.Workspace i l a] -> [(i, [a])]+taggedWindows = map $ W.tag &&& W.integrate' . W.stack++-- | Get tags with copies of the focused window (if present.)+copiesOfOn :: (Eq a) => Maybe a -> [(i, [a])] -> [i]+copiesOfOn foc tw = maybe [] hasCopyOf foc+  where hasCopyOf f = map fst $ filter ((f `elem` ) . snd) tw
XMonad/Actions/CycleRecentWS.hs view
@@ -30,7 +30,7 @@ -- -- > import XMonad.Actions.CycleRecentWS -- >--- >   , ((modMask x, xK_Tab), cycleRecentWS [xK_Alt_L] xK_Tab xK_grave)+-- >   , ((modm, xK_Tab), cycleRecentWS [xK_Alt_L] xK_Tab xK_grave) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".
XMonad/Actions/CycleSelectedLayouts.hs view
@@ -25,12 +25,12 @@  -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:--- +-- -- > import XMonad hiding ((|||)) -- > import XMonad.Layout.LayoutCombinators ((|||)) -- > import XMonad.Actions.CycleSelectedLayouts ----- >   , ((modMask x,  xK_t ),   cycleThroughLayouts ["Tall", "Mirror Tall"])+-- >   , ((modm,  xK_t ),   cycleThroughLayouts ["Tall", "Mirror Tall"]) -- -- Make sure you are using NewSelect from XMonad.Layout.LayoutCombinators, -- rather than the Select defined in xmonad core.
XMonad/Actions/CycleWS.hs view
@@ -42,7 +42,11 @@                               , prevWS                               , shiftToNext                               , shiftToPrev++                                -- * Toggling the previous workspace+                                -- $toggling                               , toggleWS+                              , toggleOrView                                  -- * Moving between screens (xinerama) @@ -56,23 +60,28 @@                                 -- * Moving between workspaces, take two!                                 -- $taketwo -                              , WSDirection(..)+                              , Direction1D(..)                               , WSType(..)                                , shiftTo                               , moveTo+                              , doTo                                  -- * The mother-combinator                                , findWorkspace+                              , toggleOrDoSkip+                              , skipTags                               ) where +import Control.Monad ( unless ) import Data.List ( findIndex ) import Data.Maybe ( isNothing, isJust )  import XMonad hiding (workspaces) import XMonad.StackSet hiding (filter)+import XMonad.Util.Types import XMonad.Util.WorkspaceCompare  -- $usage@@ -82,27 +91,27 @@ -- > -- > -- a basic CycleWS setup -- >--- >   , ((modMask x,               xK_Down),  nextWS)--- >   , ((modMask x,               xK_Up),    prevWS)--- >   , ((modMask x .|. shiftMask, xK_Down),  shiftToNext)--- >   , ((modMask x .|. shiftMask, xK_Up),    shiftToPrev)--- >   , ((modMask x,               xK_Right), nextScreen)--- >   , ((modMask x,               xK_Left),  prevScreen)--- >   , ((modMask x .|. shiftMask, xK_Right), shiftNextScreen)--- >   , ((modMask x .|. shiftMask, xK_Left),  shiftPrevScreen)--- >   , ((modMask x,               xK_z),     toggleWS)+-- >   , ((modm,               xK_Down),  nextWS)+-- >   , ((modm,               xK_Up),    prevWS)+-- >   , ((modm .|. shiftMask, xK_Down),  shiftToNext)+-- >   , ((modm .|. shiftMask, xK_Up),    shiftToPrev)+-- >   , ((modm,               xK_Right), nextScreen)+-- >   , ((modm,               xK_Left),  prevScreen)+-- >   , ((modm .|. shiftMask, xK_Right), shiftNextScreen)+-- >   , ((modm .|. shiftMask, xK_Left),  shiftPrevScreen)+-- >   , ((modm,               xK_z),     toggleWS) -- -- If you want to follow the moved window, you can use both actions: ----- >   , ((modMask x .|. shiftMask, xK_Down), shiftToNext >> nextWS)--- >   , ((modMask x .|. shiftMask, xK_Up),   shiftToPrev >> prevWS)+-- >   , ((modm .|. shiftMask, xK_Down), shiftToNext >> nextWS)+-- >   , ((modm .|. shiftMask, xK_Up),   shiftToPrev >> prevWS) -- -- You can also get fancier with 'moveTo', 'shiftTo', and 'findWorkspace'. -- For example: ----- >   , ((modMask x     , xK_f), moveTo Next EmptyWS)  -- find a free workspace--- >   , ((modMask x .|. controlMask, xK_Right),        -- a crazy keybinding!--- >         do t <- findWorkspace getXineramaWsCompare Next NonEmptyWS 2+-- >   , ((modm     , xK_f), moveTo Next EmptyWS)  -- find a free workspace+-- >   , ((modm .|. controlMask, xK_Right),        -- a crazy keybinding!+-- >         do t <- findWorkspace getSortByXineramaRule Next NonEmptyWS 2 -- >            windows . view $ t                                         ) -- -- For detailed instructions on editing your key bindings, see@@ -135,10 +144,48 @@ shiftToPrev :: X () shiftToPrev = shiftBy (-1) +-- $toggling+ -- | Toggle to the workspace displayed previously. toggleWS :: X ()-toggleWS = windows $ view =<< tag . head . hidden+toggleWS = do+    hs <- gets (hidden . windowset)+    unless (null hs) (windows . view . tag $ head hs) +-- | 'XMonad.StackSet.greedyView' a workspace, or if already there, view+-- the previously displayed workspace ala weechat. Change @greedyView@ to+-- @toggleOrView@ in your workspace bindings as in the 'XMonad.StackSet.view'+-- faq at <http://haskell.org/haskellwiki/Xmonad/Frequently_asked_questions>.+-- For more flexibility see 'toggleOrDoSkip'.+toggleOrView :: WorkspaceId -> X ()+toggleOrView = toggleOrDoSkip [] greedyView++-- | Allows ignoring listed workspace tags (such as scratchpad's \"NSP\") while+-- finding the previously displayed workspace, or choice of different actions,+-- like view, shift, etc.  For example:+--+-- > import qualified XMonad.StackSet as W+-- > import XMonad.Actions.CycleWS+-- >+-- > -- toggleOrView for people who prefer view to greedyView+-- > toggleOrView' = toggleOrDoSkip [] W.view+-- >+-- > -- toggleOrView ignoring scratchpad and named scratchpad workspace+-- > toggleOrViewNoSP = toggleOrDoSkip ["NSP"] W.greedyView+toggleOrDoSkip :: [WorkspaceId] -> (WorkspaceId -> WindowSet -> WindowSet)+                                  -> WorkspaceId -> X ()+toggleOrDoSkip skips f toWS = do+    ws <- gets windowset+    let hs' = hidden ws `skipTags` skips+    if toWS == (tag . workspace $ current ws)+        then unless (null hs') (windows . f . tag $ head hs')+        else windows (f toWS)++-- | List difference ('\\') for workspaces and tags. Removes workspaces+-- matching listed tags from the given workspace list.+skipTags :: (Eq i) => [Workspace i l a] -> [i] -> [Workspace i l a]+skipTags wss ids = filter ((`notElem` ids) . tag) wss+ switchWorkspace :: Int -> X () switchWorkspace d = wsBy d >>= windows . greedyView @@ -166,15 +213,16 @@  -} --- | Direction to cycle through the sort order.-data WSDirection = Next | Prev- -- | What type of workspaces should be included in the cycle? data WSType = EmptyWS     -- ^ cycle through empty workspaces             | NonEmptyWS  -- ^ cycle through non-empty workspaces             | HiddenWS    -- ^ cycle through non-visible workspaces             | HiddenNonEmptyWS  -- ^ cycle through non-empty non-visible workspaces             | AnyWS       -- ^ cycle through all workspaces+            | WSTagGroup Char+                          -- ^ cycle through workspaces in the same group, the+                          --   group name is all characters up to the first+                          --   separator character or the end of the tag             | WSIs (X (WindowSpace -> Bool))                           -- ^ cycle through workspaces satisfying                           --   an arbitrary predicate@@ -189,18 +237,26 @@                                     hi <- wsTypeToPred HiddenWS                                     return (\w -> hi w && ne w) wsTypeToPred AnyWS      = return (const True)+wsTypeToPred (WSTagGroup sep) = do cur <- (groupName.workspace.current) `fmap` gets windowset+                                   return $ (cur ==).groupName+                                   where groupName = takeWhile (/=sep).tag wsTypeToPred (WSIs p)   = p  -- | View the next workspace in the given direction that satisfies --   the given condition.-moveTo :: WSDirection -> WSType -> X ()-moveTo dir t = findWorkspace getSortByIndex dir t 1 >>= windows . greedyView+moveTo :: Direction1D -> WSType -> X ()+moveTo dir t = doTo dir t getSortByIndex (windows . greedyView)  -- | Move the currently focused window to the next workspace in the --   given direction that satisfies the given condition.-shiftTo :: WSDirection -> WSType -> X ()-shiftTo dir t = findWorkspace getSortByIndex dir t 1 >>= windows . shift+shiftTo :: Direction1D -> WSType -> X ()+shiftTo dir t = doTo dir t getSortByIndex (windows . shift) +-- | Using the given sort, find the next workspace in the given+-- direction of the given type, and perform the given action on it.+doTo :: Direction1D -> WSType -> X WorkspaceSort -> (WorkspaceId -> X ()) -> X ()+doTo dir t srt act = findWorkspace srt dir t 1 >>= act+ -- | Given a function @s@ to sort workspaces, a direction @dir@, a --   predicate @p@ on workspaces, and an integer @n@, find the tag of --   the workspace which is @n@ away from the current workspace in@@ -214,7 +270,7 @@ --   that 'moveTo' and 'shiftTo' are implemented by applying @(>>= --   (windows . greedyView))@ and @(>>= (windows . shift))@, respectively, --   to the output of 'findWorkspace'.-findWorkspace :: X WorkspaceSort -> WSDirection -> WSType -> Int -> X WorkspaceId+findWorkspace :: X WorkspaceSort -> Direction1D -> WSType -> Int -> X WorkspaceId findWorkspace s dir t n = findWorkspaceGen s (wsTypeToPred t) (maybeNegate dir n)   where     maybeNegate Next d = d@@ -229,7 +285,7 @@     let cur     = workspace (current ws)         sorted  = sort (workspaces ws)         pivoted = let (a,b) = span ((/= (tag cur)) . tag) sorted in b ++ a-        ws'     = filter wsPred $ pivoted+        ws'     = filter wsPred pivoted         mCurIx  = findWsIndex cur ws'         d'      = if d > 0 then d - 1 else d         next    = if null ws'
XMonad/Actions/CycleWindows.hs view
@@ -9,8 +9,10 @@ -- Portability  : unportable -- -- Provides bindings to cycle windows up or down on the current workspace--- stack while maintaining focus in place. Bindings are available to:+-- stack while maintaining focus in place. --+-- Bindings are available to:+-- -- * Cycle nearby or nth windows into the focused frame -- -- * Cycle a window halfway around the stack@@ -18,11 +20,11 @@ -- * Cycle windows through the focused position. -- -- * Cycle unfocused windows.--- +-- -- These bindings are especially useful with layouts that hide some of -- the windows in the stack, such as Full, "XMonad.Layout.TwoPane" or--- "XMonad.Layout.Mosaic" with three or four panes. See also--- "XMonad.Actions.RotSlaves" for related actions.+-- when using "XMonad.Layout.LimitWindows" to only show three or four+-- panes. See also "XMonad.Actions.RotSlaves" for related actions. ----------------------------------------------------------------------------- module XMonad.Actions.CycleWindows (         -- * Usage@@ -53,6 +55,8 @@ import qualified XMonad.StackSet as W import XMonad.Actions.RotSlaves +import Control.Arrow (second)+ -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file: --@@ -62,15 +66,15 @@ -- > -- >              -- make sure mod matches keysym -- >  , ((mod4Mask,  xK_s), cycleRecentWindows [xK_Super_L] xK_s xK_w)--- >  , ((modMask x, xK_z), rotOpposite)--- >  , ((modMask x                , xK_i), rotUnfocusedUp)--- >  , ((modMask x                , xK_u), rotUnfocusedDown)--- >  , ((modMask x .|. controlMask, xK_i), rotFocusedUp)--- >  , ((modMask x .|. controlMask, xK_u), rotFocusedDown)+-- >  , ((modm, xK_z), rotOpposite)+-- >  , ((modm                , xK_i), rotUnfocusedUp)+-- >  , ((modm                , xK_u), rotUnfocusedDown)+-- >  , ((modm .|. controlMask, xK_i), rotFocusedUp)+-- >  , ((modm .|. controlMask, xK_u), rotFocusedDown) -- -- Also, if you use focus follows mouse, you will want to read the section -- on updating the mouse pointer below.  For detailed instructions on--- editing your key bindings, see "XMonad.Doc.Extending#Editing_key_bindings". +-- editing your key bindings, see "XMonad.Doc.Extending#Editing_key_bindings". {- $pointer With FocusFollowsMouse == True, the focus is updated after binding actions, possibly focusing a window you didn't intend to focus. Most@@ -86,9 +90,9 @@ and either  > -- modify the window rotation bindings-> , ((modMask x .|. controlMask, xK_i   ), rotFocusedUp+> , ((modm .|. controlMask, xK_i   ), rotFocusedUp >                                            >> updatePointer (Relative 1 1))-> , ((modMask x .|. controlMask, xK_u   ), rotFocusedDown+> , ((modm .|. controlMask, xK_u   ), rotFocusedDown >                                            >> updatePointer (Relative 1 1)) > >    -- or add to xmonad's logHook@@ -174,12 +178,19 @@ rotOpposite' (W.Stack t l r) = W.Stack t' l' r'   where rrvl = r ++ reverse l         part = (length rrvl + 1) `div` 2-        (l',t':r') = (\(f,s) -> (f, reverse s)) . splitAt (length l) $+        (l',t':r') =  second reverse . splitAt (length l) $                                 reverse (take part rrvl ++ t : drop part rrvl)   -- $focused--- Rotate windows through the focused frame, excluding the \"next\" window.+-- Most people will want the @rotAllUp@ or @rotAllDown@ actions from+-- "XMonad.Actions.RotSlaves" to cycle all windows in the stack.+--+-- The following actions keep the \"next\" window stable, which is+-- mostly useful in two window layouts, or when you have a log viewer or+-- buffer window you want to keep next to the cycled window.++-- | Rotate windows through the focused frame, excluding the \"next\" window. -- With, e.g. TwoPane, this allows cycling windows through either the -- master or slave pane, without changing the other frame. When the master -- is focused, the window below is skipped, when a non-master window is@@ -199,7 +210,7 @@  -- $unfocused -- Rotate windows through the unfocused frames. This is similar to--- rotSlaves, from "XMonad.Actions.RotSlaves", but excludes the current+-- @rotSlaves@, from "XMonad.Actions.RotSlaves", but excludes the current -- frame rather than master. rotUnfocusedUp :: X () rotUnfocusedUp = windows . W.modify' $ rotUnfocused' rotUp@@ -215,8 +226,10 @@            (revls',rs') = splitAt (length ls) (f $ master:revls ++ rs)  -- $generic--- Generic list rotations+-- Generic list rotations such that @rotUp [1..4]@ is equivalent to+-- @[2,3,4,1]@ and @rotDown [1..4]@ to @[4,1,2,3]@. They both are+-- @id@ for null or singleton lists. rotUp :: [a] -> [a]-rotUp   l = tail l ++ [head l]+rotUp   l = drop 1 l ++ take 1 l rotDown :: [a] -> [a]-rotDown l = last l : init l+rotDown = reverse . rotUp . reverse
XMonad/Actions/DeManage.hs view
@@ -5,12 +5,13 @@ -- License     :  BSD3-style (see LICENSE) -- -- Maintainer  :  Spencer Janssen <spencerjanssen@gmail.com>--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- This module provides a method to cease management of a window -- without unmapping it.  This is especially useful for applications--- like kicker and gnome-panel.+-- like kicker and gnome-panel.  See also "XMonad.Hooks.ManageDocks" for+-- more a more automated solution. -- -- To make a panel display correctly with xmonad: --@@ -43,7 +44,7 @@ -- -- And add a keybinding, such as: ----- > , ((modMask x,               xK_d     ), withFocused demanage)+-- > , ((modm,               xK_d     ), withFocused demanage) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".
XMonad/Actions/DwmPromote.hs view
@@ -5,7 +5,7 @@ -- License     :  BSD3-style (see LICENSE) -- -- Maintainer  :  arcatan@kapsi.fi--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- Dwm-like swap function for xmonad.@@ -33,7 +33,7 @@ -- -- then add a keybinding or substitute 'dwmpromote' in place of promote: ----- >   , ((modMask x,               xK_Return), dwmpromote)+-- >   , ((modm,               xK_Return), dwmpromote) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".
+ XMonad/Actions/DynamicWorkspaceGroups.hs view
@@ -0,0 +1,137 @@+{-# LANGUAGE DeriveDataTypeable #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Actions.DynamicWorkspaceGroups+-- Copyright   :  (c) Brent Yorgey 2009+-- License     :  BSD-style (see LICENSE)+--+-- Maintainer  :  <byorgey@gmail.com>+-- Stability   :  experimental+-- Portability :  unportable+--+-- Dynamically manage \"workspace groups\", sets of workspaces being+-- used together for some common task or purpose, to allow switching+-- between workspace groups in a single action.  Note that this only+-- makes sense for multi-head setups.+--+-----------------------------------------------------------------------------++module XMonad.Actions.DynamicWorkspaceGroups+    ( -- * Usage+      -- $usage++      WSGroupId++    , addWSGroup+    , addCurrentWSGroup+    , forgetWSGroup+    , viewWSGroup++    , promptWSGroupView+    , promptWSGroupAdd+    , promptWSGroupForget+    ) where++import Data.List (find)+import Control.Arrow ((&&&))+import qualified Data.Map as M++import XMonad+import qualified XMonad.StackSet as W++import XMonad.Prompt+import qualified XMonad.Util.ExtensibleState as XS++-- $usage+-- You can use this module by importing it into your ~\/.xmonad\/xmonad.hs file:+--+-- > import XMonad.Actions.DynamicWorkspaceGroups+--+-- Then add keybindings like the following (this example uses+-- "XMonad.Util.EZConfig"-style keybindings, but this is not necessary):+--+-- >    , ("M-y n", promptWSGroupAdd myXPConfig "Name this group: ")+-- >    , ("M-y g", promptWSGroupView myXPConfig "Go to group: ")+-- >    , ("M-y d", promptWSGroupForget myXPConfig "Forget group: ")+--++type WSGroup = [(ScreenId,WorkspaceId)]++type WSGroupId = String++data WSGroupStorage = WSG { unWSG :: M.Map WSGroupId WSGroup }+  deriving (Typeable, Read, Show)++withWSG :: (M.Map WSGroupId WSGroup -> M.Map WSGroupId WSGroup) -> WSGroupStorage -> WSGroupStorage+withWSG f = WSG . f . unWSG++instance ExtensionClass WSGroupStorage where+  initialValue = WSG $ M.empty+  extensionType = PersistentExtension++-- | Add a new workspace group with the given name.+addWSGroup :: WSGroupId -> [WorkspaceId] -> X ()+addWSGroup name wids = withWindowSet $ \w -> do+  let wss  = map ((W.tag . W.workspace) &&& W.screen) $ W.screens w+      wmap = mapM (strength . (flip lookup wss &&& id)) wids+  case wmap of+    Just ps -> XS.modify . withWSG . M.insert name $ ps+    Nothing -> return ()+ where strength (ma, b) = ma >>= \a -> return (a,b)++-- | Give a name to the current workspace group.+addCurrentWSGroup :: WSGroupId -> X ()+addCurrentWSGroup name = withWindowSet $ \w ->+  addWSGroup name $ map (W.tag . W.workspace) (W.current w : W.visible w)++-- | Delete the named workspace group from the list of workspace+--   groups.  Note that this has no effect on the workspaces involved;+--   it simply forgets the given name.+forgetWSGroup :: WSGroupId -> X ()+forgetWSGroup = XS.modify . withWSG . M.delete++-- | View the workspace group with the given name.+viewWSGroup :: WSGroupId -> X ()+viewWSGroup name = do+  WSG m <- XS.get+  case M.lookup name m of+    Just grp -> mapM_ (uncurry viewWS) grp+    Nothing -> return ()++-- | View the given workspace on the given screen.+viewWS :: ScreenId -> WorkspaceId -> X ()+viewWS sid wid = do+  mw <- findScreenWS sid+  case mw of+    Just w -> do+      windows $ W.view w+      windows $ W.greedyView wid+    Nothing -> return ()++-- | Find the workspace which is currently on the given screen.+findScreenWS :: ScreenId -> X (Maybe WorkspaceId)+findScreenWS sid = withWindowSet $+  return . fmap (W.tag . W.workspace) . find ((==sid) . W.screen) . W.screens++data WSGPrompt = WSGPrompt String++instance XPrompt WSGPrompt where+  showXPrompt (WSGPrompt s) = s++-- | Prompt for a workspace group to view.+promptWSGroupView :: XPConfig -> String -> X ()+promptWSGroupView xp s = do+  gs <- fmap (M.keys . unWSG) XS.get+  mkXPrompt (WSGPrompt s) xp (mkComplFunFromList' gs) viewWSGroup++-- | Prompt for a name for the current workspace group.+promptWSGroupAdd :: XPConfig -> String -> X ()+promptWSGroupAdd xp s =+  mkXPrompt (WSGPrompt s) xp (const $ return []) addCurrentWSGroup++-- | Prompt for a workspace group to forget.+promptWSGroupForget :: XPConfig -> String -> X ()+promptWSGroupForget xp s = do+  gs <- fmap (M.keys . unWSG) XS.get+  mkXPrompt (WSGPrompt s) xp (mkComplFunFromList' gs) forgetWSGroup
+ XMonad/Actions/DynamicWorkspaceOrder.hs view
@@ -0,0 +1,165 @@+{-# LANGUAGE DeriveDataTypeable #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Actions.DynamicWorkspaceOrder+-- Copyright   :  (c) Brent Yorgey 2009+-- License     :  BSD-style (see LICENSE)+--+-- Maintainer  :  <byorgey@gmail.com>+-- Stability   :  experimental+-- Portability :  unportable+--+-- Remember a dynamically updateable ordering on workspaces, together+-- with tools for using this ordering with "XMonad.Actions.CycleWS"+-- and "XMonad.Hooks.DynamicLog".+--+-----------------------------------------------------------------------------++module XMonad.Actions.DynamicWorkspaceOrder+    ( -- * Usage+      -- $usage++      getWsCompareByOrder+    , getSortByOrder+    , swapWith++    , moveTo+    , moveToGreedy+    , shiftTo++    ) where++import XMonad+import qualified XMonad.StackSet as W+import qualified XMonad.Util.ExtensibleState as XS++import XMonad.Util.WorkspaceCompare (WorkspaceCompare, WorkspaceSort, mkWsSort)+import XMonad.Actions.CycleWS (findWorkspace, WSType(..), Direction1D(..), doTo)++import qualified Data.Map as M+import qualified Data.Set as S+import Data.Maybe (fromJust, fromMaybe)+import Data.Ord (comparing)++-- $usage+-- You can use this module by importing it into your ~\/.xmonad\/xmonad.hs file:+--+-- > import qualified XMonad.Actions.DynamicWorkspaceOrder as DO+--+-- Then add keybindings to swap the order of workspaces (these+-- examples use "XMonad.Util.EZConfig" emacs-style keybindings):+--+-- >        , ("M-C-<R>",   DO.swapWith Next NonEmptyWS)+-- >        , ("M-C-<L>",   DO.swapWith Prev NonEmptyWS)+--+-- See "XMonad.Actions.CycleWS" for information on the possible+-- arguments to 'swapWith'.+--+-- However, by itself this will do nothing; 'swapWith' does not change+-- the actual workspaces in any way.  It simply keeps track of an+-- auxiliary ordering on workspaces.  Anything which cares about the+-- order of workspaces must be updated to use the auxiliary ordering.+--+-- To change the order in which workspaces are displayed by+-- "XMonad.Hooks.DynamicLog", use 'getSortByOrder' in your+-- 'XMonad.Hooks.DynamicLog.ppSort' field, for example:+--+-- >   ... dynamicLogWithPP $ byorgeyPP {+-- >     ...+-- >     , ppSort = DO.getSortByOrder+-- >     ...+-- >   }+--+-- To use workspace cycling commands like those from+-- "XMonad.Actions.CycleWS", use the versions of 'moveTo',+-- 'moveToGreedy', and 'shiftTo' exported by this module.  For example:+--+-- >     , ("M-S-<R>",   DO.shiftTo Next HiddenNonEmptyWS)+-- >     , ("M-S-<L>",   DO.shiftTo Prev HiddenNonEmptyWS)+-- >     , ("M-<R>",     DO.moveTo Next HiddenNonEmptyWS)+-- >     , ("M-<L>",     DO.moveTo Prev HiddenNonEmptyWS)+--+-- For slight variations on these, use the source for examples and+-- tweak as desired.++-- | Extensible state storage for the workspace order.+data WSOrderStorage = WSO { unWSO :: Maybe (M.Map WorkspaceId Int) }+  deriving (Typeable, Read, Show)++instance ExtensionClass WSOrderStorage where+  initialValue = WSO Nothing+  extensionType = PersistentExtension++-- | Lift a Map function to a function on WSOrderStorage.+withWSO :: (M.Map WorkspaceId Int -> M.Map WorkspaceId Int)+           -> (WSOrderStorage -> WSOrderStorage)+withWSO f = WSO . fmap f . unWSO++-- | Update the ordering storage: initialize if it doesn't yet exist;+-- add newly created workspaces at the end as necessary.+updateOrder :: X ()+updateOrder = do+  WSO mm <- XS.get+  case mm of+    Nothing -> do+      -- initialize using ordering of workspaces from the user's config+      ws <- asks (workspaces . config)+      XS.put . WSO . Just . M.fromList $ zip ws [0..]+    Just m -> do+      -- check for new workspaces and add them at the end+      curWs <- gets (S.fromList . map W.tag . W.workspaces . windowset)+      let mappedWs  = M.keysSet m+          newWs     = curWs `S.difference` mappedWs+          nextIndex = 1 + maximum (-1 : M.elems m)+          newWsIxs  = zip (S.toAscList newWs) [nextIndex..]+      XS.modify . withWSO . M.union . M.fromList $ newWsIxs++-- | A comparison function which orders workspaces according to the+-- stored dynamic ordering.+getWsCompareByOrder :: X WorkspaceCompare+getWsCompareByOrder = do+  updateOrder+  -- after the call to updateOrder we are guaranteed that the dynamic+  -- workspace order is initialized and contains all existing+  -- workspaces.+  WSO (Just m) <- XS.get+  return $ comparing (fromMaybe 1000 . flip M.lookup m)++-- | Sort workspaces according to the stored dynamic ordering.+getSortByOrder :: X WorkspaceSort+getSortByOrder = mkWsSort getWsCompareByOrder++-- | Swap the current workspace with another workspace in the stored+-- dynamic order.+swapWith :: Direction1D -> WSType -> X ()+swapWith dir which = findWorkspace getSortByOrder dir which 1 >>= swapWithCurrent++-- | Swap the given workspace with the current one.+swapWithCurrent :: WorkspaceId -> X ()+swapWithCurrent w = do+  cur <- gets (W.currentTag . windowset)+  swapOrder w cur++-- | Swap the two given workspaces in the dynamic order.+swapOrder :: WorkspaceId -> WorkspaceId -> X ()+swapOrder w1 w2 = do+  io $ print (w1,w2)+  WSO (Just m) <- XS.get+  let [i1,i2] = map (fromJust . flip M.lookup m) [w1,w2]+  XS.modify (withWSO (M.insert w1 i2 . M.insert w2 i1))+  windows id  -- force a status bar update++-- | View the next workspace of the given type in the given direction,+-- where \"next\" is determined using the dynamic workspace order.+moveTo :: Direction1D -> WSType -> X ()+moveTo dir t = doTo dir t getSortByOrder (windows . W.view)++-- | Same as 'moveTo', but using 'greedyView' instead of 'view'.+moveToGreedy :: Direction1D -> WSType -> X ()+moveToGreedy dir t = doTo dir t getSortByOrder (windows . W.greedyView)++-- | Shift the currently focused window to the next workspace of the+-- given type in the given direction, using the dynamic workspace order.+shiftTo :: Direction1D -> WSType -> X ()+shiftTo dir t = doTo dir t getSortByOrder (windows . W.shift)
XMonad/Actions/DynamicWorkspaces.hs view
@@ -8,15 +8,18 @@ -- Stability   :  unstable -- Portability :  unportable ----- Provides bindings to add and delete workspaces.  Note that you may only--- delete a workspace that is already empty.+-- Provides bindings to add and delete workspaces. -- -----------------------------------------------------------------------------  module XMonad.Actions.DynamicWorkspaces (                                          -- * Usage                                          -- $usage-                                         addWorkspace, removeWorkspace,+                                         addWorkspace, addWorkspacePrompt,+                                         removeWorkspace,+                                         removeEmptyWorkspace,+                                         removeEmptyWorkspaceAfter,+                                         removeEmptyWorkspaceAfterExcept,                                          addHiddenWorkspace,                                          withWorkspace,                                          selectWorkspace, renameWorkspace,@@ -28,6 +31,9 @@ import XMonad.Prompt.Workspace import XMonad.Prompt ( XPConfig, mkXPrompt, XPrompt(..) ) import XMonad.Util.WorkspaceCompare ( getSortByIndex )+import Data.List (find)+import Data.Maybe (isNothing)+import Control.Monad (when)  -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:@@ -36,18 +42,18 @@ -- -- Then add keybindings like the following: ----- >   , ((modMask x .|. shiftMask, xK_BackSpace), removeWorkspace)--- >   , ((modMask x .|. shiftMask, xK_v      ), selectWorkspace defaultXPConfig)--- >   , ((modMask x, xK_m                    ), withWorkspace defaultXPConfig (windows . W.shift))--- >   , ((modMask x .|. shiftMask, xK_m      ), withWorkspace defaultXPConfig (windows . copy))--- >   , ((modMask x .|. shiftMask, xK_r      ), renameWorkspace defaultXPConfig)+-- >   , ((modm .|. shiftMask, xK_BackSpace), removeWorkspace)+-- >   , ((modm .|. shiftMask, xK_v      ), selectWorkspace defaultXPConfig)+-- >   , ((modm, xK_m                    ), withWorkspace defaultXPConfig (windows . W.shift))+-- >   , ((modm .|. shiftMask, xK_m      ), withWorkspace defaultXPConfig (windows . copy))+-- >   , ((modm .|. shiftMask, xK_r      ), renameWorkspace defaultXPConfig) -- -- > -- mod-[1..9]       %! Switch to workspace N -- > -- mod-shift-[1..9] %! Move client to workspace N -- >    ++--- >    zip (zip (repeat (modMask x)) [xK_1..xK_9]) (map (withNthWorkspace W.greedyView) [0..])+-- >    zip (zip (repeat (modm)) [xK_1..xK_9]) (map (withNthWorkspace W.greedyView) [0..]) -- >    ++--- >    zip (zip (repeat (modMask x .|. shiftMask)) [xK_1..xK_9]) (map (withNthWorkspace W.shift) [0..])+-- >    zip (zip (repeat (modm .|. shiftMask)) [xK_1..xK_9]) (map (withNthWorkspace W.shift) [0..]) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".@@ -97,25 +103,68 @@                             then windows $ greedyView w                             else addWorkspace w --- | Add a new workspace with the given name.+-- | Add a new workspace with the given name, or do nothing if a+--   workspace with the given name already exists; then switch to the+--   newly created workspace. addWorkspace :: String -> X () addWorkspace newtag = addHiddenWorkspace newtag >> windows (greedyView newtag) +-- | Prompt for the name of a new workspace, add it if it does not+--   already exist, and switch to it.+addWorkspacePrompt :: XPConfig -> X ()+addWorkspacePrompt conf = mkXPrompt (Wor "New workspace name: ") conf (const (return [])) addWorkspace --- | Add a new hidden workspace with the given name.+-- | Add a new hidden workspace with the given name, or do nothing if+--   a workspace with the given name already exists. addHiddenWorkspace :: String -> X ()-addHiddenWorkspace newtag = do l <- asks (layoutHook . config)-                               windows (addHiddenWorkspace' newtag l)+addHiddenWorkspace newtag =+  whenX (gets (not . tagMember newtag . windowset)) $ do+    l <- asks (layoutHook . config)+    windows (addHiddenWorkspace' newtag l)  -- | Remove the current workspace if it contains no windows.+removeEmptyWorkspace :: X ()+removeEmptyWorkspace = gets (currentTag . windowset) >>= removeEmptyWorkspaceByTag++-- | Remove the current workspace. removeWorkspace :: X ()-removeWorkspace = do s <- gets windowset-                     case s of-                       StackSet { current = Screen { workspace = torem }-                                , hidden = (w:_) }-                           -> do windows $ view (tag w)-                                 windows (removeWorkspace' (tag torem))-                       _ -> return ()+removeWorkspace = gets (currentTag . windowset) >>= removeWorkspaceByTag++-- | Remove workspace with specific tag if it contains no windows. Only works+--   on the current or the last workspace.+removeEmptyWorkspaceByTag :: String -> X ()+removeEmptyWorkspaceByTag t = whenX (isEmpty t) $ removeWorkspaceByTag t++-- | Remove workspace with specific tag. Only works on the current or the last workspace.+removeWorkspaceByTag :: String -> X ()+removeWorkspaceByTag torem = do+    s <- gets windowset+    case s of+        StackSet { current = Screen { workspace = cur }, hidden = (w:_) } -> do+                when (torem==tag cur) $ windows $ view $ tag w+                windows $ removeWorkspace' torem+        _ -> return ()++-- | Remove the current workspace after an operation if it is empty and hidden.+--   Can be used to remove a workspace if it is empty when leaving it. The+--   operation may only change workspace once, otherwise the workspace will not+--   be removed.+removeEmptyWorkspaceAfter :: X () -> X ()+removeEmptyWorkspaceAfter = removeEmptyWorkspaceAfterExcept []++-- | Like 'removeEmptyWorkspaceAfter' but use a list of sticky workspaces,+--   whose entries will never be removed.+removeEmptyWorkspaceAfterExcept :: [String] -> X () -> X ()+removeEmptyWorkspaceAfterExcept sticky f = do+    before <- gets (currentTag . windowset)+    f+    after <- gets (currentTag . windowset)+    when (before/=after && before `notElem` sticky) $ removeEmptyWorkspaceByTag before++isEmpty :: String -> X Bool+isEmpty t = do wsl <- gets $ workspaces . windowset+               let mws = find (\ws -> tag ws == t) wsl+               return $ maybe True (isNothing . stack) mws  addHiddenWorkspace' :: i -> l -> StackSet i l a sid sd -> StackSet i l a sid sd addHiddenWorkspace' newtag l s@(StackSet { hidden = ws }) = s { hidden = Workspace newtag l Nothing:ws }
XMonad/Actions/FindEmptyWorkspace.hs view
@@ -5,7 +5,7 @@ -- License     :  BSD3-style (see LICENSE) -- -- Maintainer  :  arcatan@kapsi.fi--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- Find an empty workspace.@@ -32,8 +32,8 @@ -- -- and add the desired keybindings, for example: -----  >   , ((modMask x,                xK_m    ), viewEmptyWorkspace)---  >   , ((modMask x .|. shiftMask,  xK_m    ), tagToEmptyWorkspace)+--  >   , ((modm,                xK_m    ), viewEmptyWorkspace)+--  >   , ((modm .|. shiftMask,  xK_m    ), tagToEmptyWorkspace) -- -- Now you can jump to an empty workspace with @mod-m@. @Mod-shift-m@ -- will tag the current window to an empty workspace and view it.
XMonad/Actions/FlexibleManipulate.hs view
@@ -7,7 +7,7 @@ -- License     :  BSD3-style (see LICENSE) -- -- Maintainer  :  <mgsloan@gmail.com>--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- Move and resize floating windows without warping the mouse.@@ -31,7 +31,7 @@ -- -- Now set up the desired mouse binding, for example: ----- >     , ((modMask x, button1), (\w -> focus w >> Flex.mouseWindow Flex.linear w))+-- >     , ((modm, button1), (\w -> focus w >> Flex.mouseWindow Flex.linear w)) -- -- * Flex.'linear' indicates that positions between the edges and the --   middle indicate a combination scale\/position.
XMonad/Actions/FlexibleResize.hs view
@@ -15,7 +15,8 @@ module XMonad.Actions.FlexibleResize (         -- * Usage         -- $usage-        XMonad.Actions.FlexibleResize.mouseResizeWindow+        XMonad.Actions.FlexibleResize.mouseResizeWindow,+        XMonad.Actions.FlexibleResize.mouseResizeEdgeWindow ) where  import XMonad@@ -28,40 +29,53 @@ -- -- Then add an appropriate mouse binding: ----- >     , ((modMask x, button3), (\w -> focus w >> Flex.mouseResizeWindow w))+-- >     , ((modm, button3), (\w -> focus w >> Flex.mouseResizeWindow w)) -- -- For detailed instructions on editing your mouse bindings, see -- "XMonad.Doc.Extending#Editing_mouse_bindings".  -- | Resize a floating window from whichever corner the mouse is --   closest to.-mouseResizeWindow :: Window -> X ()-mouseResizeWindow w = whenX (isClient w) $ withDisplay $ \d -> do+mouseResizeWindow+  :: Window -- ^ The window to resize.+  -> X ()+mouseResizeWindow = mouseResizeEdgeWindow 0+++-- | Resize a floating window from whichever corner or edge the mouse is+--   closest to.+mouseResizeEdgeWindow+  :: Rational -- ^ The size of the area where only one edge is resized.+  -> Window   -- ^ The window to resize.+  -> X ()+mouseResizeEdgeWindow edge w = whenX (isClient w) $ withDisplay $ \d -> do     io $ raiseWindow d w     wa <- io $ getWindowAttributes d w     sh <- io $ getWMNormalHints d w     (_, _, _, _, _, ix, iy, _) <- io $ queryPointer d w     let-        [pos_x, pos_y, width, height] = map (fromIntegral . ($ wa)) [wa_x, wa_y, wa_width, wa_height]-        west  = firstHalf ix width-        north = firstHalf iy height+        [pos_x, pos_y, width, height] = map (fi . ($ wa)) [wa_x, wa_y, wa_width, wa_height]+        west  = findPos ix width+        north = findPos iy height         (cx, fx, gx) = mkSel west  width  pos_x         (cy, fy, gy) = mkSel north height pos_y     io $ warpPointer d none w 0 0 0 0 cx cy-    mouseDrag (\ex ey -> do-                 wa' <- io $ getWindowAttributes d w-                 let [px, py] = map (fromIntegral . ($ wa')) [wa_x, wa_y]-                 io $ moveResizeWindow d w (fx px (fromIntegral ex))-                                           (fy py (fromIntegral ey))-                            `uncurry` applySizeHintsContents sh (gx $ fromIntegral ex, gy $ fromIntegral ey))+    mouseDrag (\ex ey -> do let (nw,nh) = applySizeHintsContents sh (gx ex, gy ey)+                            io $ moveResizeWindow d w (fx nw) (fy nh) nw nh)               (float w)     where-    firstHalf :: CInt -> Position -> Bool-    firstHalf a b = fromIntegral a * 2 <= b-    cfst = curry fst-    csnd = curry snd-    mkSel :: Bool -> Position -> Position -> (Position, a -> a -> a, CInt -> Position)-    mkSel b k p =-        if b-            then (0, csnd, ((k + p) -) . fromIntegral)-            else (k, cfst, subtract p  . fromIntegral)+    findPos :: CInt -> Position -> Maybe Bool+    findPos m s = if p < 0.5 - edge/2+                  then Just True+                  else if p < 0.5 + edge/2+                       then Nothing+                       else Just False+                  where p = fi m / fi s+    mkSel :: Maybe Bool -> Position -> Position -> (Position, Dimension -> Position, Position -> Dimension)+    mkSel b k p = case b of+                      Just True ->  (0, (fi k + fi p -).fi, (fi k + fi p -).fi)+                      Nothing ->    (k `div` 2, const p, const $ fi k)+                      Just False -> (k, const p, subtract (fi p) . fi)++fi :: (Num b, Integral a) => a -> b+fi = fromIntegral
XMonad/Actions/FloatKeys.hs view
@@ -5,7 +5,7 @@ -- License      : BSD -- -- Maintainer   : Karsten Schoelzel <kuser@gmx.de>--- Stability    : unstable+-- Stability    : stable -- Portability  : unportable -- -- Move and resize floating windows.@@ -28,11 +28,11 @@ -- -- Then add appropriate key bindings, for example: ----- >  , ((modMask x,               xK_d     ), withFocused (keysResizeWindow (-10,-10) (1,1)))--- >  , ((modMask x,               xK_s     ), withFocused (keysResizeWindow (10,10) (1,1)))--- >  , ((modMask x .|. shiftMask, xK_d     ), withFocused (keysAbsResizeWindow (-10,-10) (1024,752)))--- >  , ((modMask x .|. shiftMask, xK_s     ), withFocused (keysAbsResizeWindow (10,10) (1024,752)))--- >  , ((modMask x,               xK_a     ), withFocused (keysMoveWindowTo (512,384) (1%2,1%2)))+-- >  , ((modm,               xK_d     ), withFocused (keysResizeWindow (-10,-10) (1,1)))+-- >  , ((modm,               xK_s     ), withFocused (keysResizeWindow (10,10) (1,1)))+-- >  , ((modm .|. shiftMask, xK_d     ), withFocused (keysAbsResizeWindow (-10,-10) (1024,752)))+-- >  , ((modm .|. shiftMask, xK_s     ), withFocused (keysAbsResizeWindow (10,10) (1024,752)))+-- >  , ((modm,               xK_a     ), withFocused (keysMoveWindowTo (512,384) (1%2,1%2))) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".
+ XMonad/Actions/FloatSnap.hs view
@@ -0,0 +1,328 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.FloatSnap+-- Copyright   :  (c) 2009 Anders Engstrom <ankaan@gmail.com>+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Anders Engstrom <ankaan@gmail.com>+-- Stability   :  unstable+-- Portability :  unportable+--+-- Move and resize floating windows using other windows and the edge of the+-- screen as guidelines.+-----------------------------------------------------------------------------++module XMonad.Actions.FloatSnap (+                -- * Usage+                -- $usage+                Direction2D(..),+                snapMove,+                snapGrow,+                snapShrink,+                snapMagicMove,+                snapMagicResize,+                snapMagicMouseResize) where++import XMonad+import Control.Applicative((<$>))+import Data.List (sort)+import Data.Maybe (listToMaybe,fromJust,isNothing)+import qualified XMonad.StackSet as W++import XMonad.Hooks.ManageDocks (calcGap)+import XMonad.Util.Types (Direction2D(..))++import qualified Data.Set as S++-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- >    import XMonad.Actions.FloatSnap+--+-- Then add appropriate key bindings, for example:+--+-- >        , ((modm,               xK_Left),  withFocused $ snapMove L Nothing)+-- >        , ((modm,               xK_Right), withFocused $ snapMove R Nothing)+-- >        , ((modm,               xK_Up),    withFocused $ snapMove U Nothing)+-- >        , ((modm,               xK_Down),  withFocused $ snapMove D Nothing)+-- >        , ((modm .|. shiftMask, xK_Left),  withFocused $ snapShrink R Nothing)+-- >        , ((modm .|. shiftMask, xK_Right), withFocused $ snapGrow R Nothing)+-- >        , ((modm .|. shiftMask, xK_Up),    withFocused $ snapShrink D Nothing)+-- >        , ((modm .|. shiftMask, xK_Down),  withFocused $ snapGrow D Nothing)+--+-- For detailed instructions on editing your key bindings, see+-- "XMonad.Doc.Extending#Editing_key_bindings".+--+-- And possibly add an appropriate mouse binding, for example:+--+-- >        , ((modm,               button1), (\w -> focus w >> mouseMoveWindow w >> snapMagicMove (Just 50) (Just 50) w))+-- >        , ((modm .|. shiftMask, button1), (\w -> focus w >> mouseMoveWindow w >> snapMagicResize [L,R,U,D] (Just 50) (Just 50) w))+-- >        , ((modm,               button3), (\w -> focus w >> mouseResizeWindow w >> snapMagicResize [R,D] (Just 50) (Just 50) w))+--+-- For detailed instructions on editing your mouse bindings, see+-- "XMonad.Doc.Extending#Editing_mouse_bindings".+--+-- Using these mouse bindings, it will not snap while moving, but allow you to click the window once after it has been moved or resized to snap it into place.+-- Note that the order in which the commands are applied in the mouse bindings are important.+--+-- Interesting values for the distance to look for window in the orthogonal axis are Nothing (to snap against every window), Just 0 (to only snap+-- against windows that we should collide with geometrically while moving) and Just 1 (to also snap against windows we brush against).+--+-- For 'snapMagicMove', 'snapMagicResize' and 'snapMagicMouseResize', try instead setting it to the same as the maximum snapping distance.+--+-- When a value is specified it can be geometrically conceived as adding a border with the specified width around the window and then checking which+-- windows it should collide with.++-- | Resize the window by each edge independently to snap against the closest part of other windows or the edge of the screen. Use the location of the+--   mouse over the window to decide which edges to snap. In corners, the two adjoining edges will be snapped, along the middle of an edge only that edge+--   will be snapped. In the center of the window all edges will snap. Intended to be used together with "XMonad.Actions.FlexibleResize" or+--   "XMonad.Actions.FlexibleManipulate".+snapMagicMouseResize+    :: Rational  -- ^ How big the middle snap area of each axis should be.+    -> Maybe Int -- ^ The distance in the orthogonal axis to look for windows to snap against. Use Nothing to snap against every window.+    -> Maybe Int -- ^ The maximum distance to snap. Use Nothing to not impose any boundary.+    -> Window    -- ^ The window to move and resize.+    -> X ()+snapMagicMouseResize middle collidedist snapdist w = whenX (isClient w) $ withDisplay $ \d -> do+    wa <- io $ getWindowAttributes d w+    (_, _, _, px, py, _, _, _) <- io $ queryPointer d w+    let x = (fromIntegral px - wx wa)/(ww wa)+        y = (fromIntegral py - wy wa)/(wh wa)+        ml = if x <= (0.5 - middle/2) then [L] else []+        mr = if x >  (0.5 + middle/2) then [R] else []+        mu = if y <= (0.5 - middle/2) then [U] else []+        md = if y >  (0.5 + middle/2) then [D] else []+        mdir = ml++mr++mu++md+        dir = if mdir == []+              then [L,R,U,D]+              else mdir+    snapMagicResize dir collidedist snapdist w+    where+        wx = fromIntegral.wa_x+        wy = fromIntegral.wa_y+        ww = fromIntegral.wa_width+        wh = fromIntegral.wa_height++-- | Resize the window by each edge independently to snap against the closest part of other windows or the edge of the screen.+snapMagicResize+    :: [Direction2D] -- ^ The edges to snap.+    -> Maybe Int   -- ^ The distance in the orthogonal axis to look for windows to snap against. Use Nothing to snap against every window.+    -> Maybe Int   -- ^ The maximum distance to snap. Use Nothing to not impose any boundary.+    -> Window      -- ^ The window to move and resize.+    -> X ()+snapMagicResize dir collidedist snapdist w = whenX (isClient w) $ withDisplay $ \d -> do+    io $ raiseWindow d w+    wa <- io $ getWindowAttributes d w++    (xbegin,xend) <- handleAxis True d wa+    (ybegin,yend) <- handleAxis False d wa++    let xbegin' = if L `elem` dir then xbegin else (wx wa)+        xend'   = if R `elem` dir then xend   else (wx wa + ww wa)+        ybegin' = if U `elem` dir then ybegin else (wy wa)+        yend'   = if D `elem` dir then yend   else (wy wa + wh wa)++    io $ moveWindow d w (fromIntegral $ xbegin') (fromIntegral $ ybegin')+    io $ resizeWindow d w (fromIntegral $ xend' - xbegin') (fromIntegral $ yend' - ybegin')+    float w+    where+        wx = fromIntegral.wa_x+        wy = fromIntegral.wa_y+        ww = fromIntegral.wa_width+        wh = fromIntegral.wa_height++        handleAxis horiz d wa = do+            ((mbl,mbr,bs),(mfl,mfr,fs)) <- getSnap horiz collidedist d w+            let begin = if bs+                        then wpos wa+                        else case (mbl,mbr) of+                            (Just bl,Just br) -> if wpos wa - bl < br - wpos wa then bl else br+                            (Just bl,Nothing) -> bl+                            (Nothing,Just br) -> br+                            (Nothing,Nothing) -> wpos wa+                end = if fs+                      then wpos wa + wdim wa+                      else case (if mfl==(Just begin) then Nothing else mfl,mfr) of+                          (Just fl,Just fr) -> if wpos wa + wdim wa - fl < fr - wpos wa - wdim wa then fl else fr+                          (Just fl,Nothing) -> fl+                          (Nothing,Just fr) -> fr+                          (Nothing,Nothing) -> wpos wa + wdim wa+                begin' = if isNothing snapdist || abs (begin - wpos wa) <= fromJust snapdist then begin else (wpos wa)+                end' = if isNothing snapdist || abs (end - wpos wa - wdim wa) <= fromJust snapdist then end else (wpos wa + wdim wa)+            return (begin',end')+            where+                (wpos, wdim, _, _) = constructors horiz+++-- | Move a window by both axises in any direction to snap against the closest part of other windows or the edge of the screen.+snapMagicMove+    :: Maybe Int -- ^ The distance in the orthogonal axis to look for windows to snap against. Use Nothing to snap against every window.+    -> Maybe Int -- ^ The maximum distance to snap. Use Nothing to not impose any boundary.+    -> Window    -- ^ The window to move.+    -> X ()+snapMagicMove collidedist snapdist w = whenX (isClient w) $ withDisplay $ \d -> do+    io $ raiseWindow d w+    wa <- io $ getWindowAttributes d w++    nx <- handleAxis True d wa+    ny <- handleAxis False d wa++    io $ moveWindow d w (fromIntegral nx) (fromIntegral ny)+    float w+    where+        handleAxis horiz d wa = do+            ((mbl,mbr,bs),(mfl,mfr,fs)) <- getSnap horiz collidedist d w+            return $ if bs || fs+                     then wpos wa+                     else let b = case (mbl,mbr) of+                                    (Just bl,Just br) -> if wpos wa - bl < br - wpos wa then bl else br+                                    (Just bl,Nothing) -> bl+                                    (Nothing,Just br) -> br+                                    (Nothing,Nothing) -> wpos wa+                              f = case (mfl,mfr) of+                                    (Just fl,Just fr) -> if wpos wa + wdim wa - fl < fr - wpos wa - wdim wa then fl else fr+                                    (Just fl,Nothing) -> fl+                                    (Nothing,Just fr) -> fr+                                    (Nothing,Nothing) -> wpos wa+                              newpos = if abs (b - wpos wa) <= abs (f - wpos wa - wdim wa) then b else (f - wdim wa)+                          in if isNothing snapdist || abs (newpos - wpos wa) <= fromJust snapdist then newpos else (wpos wa)+            where+                (wpos, wdim, _, _) = constructors horiz++-- | Move a window in the specified direction until it snaps against another window or the edge of the screen.+snapMove+    :: Direction2D -- ^ What direction to move the window in.+    -> Maybe Int -- ^ The distance in the orthogonal axis to look for windows to snap against. Use Nothing to snap against every window.+    -> Window    -- ^ The window to move.+    -> X ()+snapMove L = doSnapMove True True+snapMove R = doSnapMove True False+snapMove U = doSnapMove False True+snapMove D = doSnapMove False False++doSnapMove :: Bool -> Bool -> Maybe Int -> Window -> X ()+doSnapMove horiz rev collidedist w = whenX (isClient w) $ withDisplay $ \d -> do+    io $ raiseWindow d w+    wa <- io $ getWindowAttributes d w+    ((bl,br,_),(fl,fr,_)) <- getSnap horiz collidedist d w++    let (mb,mf) = if rev then (bl,fl)+                         else (br,fr)++        newpos = fromIntegral $ case (mb,mf) of+                                    (Just b,Nothing) -> b+                                    (Nothing,Just f) -> f - wdim wa+                                    (Just b,Just f) -> if rev /= (b < f - wdim wa)+                                                       then b+                                                       else f - wdim wa+                                    _ -> wpos wa++    if horiz then io $ moveWindow d w newpos (fromIntegral $ wa_y wa)+             else io $ moveWindow d w (fromIntegral $ wa_x wa) newpos+    float w++    where+        (wpos, wdim, _, _) = constructors horiz++-- | Grow the specified edge of a window until it snaps against another window or the edge of the screen.+snapGrow+    :: Direction2D -- ^ What edge of the window to grow.+    -> Maybe Int -- ^ The distance in the orthogonal axis to look for windows to snap against. Use Nothing to snap against every window.+    -> Window    -- ^ The window to grow.+    -> X ()+snapGrow = snapResize True++-- | Shrink the specified edge of a window until it snaps against another window or the edge of the screen.+snapShrink+    :: Direction2D -- ^ What edge of the window to shrink.+    -> Maybe Int -- ^ The distance in the orthogonal axis to look for windows to snap against. Use Nothing to snap against every window.+    -> Window    -- ^ The window to shrink.+    -> X ()+snapShrink = snapResize False++snapResize :: Bool -> Direction2D -> Maybe Int -> Window -> X ()+snapResize grow dir collidedist w = whenX (isClient w) $ withDisplay $ \d -> do+    io $ raiseWindow d w+    wa <- io $ getWindowAttributes d w+    mr <- case dir of+              L -> do ((mg,ms,_),(_,_,_)) <- getSnap True collidedist d w+                      return $ case (if grow then mg else ms) of+                                   Just v -> Just (v, wy wa, ww wa + wx wa - v, wh wa)+                                   _ -> Nothing+              R -> do ((_,_,_),(ms,mg,_)) <- getSnap True collidedist d w+                      return $ case (if grow then mg else ms) of+                                   Just v -> Just (wx wa, wy wa, v - wx wa, wh wa)+                                   _ -> Nothing+              U -> do ((mg,ms,_),(_,_,_)) <- getSnap False collidedist d w+                      return $ case (if grow then mg else ms) of+                                   Just v -> Just (wx wa, v, ww wa, wh wa + wy wa - v)+                                   _ -> Nothing+              D -> do ((_,_,_),(ms,mg,_)) <- getSnap False collidedist d w+                      return $ case (if grow then mg else ms) of+                                   Just v -> Just (wx wa, wy wa, ww wa, v - wy wa)+                                   _ -> Nothing++    case mr of+        Nothing -> return ()+        Just (nx,ny,nw,nh) -> if nw>0 && nh>0 then do io $ moveWindow d w (fromIntegral nx) (fromIntegral ny)+                                                      io $ resizeWindow d w (fromIntegral nw) (fromIntegral nh)+                                              else return ()+    float w+    where+        wx = fromIntegral.wa_x+        wy = fromIntegral.wa_y+        ww = fromIntegral.wa_width+        wh = fromIntegral.wa_height+++getSnap :: Bool -> Maybe Int -> Display -> Window -> X ((Maybe Int,Maybe Int,Bool),(Maybe Int,Maybe Int,Bool))+getSnap horiz collidedist d w = do+    wa <- io $ getWindowAttributes d w+    screen <- W.current <$> gets windowset+    let sr = screenRect $ W.screenDetail screen+        wl = W.integrate' . W.stack $ W.workspace screen+    gr <- fmap ($sr) $ calcGap $ S.fromList [minBound .. maxBound]+    wla <- filter (collides wa) `fmap` (io $ mapM (getWindowAttributes d) $ filter (/=w) wl)++    return ( neighbours (back wa sr gr wla) (wpos wa)+           , neighbours (front wa sr gr wla) (wpos wa + wdim wa)+           )++    where+        wborder = fromIntegral.wa_border_width++        (wpos, wdim, rpos, rdim) = constructors horiz+        (refwpos, refwdim, _, _) = constructors $ not horiz++        back wa sr gr wla = dropWhile (< rpos sr) $+                            takeWhile (< rpos sr + rdim sr) $+                            sort $ (rpos sr):(rpos gr):(rpos gr + rdim gr):+                                   foldr (\a as -> (wpos a):(wpos a + wdim a + wborder a + wborder wa):as) [] wla++        front wa sr gr wla = dropWhile (<= rpos sr) $+                             takeWhile (<= rpos sr + rdim sr) $+                             sort $ (rpos gr - 2*wborder wa):(rpos gr + rdim gr - 2*wborder wa):(rpos sr + rdim sr - 2*wborder wa):+                                    foldr (\a as -> (wpos a - wborder a - wborder wa):(wpos a + wdim a):as) [] wla++        neighbours l v = ( listToMaybe $ reverse $ takeWhile (< v) l+                         , listToMaybe $ dropWhile (<= v) l+                         , v `elem` l+                         )++        collides wa oa = case collidedist of+                             Nothing -> True+                             Just dist -> (  refwpos oa - wborder oa < refwpos wa + refwdim wa + wborder wa + dist+                                          && refwpos wa - wborder wa - dist < refwpos oa + refwdim oa + wborder oa )+++constructors :: Bool -> (WindowAttributes -> Int, WindowAttributes -> Int, Rectangle -> Int, Rectangle -> Int)+constructors True = ( fromIntegral.wa_x+                    , fromIntegral.wa_width+                    , fromIntegral.rect_x+                    , fromIntegral.rect_width+                    )+constructors False = ( fromIntegral.wa_y+                     , fromIntegral.wa_height+                     , fromIntegral.rect_y+                     , fromIntegral.rect_height+                     )
XMonad/Actions/FocusNth.hs view
@@ -5,7 +5,7 @@ -- License      : BSD -- -- Maintainer   : Karsten Schoelzel <kuser@gmx.de>--- Stability    : unstable+-- Stability    : stable -- Portability  : unportable -- -- Focus the nth window of the current workspace.@@ -14,7 +14,7 @@ module XMonad.Actions.FocusNth (                  -- * Usage                  -- $usage-                 focusNth) where+                 focusNth,focusNth') where  import XMonad.StackSet import XMonad@@ -27,7 +27,7 @@ -- Then add appropriate keybindings, for example: -- -- > -- mod4-[1..9] @@ Switch to window N--- > ++ [((modMask x, k), focusNth i)+-- > ++ [((modm, k), focusNth i) -- >     | (i, k) <- zip [0 .. 8] [xK_1 ..]] -- -- For detailed instructions on editing your key bindings, see
XMonad/Actions/GridSelect.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ScopedTypeVariables, GeneralizedNewtypeDeriving, TypeSynonymInstances, FlexibleInstances, OverlappingInstances #-} ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Actions.GridSelect@@ -17,31 +17,52 @@ module XMonad.Actions.GridSelect (     -- * Usage     -- $usage++    -- ** Customizing+    -- *** Using a common GSConfig+    -- $commonGSConfig++    -- *** Custom keybindings+    -- $keybindings++    -- * Configuration     GSConfig(..),     defaultGSConfig,-    defaultGSSpawnConfig,+    NavigateMap,+    TwoDPosition,     buildDefaultGSConfig,++    -- * Variations on 'gridselect'     gridselect,     gridselectWindow,     withSelectedWindow,     bringSelected,     goToSelected,+    gridselectWorkspace,     spawnSelected,     runSelectedAction,++    -- * Colorizers+    HasColorizer(defaultColorizer),     fromClassName,-    defaultColorizer,+    stringColorizer,     colorRangeFromClassName++    -- * Screenshots+    -- $screenshots     ) where import Data.Maybe import Data.Bits+import Control.Applicative import Control.Monad.State import Control.Arrow import Data.List as L-import XMonad+import qualified Data.Map as M+import XMonad hiding (liftX) import XMonad.Util.Font import XMonad.Prompt (mkUnmanagedWindow) import XMonad.StackSet as W-import XMonad.Layout.DecorationUtils+import XMonad.Layout.Decoration import XMonad.Util.NamedWindows import XMonad.Actions.WindowBringer (bringWindow) import Text.Printf@@ -56,26 +77,125 @@ -- -- Then add a keybinding, e.g. ----- >    , ((modMask x, xK_g), goToSelected defaultGSConfig)------ Screenshot: <http://clemens.endorphin.org/gridselect.png>+-- >    , ((modm, xK_g), goToSelected defaultGSConfig) -- -- This module also supports displaying arbitrary information in a grid and letting -- the user select from it. E.g. to spawn an application from a given list, you -- can use the following: ----- >   , ((modMask x, xK_s), spawnSelected defaultGSSpawnConfig ["xterm","gmplayer","gvim"])+-- >   , ((modm, xK_s), spawnSelected defaultGSConfig ["xterm","gmplayer","gvim"]) +-- $commonGSConfig+--+-- It is possible to bind a @gsconfig@ at top-level in your configuration. Like so:+--+-- > -- the top of your config+-- > {-# LANGUAGE NoMonomorphismRestriction #-}+-- > import XMonad+-- > ...+-- > gsconfig1 = defaultGSConfig { gs_cellheight = 30, gs_cellwidth = 100 }+--+-- An example where 'buildDefaultGSConfig' is used instead of 'defaultGSConfig'+-- in order to specify a custom colorizer is @gsconfig2@ (found in+-- "XMonad.Actions.GridSelect#Colorizers"):+--+-- > gsconfig2 colorizer = (buildDefaultGSConfig colorizer) { gs_cellheight = 30, gs_cellwidth = 100 }+--+-- > -- | A green monochrome colorizer based on window class+-- > greenColorizer = colorRangeFromClassName+-- >                      black            -- lowest inactive bg+-- >                      (0x70,0xFF,0x70) -- highest inactive bg+-- >                      black            -- active bg+-- >                      white            -- inactive fg+-- >                      white            -- active fg+-- >   where black = minBound+-- >         white = maxBound+--+-- Then you can bind to:+--+-- >     ,((modm, xK_g), goToSelected  $ gsconfig2 myWinColorizer)+-- >     ,((modm, xK_p), spawnSelected $ spawnSelected defaultColorizer)++-- $keybindings+--+-- Adding more keybindings for gridselect to listen to is similar:+--+-- At the top of your config:+--+-- > {-# LANGAUGE NoMonomorphismRestriction #-}+-- > import XMonad+-- > import qualified Data.Map as M+--+-- Then define @gsconfig3@ which may be used in exactly the same manner as @gsconfig1@:+--+-- > gsconfig3 = defaultGSConfig+-- >    { gs_cellheight = 30+-- >    , gs_cellwidth = 100+-- >    , gs_navigate = M.unions+-- >            [reset+-- >            ,nethackKeys+-- >            ,gs_navigate                               -- get the default navigation bindings+-- >                $ defaultGSConfig `asTypeOf` gsconfig3 -- needed to fix an ambiguous type variable+-- >            ]+-- >    }+-- >   where addPair (a,b) (x,y) = (a+x,b+y)+-- >         nethackKeys = M.map addPair $ M.fromList+-- >                               [((0,xK_y),(-1,-1))+-- >                               ,((0,xK_i),(1,-1))+-- >                               ,((0,xK_n),(-1,1))+-- >                               ,((0,xK_m),(1,1))+-- >                               ]+-- >         -- jump back to the center with the spacebar, regardless of the current position.+-- >         reset = M.singleton (0,xK_space) (const (0,0))++-- $screenshots+--+-- Selecting a workspace:+--+-- <<http://haskell.org/sitewiki/images/a/a9/Xmonad-gridselect-workspace.png>>+--+-- Selecting a window by title:+--+-- <<http://haskell.org/sitewiki/images/3/35/Xmonad-gridselect-window-aavogt.png>>+ data GSConfig a = GSConfig {       gs_cellheight :: Integer,       gs_cellwidth :: Integer,       gs_cellpadding :: Integer,       gs_colorizer :: a -> Bool -> X (String, String),       gs_font :: String,+      gs_navigate :: NavigateMap,       gs_originFractX :: Double,       gs_originFractY :: Double } +-- | That is 'fromClassName' if you are selecting a 'Window', or+-- 'defaultColorizer' if you are selecting a 'String'. The catch-all instance+-- @HasColorizer a@ uses the 'focusedBorderColor' and 'normalBorderColor'+-- colors.+class HasColorizer a where+    defaultColorizer :: a -> Bool -> X (String, String)++instance HasColorizer Window where+    defaultColorizer = fromClassName++instance HasColorizer String where+    defaultColorizer = stringColorizer++instance HasColorizer a where+    defaultColorizer _ isFg =+        let getColor = if isFg then focusedBorderColor else normalBorderColor+        in asks $ flip (,) "black" . getColor . config++-- | A basic configuration for 'gridselect', with the colorizer chosen based on the type.+--+-- If you want to replace the 'gs_colorizer' field, use 'buildDefaultGSConfig'+-- instead, to avoid ambiguous type variables.+defaultGSConfig :: HasColorizer a => GSConfig a+defaultGSConfig = buildDefaultGSConfig defaultColorizer++type NavigateMap = M.Map (KeyMask,KeySym) (TwoDPosition -> TwoDPosition)+ type TwoDPosition = (Integer, Integer)  type TwoDElementMap a = [(TwoDPosition,(String,a))]@@ -89,8 +209,19 @@                              , td_drawingWin :: Window                              } -type TwoD a b = StateT (TwoDState a) X b+newtype TwoD a b = TwoD { unTwoD :: StateT (TwoDState a) X b }+    deriving (Monad,Functor,MonadState (TwoDState a)) +instance Applicative (TwoD a) where+    (<*>) = ap+    pure = return++liftX ::  X a1 -> TwoD a a1+liftX = TwoD . lift++evalTwoD ::  TwoD a1 a -> TwoDState a1 -> X a+evalTwoD m s = flip evalStateT s $ unTwoD m+ diamondLayer :: (Enum b', Num b') => b' -> [(b', b')] -- FIXME remove nub diamondLayer n = let ul = [ (x,n-x) | x <- [0..n] ]@@ -107,9 +238,6 @@   map (\(x', y') -> (x' + fromInteger originX, y' + fromInteger originY)) .   take 1000 $ diamond -tupadd :: (Num t1, Num t) => (t, t1) -> (t, t1) -> (t, t1)-tupadd (a,b) (c,d) = (a+c,b+d)- findInElementMap :: (Eq a) => a -> [(a, b)] -> Maybe (a, b) findInElementMap pos = find ((== pos) . fst) @@ -153,8 +281,8 @@         cellheight = gs_cellheight gsconfig         paneX' = div (paneX-cellwidth) 2         paneY' = div (paneY-cellheight) 2-        updateElement (pos@(x,y),(text, element)) = lift $ do-            colors <- (gs_colorizer gsconfig) element (pos == curpos)+        updateElement (pos@(x,y),(text, element)) = liftX $ do+            colors <- gs_colorizer gsconfig element (pos == curpos)             drawWinBox win font                        colors                        cellheight@@ -163,13 +291,12 @@                        (paneX'+x*cellwidth)                        (paneY'+y*cellheight)                        (gs_cellpadding gsconfig)-    mapM updateElement elementmap-    return ()+    mapM_ updateElement elementmap  eventLoop :: TwoD a (Maybe a) eventLoop = do-  (keysym,string,event) <- lift $ withDisplay $ \d -> liftIO $ allocaXEvent $ \e -> do-                             nextEvent d e+  (keysym,string,event) <- liftX $ withDisplay $ \d -> liftIO $ allocaXEvent $ \e -> do+                             maskEvent d (exposureMask .|. keyPressMask .|. buttonReleaseMask) e                              ev <- getEvent e                              (ks,s) <- if ev_event_type ev == keyPress                                        then lookupString $ asKeyEvent e@@ -177,23 +304,21 @@                              return (ks,s,ev)   handle (fromMaybe xK_VoidSymbol keysym,string) event -handle :: (KeySym, String)-       -> Event-       -> StateT (TwoDState a) X (Maybe a)-handle (ks,_) (KeyEvent {ev_event_type = t})+handle ::  (KeySym, t) -> Event -> TwoD a (Maybe a)+handle (ks,_) (KeyEvent {ev_event_type = t, ev_state = m })     | t == keyPress && ks == xK_Escape = return Nothing-    | t == keyPress && (ks == xK_Left || ks == xK_h)  = diffAndRefresh (-1,0)-    | t == keyPress && (ks == xK_Right || ks == xK_l) = diffAndRefresh (1,0)-    | t == keyPress && (ks == xK_Down || ks == xK_j) = diffAndRefresh (0,1)-    | t == keyPress && (ks == xK_Up || ks == xK_k) = diffAndRefresh (0,-1)     | t == keyPress && ks == xK_Return = do        (TwoDState { td_curpos = pos, td_elementmap = elmap }) <- get        return $ fmap (snd . snd) $ findInElementMap pos elmap+    | t == keyPress = do+        m' <- liftX (cleanMask m)+        keymap <- gets (gs_navigate . td_gsconfig)+        maybe eventLoop diffAndRefresh . M.lookup (m',ks) $ keymap   where diffAndRefresh diff = do           state <- get           let elmap = td_elementmap state               oldPos = td_curpos state-              newPos = oldPos `tupadd` diff+              newPos = diff oldPos               newSelectedEl = findInElementMap newPos elmap           when (isJust newSelectedEl) $ do                                 put state { td_curpos =  newPos }@@ -203,7 +328,7 @@ handle _ (ButtonEvent { ev_event_type = t, ev_x = x, ev_y = y })     | t == buttonRelease = do         (TwoDState { td_elementmap = elmap, td_paneX = px, td_paneY = py,-                     td_gsconfig = (GSConfig ch cw _ _ _ _ _) }) <- get+                     td_gsconfig = (GSConfig ch cw _ _ _ _ _ _) }) <- get         let gridX = (fi x - (px - cw) `div` 2) `div` cw             gridY = (fi y - (py - ch) `div` 2) `div` ch         case lookup (gridX,gridY) elmap of@@ -234,8 +359,8 @@          _ -> error "The world is ending. x mod a >= a."  -- | Default colorizer for Strings-defaultColorizer :: String -> Bool -> X (String, String)-defaultColorizer s active = +stringColorizer :: String -> Bool -> X (String, String)+stringColorizer s active =     let seed x = toInteger (sum $ map ((*x).fromEnum) s) :: Integer         (r,g,b) = hsv2rgb ((seed 83) `mod` 360,                            (fromInteger ((seed 191) `mod` 1000))/2500+0.4,@@ -259,17 +384,17 @@                         -> (Word8, Word8, Word8) -- ^ Inactive text color                         -> (Word8, Word8, Word8) -- ^ Active text color                         -> Window -> Bool -> X (String, String)-colorRangeFromClassName startC endC activeC inactiveT activeT w active = +colorRangeFromClassName startC endC activeC inactiveT activeT w active =     do classname <- runQuery className w-       if active +       if active          then return (rgbToHex activeC, rgbToHex activeT)-         else return (rgbToHex $ mix startC endC +         else return (rgbToHex $ mix startC endC                   $ stringToRatio classname, rgbToHex inactiveT)     where rgbToHex :: (Word8, Word8, Word8) -> String           rgbToHex (r, g, b) = '#':twodigitHex r                                ++twodigitHex g++twodigitHex b --- | Creates a mix of two colors according to a ratio +-- | Creates a mix of two colors according to a ratio -- (1 -> first color, 0 -> second color). mix :: (Word8, Word8, Word8) -> (Word8, Word8, Word8)         -> Double -> (Word8, Word8, Word8)@@ -290,7 +415,8 @@  -- | Brings up a 2D grid of elements in the center of the screen, and one can -- select an element with cursors keys. The selected element is returned.-gridselect :: forall a . GSConfig a -> [(String,a)] -> X (Maybe a)+gridselect :: GSConfig a -> [(String,a)] -> X (Maybe a)+gridselect _ [] = return Nothing gridselect gsconfig elmap =  withDisplay $ \dpy -> do     rootw <- asks theRoot@@ -304,25 +430,23 @@     font <- initXMF (gs_font gsconfig)     let screenWidth = toInteger $ rect_width s;         screenHeight = toInteger $ rect_height s;-    selectedElement <- if (status == grabSuccess) then-                          do-                            let restriction :: Integer -> (GSConfig a -> Integer) -> Double-                                restriction ss cs = ((fromInteger ss)/(fromInteger $ cs gsconfig)-1)/2+    selectedElement <- if (status == grabSuccess) then do+                            let restriction ss cs = (fromInteger ss/fromInteger (cs gsconfig)-1)/2 :: Double                                 restrictX = floor $ restriction screenWidth gs_cellwidth                                 restrictY = floor $ restriction screenHeight gs_cellheight                                 originPosX = floor $ ((gs_originFractX gsconfig) - (1/2)) * 2 * fromIntegral restrictX                                 originPosY = floor $ ((gs_originFractY gsconfig) - (1/2)) * 2 * fromIntegral restrictY                                 coords = diamondRestrict restrictX restrictY originPosX originPosY                                 elmap' = zip coords elmap-                            selectedElement <- evalStateT (updateAllElements >> eventLoop)-                                                          (TwoDState (head coords)-                                                           elmap'-                                                           gsconfig-                                                           font-                                                           screenWidth-                                                           screenHeight-                                                           win)-                            return selectedElement++                            evalTwoD (updateAllElements >> eventLoop)+                                (TwoDState (head coords)+                                            elmap'+                                            gsconfig+                                            font+                                            screenWidth+                                            screenHeight+                                            win)                       else                           return Nothing     liftIO $ do@@ -357,13 +481,22 @@ decorateName' w = do   fmap show $ getName w -defaultGSConfig :: GSConfig Window-defaultGSConfig = buildDefaultGSConfig fromClassName- -- | Builds a default gs config from a colorizer function. buildDefaultGSConfig :: (a -> Bool -> X (String,String)) -> GSConfig a-buildDefaultGSConfig col = GSConfig 50 130 10 col "xft:Sans-8" (1/2) (1/2)+buildDefaultGSConfig col = GSConfig 50 130 10 col "xft:Sans-8" defaultGSNav (1/2) (1/2) +defaultGSNav :: NavigateMap+defaultGSNav = M.map (\(x,y) (a,b) -> (x+a,y+b)) $ M.fromList+    [((0,xK_Left) ,(-1,0))+    ,((0,xK_h)    ,(-1,0))+    ,((0,xK_Right),(1,0))+    ,((0,xK_l)    ,(1,0))+    ,((0,xK_Down) ,(0,1))+    ,((0,xK_j)    ,(0,1))+    ,((0,xK_Up)   ,(0,-1))+    ,((0,xK_k)    ,(0,-1))+    ]+ borderColor :: String borderColor = "white" @@ -378,9 +511,6 @@ goToSelected :: GSConfig Window -> X () goToSelected = withSelectedWindow $ windows . W.focusWindow -defaultGSSpawnConfig :: GSConfig String-defaultGSSpawnConfig = buildDefaultGSConfig defaultColorizer- -- | Select an application to spawn from a given list spawnSelected :: GSConfig String -> [String] -> X () spawnSelected conf lst = gridselect conf (zip lst lst) >>= flip whenJust spawn@@ -393,6 +523,14 @@         Just selectedAction -> selectedAction         Nothing -> return () --- | Short-hand for 'fromIntegral'-fi :: (Integral a, Num b) => a -> b-fi = fromIntegral+-- | Select a workspace and view it using the given function+-- (normally 'W.view' or 'W.greedyView')+--+-- Another option is to shift the current window to the selected workspace:+--+-- > gridselectWorkspace (\ws -> W.greedyView ws . W.shift ws)+gridselectWorkspace :: GSConfig WorkspaceId ->+                          (WorkspaceId -> WindowSet -> WindowSet) -> X ()+gridselectWorkspace conf viewFunc = withWindowSet $ \ws -> do+    let wss = map W.tag $ W.hidden ws ++ map W.workspace (W.current ws : W.visible ws)+    gridselect conf (zip wss wss) >>= flip whenJust (windows . viewFunc)
XMonad/Actions/MessageFeedback.hs view
@@ -52,8 +52,8 @@ -- -- is mis-typed. For this reason, this module provides alternatives (ending with -- an underscore, e.g. tryMessage_) that discard their result and return an @X ()@.--- For example, to correct the previous example: --- +-- For example, to correct the previous example:+-- -- > ((modKey, xK_Left), tryMessage_ Shrink (MoveLeft 50)) -- 
XMonad/Actions/MouseGestures.hs view
@@ -15,14 +15,14 @@ module XMonad.Actions.MouseGestures (     -- * Usage     -- $usage-    Direction(..),+    Direction2D(..),     mouseGestureH,     mouseGesture,     mkCollect ) where  import XMonad-import XMonad.Hooks.ManageDocks (Direction(..))+import XMonad.Util.Types (Direction2D(..))  import Data.IORef import qualified Data.Map as M@@ -39,7 +39,7 @@ -- -- then add an appropriate mouse binding: ----- >     , ((modMask x .|. shiftMask, button3), mouseGesture gestures)+-- >     , ((modm .|. shiftMask, button3), mouseGesture gestures) -- -- where @gestures@ is a 'Data.Map.Map' from gestures to actions on -- windows, for example:@@ -64,10 +64,10 @@     where     d a b = abs (a - b) -dir :: Pos -> Pos -> Direction+dir :: Pos -> Pos -> Direction2D dir (ax, ay) (bx, by) = trans . (/ pi) $ atan2 (fromIntegral $ ay - by) (fromIntegral $ bx - ax)     where-    trans :: Double -> Direction+    trans :: Double -> Direction2D     trans x         | rg (-3/4) (-1/4) x = D         | rg (-1/4)  (1/4) x = R@@ -75,7 +75,7 @@         | otherwise          = L     rg a z x = a <= x && x < z -gauge :: (Direction -> X ()) -> Pos -> IORef (Maybe (Direction, Pos)) -> Position -> Position -> X ()+gauge :: (Direction2D -> X ()) -> Pos -> IORef (Maybe (Direction2D, Pos)) -> Position -> Position -> X () gauge hook op st nx ny = do     let np = (nx, ny)     stx <- io $ readIORef st@@ -96,7 +96,7 @@ -- | @'mouseGestureH' moveHook endHook@ is a mouse button -- event handler. It collects mouse movements, calling @moveHook@ for each -- update; when the button is released, it calls @endHook@.-mouseGestureH :: (Direction -> X ()) -> X () -> X ()+mouseGestureH :: (Direction2D -> X ()) -> X () -> X () mouseGestureH moveHook endHook = do     dpy <- asks display     root <- asks theRoot@@ -108,7 +108,7 @@  -- | A utility function on top of 'mouseGestureH'. It uses a 'Data.Map.Map' to -- look up the mouse gesture, then executes the corresponding action (if any).-mouseGesture :: Map [Direction] (Window -> X ()) -> Window -> X ()+mouseGesture :: Map [Direction2D] (Window -> X ()) -> Window -> X () mouseGesture tbl win = do     (mov, end) <- mkCollect     mouseGestureH (\d -> mov d >> return ()) $ end >>= \gest ->@@ -121,7 +121,7 @@ -- collect mouse movements (and return the current gesture as a list); the end -- hook will return a list of the completed gesture, which you can access with -- 'Control.Monad.>>='.-mkCollect :: (MonadIO m, MonadIO m') => m (Direction -> m' [Direction], m' [Direction])+mkCollect :: (MonadIO m, MonadIO m') => m (Direction2D -> m' [Direction2D], m' [Direction2D]) mkCollect = liftIO $ do     acc <- newIORef []     let
XMonad/Actions/MouseResize.hs view
@@ -23,12 +23,8 @@     , MouseResize (..)     ) where -import Control.Monad-import Data.Maybe- import XMonad import XMonad.Layout.Decoration-import XMonad.Layout.LayoutModifier  import XMonad.Layout.WindowArranger import XMonad.Util.XUtils@@ -47,11 +43,11 @@ -- -- Then edit your @layoutHook@ by modifying a given layout: ----- > myLayouts = mouseResize $ windowArrange $ layoutHook defaultConfig+-- > myLayout = mouseResize $ windowArrange $ layoutHook defaultConfig -- -- and then: ----- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -114,6 +110,11 @@     Just tr  -> withDisplay $ \d -> do                   tw <- mkInputWindow d tr                   io $ selectInput d tw (exposureMask .|. buttonPressMask)++                  cursor <- io $ createFontCursor d xC_bottom_right_corner+                  io $ defineCursor d tw cursor+                  io $ freeCursor d cursor+                   showWindow tw                   return ((w,r), Just tw)     Nothing ->    return ((w,r), Nothing)
XMonad/Actions/NoBorders.hs view
@@ -5,7 +5,7 @@ -- License     :  BSD3-style (see LICENSE) -- -- Maintainer  :  Lukas Mai <l.mai@web.de>--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- This module provides helper functions for dealing with window borders.@@ -21,7 +21,7 @@ -- | Toggle the border of the currently focused window. To use it, add a -- keybinding like so: ----- > , ((modMask x,  xK_g ),   withFocused toggleBorder)+-- > , ((modm,  xK_g ),   withFocused toggleBorder) -- toggleBorder :: Window -> X () toggleBorder w = do
+ XMonad/Actions/OnScreen.hs view
@@ -0,0 +1,188 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Actions.OnScreen+-- Copyright   :  (c) 2009 Nils Schweinsberg+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Nils Schweinsberg <mail@n-sch.de>+-- Stability   :  unstable+-- Portability :  unportable+--+-- Control workspaces on different screens (in xinerama mode).+--+-----------------------------------------------------------------------------++module XMonad.Actions.OnScreen (+    -- * Usage+    -- $usage+      onScreen+    , onScreen'+    , Focus(..)+    , viewOnScreen+    , greedyViewOnScreen+    , onlyOnScreen+    , toggleOnScreen+    , toggleGreedyOnScreen+    ) where++import XMonad+import XMonad.StackSet hiding (new)++import Control.Monad (guard)+-- import Control.Monad.State.Class (gets)+import Data.Maybe (fromMaybe)+++-- | Focus data definitions+data Focus = FocusNew                       -- ^ always focus the new screen+           | FocusCurrent                   -- ^ always keep the focus on the current screen+           | FocusTag WorkspaceId           -- ^ always focus tag i on the new stack+           | FocusTagVisible WorkspaceId    -- ^ focus tag i only if workspace with tag i is visible on the old stack+++-- | Run any function that modifies the stack on a given screen. This function+-- will also need to know which Screen to focus after the function has been+-- run.+onScreen :: (WindowSet -> WindowSet) -- ^ function to run+         -> Focus                    -- ^ what to do with the focus+         -> ScreenId                 -- ^ screen id+         -> WindowSet                -- ^ current stack+         -> WindowSet+onScreen f foc sc st = fromMaybe st $ do+    ws <- lookupWorkspace sc st++    let fStack      = f $ view ws st++    return $ setFocus foc st fStack+++-- set focus for new stack+setFocus :: Focus+         -> WindowSet -- ^ old stack+         -> WindowSet -- ^ new stack+         -> WindowSet+setFocus FocusNew _ new             = new+setFocus FocusCurrent old new        =+    case lookupWorkspace (screen $ current old) new of+         Nothing -> new+         Just i -> view i new+setFocus (FocusTag i) _ new         = view i new+setFocus (FocusTagVisible i) old new =+    if i `elem` map (tag . workspace) (visible old)+       then setFocus (FocusTag i) old new+       else setFocus FocusCurrent old new++-- | A variation of @onScreen@ which will take any @X ()@ function and run it+-- on the given screen.+-- Warning: This function will change focus even if the function it's supposed+-- to run doesn't succeed.+onScreen' :: X ()       -- ^ X function to run+          -> Focus      -- ^ focus+          -> ScreenId   -- ^ screen id+          -> X ()+onScreen' x foc sc = do+    st <- gets windowset+    case lookupWorkspace sc st of+         Nothing -> return ()+         Just ws -> do+             windows $ view ws+             x+             windows $ setFocus foc st+++-- | Switch to workspace @i@ on screen @sc@. If @i@ is visible use @view@ to+-- switch focus to the workspace @i@.+viewOnScreen :: ScreenId    -- ^ screen id+             -> WorkspaceId -- ^ index of the workspace+             -> WindowSet   -- ^ current stack+             -> WindowSet+viewOnScreen sid i =+    onScreen (view i) (FocusTag i) sid++-- | Switch to workspace @i@ on screen @sc@. If @i@ is visible use @greedyView@+-- to switch the current workspace with workspace @i@.+greedyViewOnScreen :: ScreenId    -- ^ screen id+                   -> WorkspaceId -- ^ index of the workspace+                   -> WindowSet   -- ^ current stack+                   -> WindowSet+greedyViewOnScreen sid i =+    onScreen (greedyView i) (FocusTagVisible i) sid++-- | Switch to workspace @i@ on screen @sc@. If @i@ is visible do nothing.+onlyOnScreen :: ScreenId    -- ^ screen id+             -> WorkspaceId -- ^ index of the workspace+             -> WindowSet   -- ^ current stack+             -> WindowSet+onlyOnScreen sid i =+    onScreen (view i) FocusCurrent sid++-- | @toggleOrView@ as in "XMonad.Actions.CycleWS" for @onScreen@ with view+toggleOnScreen :: ScreenId    -- ^ screen id+               -> WorkspaceId -- ^ index of the workspace+               -> WindowSet   -- ^ current stack+               -> WindowSet+toggleOnScreen sid i =+    onScreen (toggleOrView' view i) FocusCurrent sid++-- | @toggleOrView@ from "XMonad.Actions.CycleWS" for @onScreen@ with greedyView+toggleGreedyOnScreen :: ScreenId    -- ^ screen id+                     -> WorkspaceId -- ^ index of the workspace+                     -> WindowSet   -- ^ current stack+                     -> WindowSet+toggleGreedyOnScreen sid i =+    onScreen (toggleOrView' greedyView i) FocusCurrent sid+++-- a \"pure\" version of X.A.CycleWS.toggleOrDoSkip+toggleOrView' :: (WorkspaceId -> WindowSet -> WindowSet)   -- ^ function to run+              -> WorkspaceId                               -- ^ tag to look for+              -> WindowSet                                 -- ^ current stackset+              -> WindowSet+toggleOrView' f i st = fromMaybe (f i st) $ do+    let st' = hidden st+    -- make sure we actually have to do something+    guard $ i == (tag . workspace $ current st)+    guard $ not (null st')+    -- finally, toggle!+    return $ f (tag . head $ st') st+++-- $usage+--+-- This module provides an easy way to control, what you see on other screens in+-- xinerama mode without having to focus them. Put this into your+-- @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Actions.OnScreen+--+-- Then add the appropriate keybindings, for example replace your current keys+-- to switch the workspaces with this at the bottom of your keybindings:+--+-- >     +++-- >     [ ((m .|. modm, k), windows (f i))+-- >       | (i, k) <- zip (workspaces conf) ([xK_1 .. xK_9] ++ [xK_0])+-- >       , (f, m) <- [ (viewOnScreen 0, 0)+-- >                   , (viewOnScreen 1, controlMask)+-- >                   , (greedyView, controlMask .|. shiftMask) ]+-- >     ]+--+-- This will provide you with the following keybindings:+--+--      * modkey + 1-0:+--      Switch to workspace 1-0 on screen 0+--+--      * modkey + control + 1-0:+--      Switch to workspace 1-0 on screen 1+--+--      * modkey + control + shift + 1-0:+--      Default greedyView behaviour+--+--+-- A more basic version inside the default keybindings would be:+--+-- >        , ((modm .|. controlMask, xK_1) windows (viewOnScreen 0 "1"))+--+-- where 0 is the first screen and \"1\" the workspace with the tag \"1\".+--+-- For detailed instructions on editing your key bindings, see+-- "XMonad.Doc.Extending#Editing_key_bindings".
XMonad/Actions/PerWorkspaceKeys.hs view
@@ -21,7 +21,6 @@  import XMonad import XMonad.StackSet as S-import Data.List (find)  -- $usage --@@ -42,9 +41,9 @@ -- If it isn't listed, then run default action (marked with empty string, \"\"), or do nothing if default isn't supplied. bindOn :: [(String, X())] -> X() bindOn bindings = chooseAction chooser where-    chooser ws = case find ((ws==).fst) bindings of-        Just (_, action) -> action-        Nothing -> case find ((""==).fst) bindings of-            Just (_, action) -> action+    chooser ws = case lookup ws bindings of+        Just action -> action+        Nothing -> case lookup "" bindings of+            Just action -> action             Nothing -> return () 
XMonad/Actions/PhysicalScreens.hs view
@@ -19,21 +19,20 @@                                       , getScreen                                       , viewScreen                                       , sendToScreen+                                      , onNextNeighbour+                                      , onPrevNeighbour                                       ) where  import XMonad import qualified XMonad.StackSet as W -import qualified Graphics.X11.Xlib as X-import Graphics.X11.Xinerama--import Data.List (sortBy)+import Data.List (sortBy,findIndex) import Data.Function (on)  {- $usage  This module allows you name Xinerama screens from XMonad using their-physical location reletive to each other (as reported by Xinerama),+physical location relative to each other (as reported by Xinerama), rather than their @ScreenID@ s, which are arbitrarily determined by your X server and graphics hardware. @@ -44,11 +43,16 @@  > import XMonad.Actions.PhysicalSCreens +> , ((modMask, xK_a), onPrevNeighbour W.view)+> , ((modMask, xK_o), onNextNeighbour W.view)+> , ((modMask .|. shiftMask, xK_a), onPrevNeighbour W.shift)+> , ((modMask .|. shiftMask, xK_o), onNextNeighbour W.shift)+ > -- > -- mod-{w,e,r}, Switch to physical/Xinerama screens 1, 2, or 3 > -- mod-shift-{w,e,r}, Move client to screen 1, 2, or 3 > ---> [((modMask .|. mask, key), f sc)+> [((modm .|. mask, key), f sc) >     | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..] >     , (f, mask) <- [(viewScreen, 0), (sendToScreen, shiftMask)]] @@ -61,12 +65,12 @@  -- | Translate a physical screen index to a "ScreenId" getScreen :: PhysicalScreen -> X (Maybe ScreenId)-getScreen (P i) = withDisplay $ \dpy -> do-                    screens <- io $ getScreenInfo dpy-                    if i >= length screens-                     then return Nothing-                     else let ss = sortBy (cmpScreen `on` fst) $ zip screens [0..]-                          in return $ Just $ snd $ ss !! i+getScreen (P i) = do w <- gets windowset+                     let screens = W.current w : W.visible w+                     if i<0 || i >= length screens+                      then return Nothing+                      else let ss = sortBy (cmpScreen `on` (screenRect . W.screenDetail)) screens+                           in return $ Just $ W.screen $ ss !! i  -- | Switch to a given physical screen viewScreen :: PhysicalScreen -> X ()@@ -85,4 +89,27 @@ -- | Compare two screens by their top-left corners, ordering -- | top-to-bottom and then left-to-right. cmpScreen :: Rectangle -> Rectangle -> Ordering-cmpScreen  (Rectangle x1 y1 _ _) (Rectangle x2 y2 _ _) = compare (y1,x1) (y2,x2)+cmpScreen (Rectangle x1 y1 _ _) (Rectangle x2 y2 _ _) = compare (y1,x1) (y2,x2)+++-- | Get ScreenId for neighbours of the current screen based on position offset.+getNeighbour :: Int -> X ScreenId+getNeighbour d = do w <- gets windowset+                    let ss = map W.screen $ sortBy (cmpScreen `on` (screenRect . W.screenDetail)) $ W.current w : W.visible w+                        curPos = maybe 0 id $ findIndex (== W.screen (W.current w)) ss+                        pos = (curPos + d) `mod` length ss+                    return $ ss !! pos++neighbourWindows :: Int -> (WorkspaceId -> WindowSet -> WindowSet) -> X ()+neighbourWindows d f = do s <- getNeighbour d+                          w <- screenWorkspace s+                          whenJust w $ windows . f++-- | Apply operation on a WindowSet with the WorkspaceId of the next screen in the physical order as parameter.+onNextNeighbour :: (WorkspaceId -> WindowSet -> WindowSet) -> X ()+onNextNeighbour = neighbourWindows 1++-- | Apply operation on a WindowSet with the WorkspaceId of the previous screen in the physical order as parameter.+onPrevNeighbour :: (WorkspaceId -> WindowSet -> WindowSet) -> X ()+onPrevNeighbour = neighbourWindows (-1)+
XMonad/Actions/Plane.hs view
@@ -78,9 +78,9 @@ -- divisor, the last line will have the remaining workspaces. data Lines     = GConf     -- ^ Use @gconftool-2@ to find out the number of lines.-    | Lines Int -- ^ Specify the number of lines explicity.+    | Lines Int -- ^ Specify the number of lines explicitly. --- | This is the way most people would like to use this module.  It ataches the+-- | This is the way most people would like to use this module.  It attaches the -- 'KeyMask' passed as a parameter with 'xK_Left', 'xK_Up', 'xK_Right' and -- 'xK_Down', associating it with 'planeMove' to the corresponding 'Direction'. -- It also associates these bindings with 'shiftMask' to 'planeShift'.
XMonad/Actions/Promote.hs view
@@ -33,7 +33,7 @@ -- -- then add a keybinding or substitute 'promote' in place of swapMaster: ----- >   , ((modMask x,               xK_Return), promote)+-- >   , ((modm,               xK_Return), promote) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".
+ XMonad/Actions/RandomBackground.hs view
@@ -0,0 +1,72 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Actions.RandomBackground+-- Copyright   :  (c) 2009 Anze Slosar+--                translation to Haskell by Adam Vogt+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  <vogt.adam@gmail.com>+-- Stability   :  unstable+-- Portability :  unportable+--+-- An action to start terminals with a random background color+--+-----------------------------------------------------------------------------++module XMonad.Actions.RandomBackground (+    -- * Usage+    -- $usage+    randomBg',+    randomBg,+    RandomColor(HSV,RGB)+    ) where++import XMonad(X, XConf(config), XConfig(terminal), io, spawn,+              MonadIO, asks)+import System.Random+import Control.Monad(liftM)+import Numeric(showHex)++-- $usage+--+-- Add to your keybindings something like:+--+-- > ,((modm .|. shiftMask, xK_Return), randomBg $ HSV 0xff 0x20++-- | RandomColor fixes constraints when generating random colors. All+-- parameters should be in the range 0 -- 0xff+data RandomColor = RGB { _colorMin :: Int+                       , _colorMax :: Int+                       } -- ^ specify the minimum and maximum lowest values for each color channel.+                 | HSV { _colorSaturation :: Double+                       , _colorValue :: Double+                       } -- ^ specify the saturation and value, leaving the hue random.++toHex :: [Int] -> String+toHex =  ("'#"++) . (++"'") . concatMap (ensure 2 . ($ "") . showHex)+    where ensure x = reverse . take x . (++repeat '0') . reverse++randPermutation ::  (RandomGen g) => [a] -> g -> [a]+randPermutation xs g = swap $ zip (randoms g) xs+  where+    swap ((True,x):(c,y):ys) = y:swap ((c,x):ys)+    swap ((False,x):ys) = x:swap ys+    swap x = map snd x++-- | @randomBg'@ produces a random hex number in the form @'#xxyyzz'@+randomBg' ::  (MonadIO m) => RandomColor -> m String+randomBg' (RGB l h) = io $ liftM (toHex . take 3 . randomRs (l,h)) newStdGen+randomBg' (HSV s v) = io $ do+    g <- newStdGen+    let x = (^(2::Int)) $ fst $ randomR (0,sqrt $ pi / 3) g+    return $ toHex $ map round $ randPermutation [v,(v-s)*x + s,s] g++-- | @randomBg@ starts a terminal with the background color taken from 'randomBg''+--+-- This depends on the your 'terminal' configuration field accepting an+-- argument like @-bg '#ff0023'@+randomBg :: RandomColor -> X ()+randomBg x = do+    t <- asks (terminal . config)+    c <- randomBg' x+    spawn $ t ++ " -bg " ++ c
XMonad/Actions/RotSlaves.hs view
@@ -5,7 +5,7 @@ -- License      : BSD3-style (see LICENSE) -- -- Maintainer   : Hans Philipp Annen <haphi@gmx.net>--- Stability    : unstable+-- Stability    : stable -- Portability  : unportable -- -- Rotate all windows except the master window and keep the focus in@@ -28,7 +28,7 @@ -- -- and add whatever keybindings you would like, for example: ----- > , ((modMask x .|. shiftMask, xK_Tab   ), rotSlavesUp)+-- > , ((modm .|. shiftMask, xK_Tab   ), rotSlavesUp) -- -- This operation will rotate all windows except the master window, -- while the focus stays where it is. It is useful together with the
XMonad/Actions/Search.hs view
@@ -20,7 +20,7 @@                                  promptSearchBrowser,                                  selectSearch,                                  selectSearchBrowser,-                                 hasPrefix,+                                 isPrefixOf,                                  escape,                                  use,                                  intelligent,@@ -29,6 +29,7 @@                                  namedEngine,                                   amazon,+                                 alpha,                                  codesearch,                                  deb,                                  debbts,@@ -40,12 +41,15 @@                                  images,                                  imdb,                                  isohunt,+                                 lucky,                                  maps,                                  mathworld,+                                 openstreetmap,                                  scholar,                                  thesaurus,                                  wayback,                                  wikipedia,+                                 wiktionary,                                  youtube,                                  multi                                   -- * Use case: searching with a submap@@ -53,9 +57,10 @@                           ) where  import Data.Char (chr, ord, isAlpha, isMark, isDigit)+import Data.List (isPrefixOf) import Numeric (showIntAtBase) import XMonad (X(), MonadIO, liftIO)-import XMonad.Prompt (XPrompt(showXPrompt), mkXPrompt, XPConfig(), historyCompletion)+import XMonad.Prompt (XPrompt(showXPrompt), mkXPrompt, XPConfig(), historyCompletionP) import XMonad.Prompt.Shell (getBrowser) import XMonad.Util.Run (safeSpawn) import XMonad.Util.XSelection (getSelection)@@ -86,6 +91,8 @@  * 'amazon' -- Amazon keyword search. +* 'alpha' -- Wolfram|Alpha query.+ * 'codesearch' -- Google Labs Code Search search.  * 'deb'    -- Debian package search.@@ -108,10 +115,14 @@  * 'isohunt' -- isoHunt search. +* 'lucky' -- Google "I'm feeling lucky" search.+ * 'maps'   -- Google maps.  * 'mathworld' -- Wolfram MathWorld search. +* 'openstreetmap' -- OpenStreetMap free wiki world map.+ * 'scholar' -- Google scholar academic search.  * 'thesaurus' -- thesaurus.reference.com search.@@ -228,7 +239,7 @@ -- | Given a browser, a search engine's transformation function, and a search term, perform the --   requested search in the browser. search :: Browser -> Site -> Query -> X ()-search browser site query = safeSpawn browser $ site query+search browser site query = safeSpawn browser [site query]  {- | Given a base URL, create the 'SearchEngine' that escapes the query and    appends it to the base. You can easily define a new engine locally using@@ -250,8 +261,8 @@    inside of a URL instead of in the end) you can use the alternative 'searchEngineF' function.  > searchFunc :: String -> String-> searchFunc s | s `hasPrefix` "wiki:"   = "http://en.wikipedia.org/wiki/" ++ (escape $ tail $ snd $ break (==':') s)->              | s `hasPrefix` "http://" = s+> searchFunc s | s `isPrefixOf` "wiki:"   = "http://en.wikipedia.org/wiki/" ++ (escape $ tail $ snd $ break (==':') s)+>              | s `isPrefixOf` "http://" = s >              | otherwise               = (use google) s > myNewEngine = searchEngineF "mymulti" searchFunc @@ -266,36 +277,36 @@ searchEngineF :: Name -> Site -> SearchEngine searchEngineF = SearchEngine - -- The engines.-amazon, codesearch, deb, debbts, debpts, dictionary, google, hackage, hoogle, images,-  imdb, isohunt, maps, mathworld, scholar, thesaurus, wayback, wikipedia,+amazon, alpha, codesearch, deb, debbts, debpts, dictionary, google, hackage, hoogle,+  images, imdb, isohunt, lucky, maps, mathworld, openstreetmap, scholar, thesaurus, wayback, wikipedia, wiktionary,   youtube :: SearchEngine-amazon     = searchEngine "amazon"     "http://www.amazon.com/exec/obidos/external-search?index=all&keyword="-codesearch = searchEngine "codesearch" "http://www.google.com/codesearch?q="-deb        = searchEngine "deb"        "http://packages.debian.org/"-debbts     = searchEngine "debbts"     "http://bugs.debian.org/"-debpts     = searchEngine "debpts"     "http://packages.qa.debian.org/"-dictionary = searchEngine "dict"       "http://dictionary.reference.com/browse/"-google     = searchEngine "google"     "http://www.google.com/search?num=100&q="-hackage    = searchEngine "hackage"    "http://hackage.haskell.org/cgi-bin/hackage-scripts/package/"-hoogle     = searchEngine "hoogle"     "http://www.haskell.org/hoogle/?q="-images     = searchEngine "images"     "http://images.google.fr/images?q="-imdb       = searchEngine "imdb"       "http://www.imdb.com/Find?select=all&for="-isohunt    = searchEngine "isohunt"    "http://isohunt.com/torrents/?ihq="-maps       = searchEngine "maps"       "http://maps.google.com/maps?q="-mathworld  = searchEngine "mathworld"  "http://mathworld.wolfram.com/search/?query="-scholar    = searchEngine "scholar"    "http://scholar.google.com/scholar?q="-thesaurus  = searchEngine "thesaurus"  "http://thesaurus.reference.com/search?q="-wikipedia  = searchEngine "wiki"       "https://secure.wikimedia.org/wikipedia/en/wiki/Special:Search?go=Go&search="-youtube    = searchEngine "youtube"    "http://www.youtube.com/results?search_type=search_videos&search_query="-{- This doesn't seem to work, but nevertheless, it seems to be the official-   method at <http://web.archive.org/collections/web/advanced.html> to get the-   latest backup. -}-wayback   = searchEngine "wayback" "http://web.archive.org/"+amazon        = searchEngine "amazon"        "http://www.amazon.com/exec/obidos/external-search?index=all&keyword="+alpha         = searchEngine "alpha"         "http://www.wolframalpha.com/input/?i="+codesearch    = searchEngine "codesearch"    "http://www.google.com/codesearch?q="+deb           = searchEngine "deb"           "http://packages.debian.org/"+debbts        = searchEngine "debbts"        "http://bugs.debian.org/"+debpts        = searchEngine "debpts"        "http://packages.qa.debian.org/"+dictionary    = searchEngine "dict"          "http://dictionary.reference.com/browse/"+google        = searchEngine "google"        "http://www.google.com/search?num=100&q="+hackage       = searchEngine "hackage"       "http://hackage.haskell.org/package/"+hoogle        = searchEngine "hoogle"        "http://www.haskell.org/hoogle/?q="+images        = searchEngine "images"        "http://images.google.fr/images?q="+imdb          = searchEngine "imdb"          "http://www.imdb.com/find?s=all&q="+isohunt       = searchEngine "isohunt"       "http://isohunt.com/torrents/?ihq="+lucky         = searchEngine "lucky"         "http://www.google.com/search?btnI&q="+maps          = searchEngine "maps"          "http://maps.google.com/maps?q="+mathworld     = searchEngine "mathworld"     "http://mathworld.wolfram.com/search/?query="+openstreetmap = searchEngine "openstreetmap" "http://gazetteer.openstreetmap.org/namefinder/?find="+scholar       = searchEngine "scholar"       "http://scholar.google.com/scholar?q="+thesaurus     = searchEngine "thesaurus"     "http://thesaurus.reference.com/search?q="+wikipedia     = searchEngine "wiki"          "http://en.wikipedia.org/wiki/Special:Search?go=Go&search="+wiktionary    = searchEngine "wikt"          "http://en.wiktionary.org/wiki/Special:Search?go=Go&search="+youtube       = searchEngine "youtube"       "http://www.youtube.com/results?search_type=search_videos&search_query="+wayback       = searchEngineF "wayback"      ("http://web.archive.org/web/*/"++)  multi :: SearchEngine-multi = namedEngine "multi" $ foldr1 (!>) [amazon, codesearch, deb, debbts, debpts, dictionary, google, hackage, hoogle, images, imdb, isohunt, maps, mathworld, scholar, thesaurus, wayback, wikipedia, (prefixAware google)]+multi = namedEngine "multi" $ foldr1 (!>) [amazon, alpha, codesearch, deb, debbts, debpts, dictionary, google, hackage, hoogle, images, imdb, isohunt, lucky, maps, mathworld, openstreetmap, scholar, thesaurus, wayback, wikipedia, wiktionary, (prefixAware google)]  {- | This function wraps up a search engine and creates a new one, which works    like the argument, but goes directly to a URL if one is given rather than@@ -307,14 +318,10 @@ intelligent :: SearchEngine -> SearchEngine intelligent (SearchEngine name site) = searchEngineF name (\s -> if (fst $ break (==':') s) `elem` ["http", "https", "ftp"] then s else (site s)) -{- | Checks if a string starts with a given prefix -}-hasPrefix :: String -> String -> Bool-hasPrefix _ [] = True-hasPrefix [] (_:_) = False-hasPrefix (t:ts) (p:ps) = if t == p then hasPrefix ts ps else False-+-- | > removeColonPrefix "foo://bar" ~> "//bar"+-- > removeColonPrefix "foo//bar" ~> "foo//bar" removeColonPrefix :: String -> String-removeColonPrefix str = tail $ snd $ break (==':') str+removeColonPrefix s = if ':' `elem` s then drop 1 $ dropWhile (':' /=) s else s  {- | Connects a few search engines into one. If the search engines\' names are    \"s1\", \"s2\" and \"s3\", then the resulting engine will use s1 if the query@@ -328,14 +335,14 @@   \"mathworld:integral\" will search mathworld, and everything else will fall back to   google. The use of intelligent will make sure that URLs are opened directly. -} (!>) :: SearchEngine -> SearchEngine -> SearchEngine-(SearchEngine name1 site1) !> (SearchEngine name2 site2) = searchEngineF (name1 ++ "/" ++ name2) (\s -> if s `hasPrefix` (name1++":") then site1 (removeColonPrefix s) else site2 s)+(SearchEngine name1 site1) !> (SearchEngine name2 site2) = searchEngineF (name1 ++ "/" ++ name2) (\s -> if s `isPrefixOf` (name1++":") then site1 (removeColonPrefix s) else site2 s)  {- | Makes a search engine prefix-aware. Especially useful together with '!>'.    It will automatically remove the prefix from a query so that you don\'t end-	 up searching for google:xmonad if google is your fallback engine and you-	 explicitly add the prefix. -}+     up searching for google:xmonad if google is your fallback engine and you+     explicitly add the prefix. -} prefixAware :: SearchEngine -> SearchEngine-prefixAware (SearchEngine name site) = SearchEngine name (\s -> if s `hasPrefix` (name++":") then site $ removeColonPrefix s else site s)+prefixAware (SearchEngine name site) = SearchEngine name (\s -> if s `isPrefixOf` (name++":") then site $ removeColonPrefix s else site s)  {- | Changes search engine's name -} namedEngine :: Name -> SearchEngine -> SearchEngine@@ -345,7 +352,8 @@    Prompt's result, passes it to a given searchEngine and opens it in a given    browser. -} promptSearchBrowser :: XPConfig -> Browser -> SearchEngine -> X ()-promptSearchBrowser config browser (SearchEngine name site) = mkXPrompt (Search name) config historyCompletion $ search browser site+promptSearchBrowser config browser (SearchEngine name site) =+    mkXPrompt (Search name) config (historyCompletionP ("Search [" `isPrefixOf`)) $ search browser site  {- | Like 'search', but in this case, the string is not specified but grabbed  from the user's response to a prompt. Example:
XMonad/Actions/SimpleDate.hs view
@@ -29,7 +29,7 @@ -- -- and add a keybinding, for example: ----- >    , ((modMask x,               xK_d     ), date)+-- >    , ((modm,               xK_d     ), date) -- -- In this example, a popup date menu will now be bound to @mod-d@. --
XMonad/Actions/SinkAll.hs view
@@ -28,7 +28,7 @@ -- -- then add a keybinding; for example: -----     , ((modMask x .|. shiftMask, xK_t), sinkAll)+-- >   , ((modm .|. shiftMask, xK_t), sinkAll) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".
XMonad/Actions/SpawnOn.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveDataTypeable #-} ----------------------------------------------------------------------------- -- | -- Module       : XMonad.Actions.SpawnOn@@ -8,9 +9,9 @@ -- Stability    : unstable -- Portability  : unportable ----- Provides a way to spawn an application on a specific workspace by using--- the _NET_WM_PID property that most windows set on creation. Hence this module--- won't work on applications that don't set this property.+-- Provides a way to modify a window spawned by a command(e.g shift it to the workspace+-- it was launched on) by using the _NET_WM_PID property that most windows set on creation.+-- Hence this module won't work on applications that don't set this property. -- ----------------------------------------------------------------------------- @@ -18,16 +19,15 @@     -- * Usage     -- $usage     Spawner,-    mkSpawner,     manageSpawn,     spawnHere,     spawnOn,+    spawnAndDo,     shellPromptHere,     shellPromptOn ) where  import Data.List (isInfixOf)-import Data.IORef import System.Posix.Types (ProcessID)  import XMonad@@ -36,6 +36,7 @@ import XMonad.Hooks.ManageHelpers import XMonad.Prompt import XMonad.Prompt.Shell+import qualified XMonad.Util.ExtensibleState as XS  -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:@@ -43,42 +44,47 @@ -- >    import XMonad.Actions.SpawnOn -- -- >    main = do--- >      sp <- mkSpawner -- >      xmonad defaultConfig { -- >         ...--- >         manageHook = manageSpawn sp <+> manageHook defaultConfig+-- >         manageHook = manageSpawn <+> manageHook defaultConfig -- >         ... -- >      } -- -- To ensure that application appears on a workspace it was launched at, add keybindings like: ----- >  , ((mod1Mask,xK_o), spawnHere sp "urxvt")--- >  , ((mod1Mask,xK_s), shellPromptHere sp defaultXPConfig)+-- >  , ((mod1Mask,xK_o), spawnHere "urxvt")+-- >  , ((mod1Mask,xK_s), shellPromptHere defaultXPConfig) --+-- The module can also be used to apply other manage hooks to the window of+-- the spawned application(e.g. float or resize it).+-- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings". -newtype Spawner = Spawner {pidsRef :: IORef [(ProcessID, WorkspaceId)]}+newtype Spawner = Spawner {pidsRef :: [(ProcessID, ManageHook)]} deriving Typeable +instance ExtensionClass Spawner where+    initialValue = Spawner []+ maxPids :: Int maxPids = 5 --- | Create 'Spawner' which then has to be passed to other functions.-mkSpawner :: (Functor m, MonadIO m) => m Spawner-mkSpawner = io . fmap Spawner $ newIORef []+-- | Get the current Spawner or create one if it doesn't exist.+modifySpawner :: ([(ProcessID, ManageHook)] -> [(ProcessID, ManageHook)]) -> X ()+modifySpawner f = XS.modify (Spawner . f . pidsRef)  -- | Provides a manage hook to react on process spawned with -- 'spawnOn', 'spawnHere' etc.-manageSpawn :: Spawner -> ManageHook-manageSpawn sp = do-    pids <- io . readIORef $ pidsRef sp+manageSpawn :: ManageHook+manageSpawn = do+    Spawner pids <- liftX XS.get     mp <- pid     case flip lookup pids =<< mp of-        Nothing -> doF id-        Just w  -> do+        Nothing -> idHook+        Just mh  -> do             whenJust mp $ \p ->-                io . modifyIORef (pidsRef sp) $ filter ((/= p) . fst)-            doShift w+                liftX . modifySpawner $ filter ((/= p) . fst)+            mh  mkPrompt :: (String -> X ()) -> XPConfig -> X () mkPrompt cb c = do@@ -87,28 +93,31 @@  -- | Replacement for Shell prompt ("XMonad.Prompt.Shell") which launches -- application on current workspace.-shellPromptHere :: Spawner -> XPConfig -> X ()-shellPromptHere sp = mkPrompt (spawnHere sp)+shellPromptHere :: XPConfig -> X ()+shellPromptHere = mkPrompt spawnHere  -- | Replacement for Shell prompt ("XMonad.Prompt.Shell") which launches -- application on given workspace.-shellPromptOn :: Spawner -> WorkspaceId -> XPConfig -> X ()-shellPromptOn sp ws = mkPrompt (spawnOn sp ws)+shellPromptOn :: WorkspaceId -> XPConfig -> X ()+shellPromptOn ws = mkPrompt (spawnOn ws)  -- | Replacement for 'spawn' which launches -- application on current workspace.-spawnHere :: Spawner -> String -> X ()-spawnHere sp cmd = withWindowSet $ \ws -> spawnOn sp (W.currentTag ws) cmd+spawnHere :: String -> X ()+spawnHere cmd = withWindowSet $ \ws -> spawnOn (W.currentTag ws) cmd  -- | Replacement for 'spawn' which launches -- application on given workspace.-spawnOn :: Spawner -> WorkspaceId -> String -> X ()-spawnOn sp ws cmd = do+spawnOn :: WorkspaceId -> String -> X ()+spawnOn ws cmd = spawnAndDo (doShift ws) cmd++-- | Spawn an application and apply the manage hook when it opens.+spawnAndDo :: ManageHook -> String -> X ()+spawnAndDo mh cmd = do     p <- spawnPID $ mangle cmd-    io $ modifyIORef (pidsRef sp) (take maxPids . ((p, ws) :))+    modifySpawner $ (take maxPids . ((p,mh) :))  where     -- TODO this is silly, search for a better solution     mangle xs | any (`elem` metaChars) xs || "exec" `isInfixOf` xs = xs               | otherwise = "exec " ++ xs     metaChars = "&|;"-
XMonad/Actions/Submap.hs view
@@ -18,7 +18,7 @@                              submap,                              submapDefault                             ) where-+import Data.Bits import XMonad hiding (keys) import qualified Data.Map as M import Control.Monad.Fix (fix)@@ -34,7 +34,7 @@  Allows you to create a sub-mapping of keys. Example: ->    , ((modMask x, xK_a), submap . M.fromList $+>    , ((modm, xK_a), submap . M.fromList $ >        [ ((0, xK_n),     spawn "mpc next") >        , ((0, xK_p),     spawn "mpc prev") >        , ((0, xK_z),     spawn "mpc random")@@ -74,8 +74,8 @@         if isModifierKey keysym             then nextkey             else return (m, keysym)--    m' <- cleanMask m+    -- Remove num lock mask and Xkb group state bits+    m' <- cleanMask $ m .&. ((1 `shiftL` 12) - 1)     maybe def id (M.lookup (m', s) keys)      io $ ungrabKeyboard d currentTime
XMonad/Actions/SwapWorkspaces.hs view
@@ -19,7 +19,7 @@                                      swapWithCurrent,                                      swapTo,                                      swapWorkspaces,-                                     WSDirection(..)+                                     Direction1D(..)                                     ) where  import XMonad (windows, X())@@ -36,7 +36,7 @@ -- Then throw something like this in your keys definition: -- -- > ++--- > [((modMask x .|. controlMask, k), windows $ swapWithCurrent i)+-- > [((modm .|. controlMask, k), windows $ swapWithCurrent i) -- >     | (i, k) <- zip workspaces [xK_1 ..]] -- -- After installing this update, if you're on workspace 1, hitting mod-ctrl-5@@ -52,7 +52,7 @@  -- | Say @swapTo Next@ or @swapTo Prev@ to move your current workspace. -- This is an @X ()@ so can be hooked up to your keybindings directly.-swapTo :: WSDirection -> X ()+swapTo :: Direction1D -> X () swapTo dir = findWorkspace getSortByIndex dir AnyWS 1 >>= windows . swapWithCurrent  -- | Takes two workspace tags and an existing XMonad.StackSet and returns a new
XMonad/Actions/TagWindows.hs view
@@ -25,7 +25,7 @@                  tagDelPrompt                  ) where -import Data.List (nub,concat,sortBy)+import Data.List (nub,sortBy) import Control.Monad  import XMonad.StackSet hiding (filter)@@ -42,16 +42,16 @@ -- -- and add keybindings such as the following: ----- >   , ((modMask x,                 xK_f  ), withFocused (addTag "abc"))--- >   , ((modMask x .|. controlMask, xK_f  ), withFocused (delTag "abc"))--- >   , ((modMask x .|. shiftMask,   xK_f  ), withTaggedGlobal "abc" sink)--- >   , ((modMask x,                 xK_d  ), withTaggedP "abc" (shiftWin "2"))--- >   , ((modMask x .|. shiftMask,   xK_d  ), withTaggedGlobalP "abc" shiftHere)--- >   , ((modMask x .|. controlMask, xK_d  ), focusUpTaggedGlobal "abc")--- >   , ((modMask x,                 xK_g  ), tagPrompt defaultXPConfig (\s -> withFocused (addTag s)))--- >   , ((modMask x .|. controlMask, xK_g  ), tagDelPrompt defaultXPConfig)--- >   , ((modMask x .|. shiftMask,   xK_g  ), tagPrompt defaultXPConfig (\s -> withTaggedGlobal s float))--- >   , ((modWinMask,                xK_g  ), tagPrompt defaultXPConfig (\s -> withTaggedP s (shiftWin "2")))+-- >   , ((modm,                 xK_f  ), withFocused (addTag "abc"))+-- >   , ((modm .|. controlMask, xK_f  ), withFocused (delTag "abc"))+-- >   , ((modm .|. shiftMask,   xK_f  ), withTaggedGlobalP "abc" W.sink)+-- >   , ((modm,                 xK_d  ), withTaggedP "abc" (W.shiftWin "2"))+-- >   , ((modm .|. shiftMask,   xK_d  ), withTaggedGlobalP "abc" shiftHere)+-- >   , ((modm .|. controlMask, xK_d  ), focusUpTaggedGlobal "abc")+-- >   , ((modm,                 xK_g  ), tagPrompt defaultXPConfig (\s -> withFocused (addTag s)))+-- >   , ((modm .|. controlMask, xK_g  ), tagDelPrompt defaultXPConfig)+-- >   , ((modm .|. shiftMask,   xK_g  ), tagPrompt defaultXPConfig (\s -> withTaggedGlobal s float))+-- >   , ((modWinMask,                xK_g  ), tagPrompt defaultXPConfig (\s -> withTaggedP s (W.shiftWin "2"))) -- >   , ((modWinMask .|. shiftMask,  xK_g  ), tagPrompt defaultXPConfig (\s -> withTaggedGlobalP s shiftHere)) -- >   , ((modWinMask .|. controlMask, xK_g ), tagPrompt defaultXPConfig (\s -> focusUpTaggedGlobal s)) --
XMonad/Actions/TopicSpace.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveDataTypeable #-} ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Actions.TopicSpace@@ -9,148 +10,19 @@ -- Portability :  unportable -- -- Turns your workspaces into a more topic oriented system.------ This module allows to organize your workspaces on a precise topic basis.  So--- instead of having a workspace called `work' you can setup one workspace per--- task.  Here we call these workspaces, topics. The great thing with--- topics is that one can attach a directory that makes sense to each--- particular topic.  One can also attach an action which will be triggered--- when switching to a topic that does not have any windows in it.  So you can--- attach your mail client to the mail topic, some terminals in the right--- directory to the xmonad topic... This package also provides a nice way to--- display your topics in an historical way using a custom `pprWindowSet'--- function. You can also easily switch to recents topics using this history--- of last focused topics.------ Here is an example of configuration using TopicSpace:------ @--- -- The list of all topics/workspaces of your xmonad configuration.--- -- The order is important, new topics must be inserted--- -- at the end of the list if you want hot-restarting--- -- to work.--- myTopics :: [Topic]--- myTopics =---   [ \"dashboard\" -- the first one---   , \"admin\", \"build\", \"cleaning\", \"conf\", \"darcs\", \"haskell\", \"irc\"---   , \"mail\", \"movie\", \"music\", \"talk\", \"text\", \"tools\", \"web\", \"xmonad\"---   , \"yi\", \"documents\", \"twitter\", \"pdf\"---   ]--- @------ @---  myTopicConfig :: TopicConfig---  myTopicConfig = TopicConfig---    { topicDirs = M.fromList $---        [ (\"conf\", \"w\/conf\")---        , (\"dashboard\", \"Desktop\")---        , (\"yi\", \"w\/dev-haskell\/yi\")---        , (\"darcs\", \"w\/dev-haskell\/darcs\")---        , (\"haskell\", \"w\/dev-haskell\")---        , (\"xmonad\", \"w\/dev-haskell\/xmonad\")---        , (\"tools\", \"w\/tools\")---        , (\"movie\", \"Movies\")---        , (\"talk\", \"w\/talks\")---        , (\"music\", \"Music\")---        , (\"documents\", \"w\/documents\")---        , (\"pdf\", \"w\/documents\")---        ]---    , defaultTopicAction = const $ spawnShell >*> 3---    , defaultTopic = \"dashboard\"---    , maxTopicHistory = 10---    , topicActions = M.fromList $---        [ (\"conf\",       spawnShell >> spawnShellIn \"wd\/ertai\/private\")---        , (\"darcs\",      spawnShell >*> 3)---        , (\"yi\",         spawnShell >*> 3)---        , (\"haskell\",    spawnShell >*> 2 >>---                         spawnShellIn \"wd\/dev-haskell\/ghc\")---        , (\"xmonad\",     spawnShellIn \"wd\/x11-wm\/xmonad\" >>---                         spawnShellIn \"wd\/x11-wm\/xmonad\/contrib\" >>---                         spawnShellIn \"wd\/x11-wm\/xmonad\/utils\" >>---                         spawnShellIn \".xmonad\" >>---                         spawnShellIn \".xmonad\")---        , (\"mail\",       mailAction)---        , (\"irc\",        ssh somewhere)---        , (\"admin\",      ssh somewhere >>---                         ssh nowhere)---        , (\"dashboard\",  spawnShell)---        , (\"twitter\",    spawnShell)---        , (\"web\",        spawn browserCmd)---        , (\"movie\",      spawnShell)---        , (\"documents\",  spawnShell >*> 2 >>---                         spawnShellIn \"Documents\" >*> 2)---        , (\"pdf\",        spawn pdfViewerCmd)---        ]---    }--- @------ @---  -- extend your keybindings---  myKeys =---    [ ((modMask              , xK_n     ), spawnShell) -- %! Launch terminal---    , ((modMask              , xK_a     ), currentTopicAction myTopicConfig)---    , ((modMask              , xK_g     ), promptedGoto)---    , ((modMask .|. shiftMask, xK_g     ), promptedShift)---    ...---    ]---    ++---    [ ((modMask, k), switchNthLastFocused defaultTopic i)---    | (i, k) <- zip [1..] workspaceKeys]--- @------ @---  spawnShell :: X ()---  spawnShell = currentTopicDir myTopicConfig >>= spawnShellIn--- @------ @---  spawnShellIn :: Dir -> X ()---  spawnShellIn dir = spawn $ \"urxvt '(cd ''\" ++ dir ++ \"'' && \" ++ myShell ++ \" )'\"--- @------ @---  goto :: Topic -> X ()---  goto = switchTopic myTopicConfig--- @------ @---  promptedGoto :: X ()---  promptedGoto = workspacePrompt myXPConfig goto--- @------ @---  promptedShift :: X ()---  promptedShift = workspacePrompt myXPConfig $ windows . W.shift--- @------ @---  myConfig = do---      checkTopicConfig myTopics myTopicConfig---      myLogHook <- makeMyLogHook---      return $ defaultConfig---           { borderWidth = 1 -- Width of the window border in pixels.---           , workspaces = myTopics---           , layoutHook = myModifiers myLayouts---           , manageHook = myManageHook---           , logHook = myLogHook---           , handleEventHook = myHandleEventHook---           , terminal = myTerminal -- The preferred terminal program.---           , normalBorderColor = \"#3f3c6d\"---           , focusedBorderColor = \"#4f66ff\"---           , XMonad.modMask = mod1Mask---           , keys = myKeys---           , mouseBindings = myMouseBindings---           }--- @------ @---  main :: IO ()---  main = xmonad =<< myConfig--- @+-----------------------------------------------------------------------------+ module XMonad.Actions.TopicSpace-  ( Topic+  (+  -- * Overview+  -- $overview++  -- * Usage+  -- $usage+   Topic   , Dir   , TopicConfig(..)+  , defaultTopicConfig   , getLastFocusedTopics   , setLastFocusedTopic   , pprWindowSet@@ -159,6 +31,7 @@   , currentTopicAction   , switchTopic   , switchNthLastFocused+  , shiftNthLastFocused   , currentTopicDir   , checkTopicConfig   , (>*>)@@ -168,16 +41,12 @@ import XMonad  import Data.List-import Data.Maybe (fromMaybe, isNothing)+import Data.Maybe (fromMaybe, isNothing, listToMaybe) import Data.Ord import qualified Data.Map as M-import Graphics.X11.Xlib-import Control.Monad ((=<<),liftM2,when,unless,replicateM_)+import Control.Monad (liftM2,when,unless,replicateM_) import System.IO-import Foreign.C.String (castCCharToChar,castCharToCChar) -import XMonad.Operations-import Control.Applicative ((<$>)) import qualified XMonad.StackSet as W  import XMonad.Prompt@@ -188,7 +57,127 @@ import qualified XMonad.Hooks.DynamicLog as DL  import XMonad.Util.Run (spawnPipe)+import qualified XMonad.Util.ExtensibleState as XS +-- $overview+-- This module allows to organize your workspaces on a precise topic basis.  So+-- instead of having a workspace called `work' you can setup one workspace per+-- task.  Here we call these workspaces, topics. The great thing with+-- topics is that one can attach a directory that makes sense to each+-- particular topic.  One can also attach an action which will be triggered+-- when switching to a topic that does not have any windows in it.  So you can+-- attach your mail client to the mail topic, some terminals in the right+-- directory to the xmonad topic... This package also provides a nice way to+-- display your topics in an historical way using a custom `pprWindowSet'+-- function. You can also easily switch to recent topics using this history+-- of last focused topics.++-- $usage+-- Here is an example of configuration using TopicSpace:+--+-- > -- The list of all topics/workspaces of your xmonad configuration.+-- > -- The order is important, new topics must be inserted+-- > -- at the end of the list if you want hot-restarting+-- > -- to work.+-- > myTopics :: [Topic]+-- > myTopics =+-- >   [ "dashboard" -- the first one+-- >   , "admin", "build", "cleaning", "conf", "darcs", "haskell", "irc"+-- >   , "mail", "movie", "music", "talk", "text", "tools", "web", "xmonad"+-- >   , "yi", "documents", "twitter", "pdf"+-- >   ]+-- >+-- > myTopicConfig :: TopicConfig+-- > myTopicConfig = defaultTopicConfig+-- >   { topicDirs = M.fromList $+-- >       [ ("conf", "w/conf")+-- >       , ("dashboard", "Desktop")+-- >       , ("yi", "w/dev-haskell/yi")+-- >       , ("darcs", "w/dev-haskell/darcs")+-- >       , ("haskell", "w/dev-haskell")+-- >       , ("xmonad", "w/dev-haskell/xmonad")+-- >       , ("tools", "w/tools")+-- >       , ("movie", "Movies")+-- >       , ("talk", "w/talks")+-- >       , ("music", "Music")+-- >       , ("documents", "w/documents")+-- >       , ("pdf", "w/documents")+-- >       ]+-- >   , defaultTopicAction = const $ spawnShell >*> 3+-- >   , defaultTopic = "dashboard"+-- >   , topicActions = M.fromList $+-- >       [ ("conf",       spawnShell >> spawnShellIn "wd/ertai/private")+-- >       , ("darcs",      spawnShell >*> 3)+-- >       , ("yi",         spawnShell >*> 3)+-- >       , ("haskell",    spawnShell >*> 2 >>+-- >                        spawnShellIn "wd/dev-haskell/ghc")+-- >       , ("xmonad",     spawnShellIn "wd/x11-wm/xmonad" >>+-- >                        spawnShellIn "wd/x11-wm/xmonad/contrib" >>+-- >                        spawnShellIn "wd/x11-wm/xmonad/utils" >>+-- >                        spawnShellIn ".xmonad" >>+-- >                        spawnShellIn ".xmonad")+-- >       , ("mail",       mailAction)+-- >       , ("irc",        ssh somewhere)+-- >       , ("admin",      ssh somewhere >>+-- >                        ssh nowhere)+-- >       , ("dashboard",  spawnShell)+-- >       , ("twitter",    spawnShell)+-- >       , ("web",        spawn browserCmd)+-- >       , ("movie",      spawnShell)+-- >       , ("documents",  spawnShell >*> 2 >>+-- >                        spawnShellIn "Documents" >*> 2)+-- >       , ("pdf",        spawn pdfViewerCmd)+-- >       ]+-- >   }+-- >+-- > -- extend your keybindings+-- > myKeys conf@XConfig{modMask=modm} =+-- >   [ ((modm              , xK_n     ), spawnShell) -- %! Launch terminal+-- >   , ((modm              , xK_a     ), currentTopicAction myTopicConfig)+-- >   , ((modm              , xK_g     ), promptedGoto)+-- >   , ((modm .|. shiftMask, xK_g     ), promptedShift)+-- >   {- more  keys ... -}+-- >   ]+-- >   +++-- >   [ ((modm, k), switchNthLastFocused myTopicConfig i)+-- >   | (i, k) <- zip [1..] workspaceKeys]+-- >+-- > spawnShell :: X ()+-- > spawnShell = currentTopicDir myTopicConfig >>= spawnShellIn+-- >+-- > spawnShellIn :: Dir -> X ()+-- > spawnShellIn dir = spawn $ "urxvt '(cd ''" ++ dir ++ "'' && " ++ myShell ++ " )'"+-- >+-- > goto :: Topic -> X ()+-- > goto = switchTopic myTopicConfig+-- >+-- > promptedGoto :: X ()+-- > promptedGoto = workspacePrompt myXPConfig goto+-- >+-- > promptedShift :: X ()+-- > promptedShift = workspacePrompt myXPConfig $ windows . W.shift+-- >+-- > myConfig = do+-- >     checkTopicConfig myTopics myTopicConfig+-- >     myLogHook <- makeMyLogHook+-- >     return $ defaultConfig+-- >          { borderWidth = 1 -- Width of the window border in pixels.+-- >          , workspaces = myTopics+-- >          , layoutHook = myModifiers myLayout+-- >          , manageHook = myManageHook+-- >          , logHook = myLogHook+-- >          , handleEventHook = myHandleEventHook+-- >          , terminal = myTerminal -- The preferred terminal program.+-- >          , normalBorderColor = "#3f3c6d"+-- >          , focusedBorderColor = "#4f66ff"+-- >          , XMonad.modMask = mod1Mask+-- >          , keys = myKeys+-- >          , mouseBindings = myMouseBindings+-- >          }+-- >+-- > main :: IO ()+-- > main = xmonad =<< myConfig+ -- | An alias for @flip replicateM_@ (>*>) :: Monad m => m a -> Int -> m () (>*>) = flip replicateM_@@ -216,19 +205,31 @@                                  -- numeric keypad.                                } +defaultTopicConfig :: TopicConfig+defaultTopicConfig = TopicConfig { topicDirs = M.empty+                                 , topicActions = M.empty+                                 , defaultTopicAction = const (ask >>= spawn . terminal . config)+                                 , defaultTopic = "1"+                                 , maxTopicHistory = 10+                                 }++newtype PrevTopics = PrevTopics { getPrevTopics :: [String] } deriving (Read,Show,Typeable)+instance ExtensionClass PrevTopics where+    initialValue = PrevTopics []+    extensionType = PersistentExtension+ -- | Returns the list of last focused workspaces the empty list otherwise.--- This function rely on a reserved property namely _XMONAD_LAST_FOCUSED_WORKSPACES. getLastFocusedTopics :: X [String]-getLastFocusedTopics = getStringListProp "_XMONAD_LAST_FOCUSED_WORKSPACES"+getLastFocusedTopics = XS.gets getPrevTopics  -- | Given a 'TopicConfig', the last focused topic, and a predicate that will -- select topics that one want to keep, this function will set the property -- of last focused topics. setLastFocusedTopic :: TopicConfig -> Topic -> (Topic -> Bool) -> X () setLastFocusedTopic tg w predicate =-  getLastFocusedTopics >>=-    setStringListProp "_XMONAD_LAST_FOCUSED_WORKSPACES"+  XS.modify $ PrevTopics     . take (maxTopicHistory tg) . nub . (w:) . filter predicate+    . getPrevTopics  -- | This function is a variant of 'DL.pprWindowSet' which takes a topic configuration -- and a pretty-printing record 'PP'. It will show the list of topics sorted historically@@ -274,6 +275,12 @@   lastWs <- getLastFocusedTopics   switchTopic tg $ (lastWs ++ repeat (defaultTopic tg)) !! depth +-- | Shift the focused window to the Nth last focused topic, or fallback to doing nothing.+shiftNthLastFocused :: Int -> X ()+shiftNthLastFocused n = do+  ws <- fmap (listToMaybe . drop n) getLastFocusedTopics+  whenJust ws $ windows . W.shift+ -- | Returns the directory associated with current topic returns the empty string otherwise. currentTopicDir :: TopicConfig -> X String currentTopicDir tg = do@@ -294,42 +301,9 @@     check diffTopic "Seen but missing topics/workspaces"     check dups      "Duplicate topics/workspaces" -type StringProp = String--withStringProp :: StringProp -> (Display -> Window -> Atom -> X a) -> X a-withStringProp prop f =-  withDisplay $ \dpy -> do-    rootw <- asks theRoot-    a     <- io $ internAtom dpy prop False-    f dpy rootw a---- | Get the name of a string property and returns it as a 'Maybe'.-getStringProp :: StringProp -> X (Maybe String)-getStringProp prop =-  withStringProp prop $ \dpy rootw a -> do-    p <- io $ getWindowProperty8 dpy a rootw-    return $ map castCCharToChar <$> p---- | Set the value of a string property.-setStringProp :: StringProp -> String -> X ()-setStringProp prop string =-  withStringProp prop $ \dpy rootw a ->-    io $ changeProperty8 dpy rootw a a propModeReplace $ map castCharToCChar string---- | Given a property name, returns its contents as a list. It uses the empty--- list as default value.-getStringListProp :: StringProp -> X [String]-getStringListProp prop = return . maybe [] words =<< getStringProp prop---- | Given a property name and a list, sets the value of this property with--- the list given as argument.-setStringListProp :: StringProp -> [String] -> X ()-setStringListProp prop = setStringProp prop . unwords- -- | Display the given message using the @xmessage@ program. xmessage :: String -> IO () xmessage s = do   h <- spawnPipe "xmessage -file -"   hPutStr h s   hClose h-
XMonad/Actions/UpdateFocus.hs view
@@ -1,6 +1,6 @@ ----------------------------------------------------------------------------- -- |--- Module      :  XMonadContrib.UpdateFocus+-- Module      :  XMonad.Actions.UpdateFocus -- Copyright   :  (c) Daniel Schoepe -- License     :  BSD3-style (see LICENSE) --@@ -21,7 +21,6 @@  import XMonad import qualified XMonad.StackSet as W-import Graphics.X11.Xlib.Extras import Control.Monad (when) import Data.Monoid @@ -45,10 +44,10 @@     -- check only every 15 px to avoid excessive calls to translateCoordinates     when (x `mod` 15 == 0 || y `mod` 15 == 0) $ do       dpy <- asks display-      Just foc <- withWindowSet $ return . W.peek+      foc <- withWindowSet $ return . W.peek       -- get the window under the pointer:       (_,_,_,w) <- io $ translateCoordinates dpy root root (fromIntegral x) (fromIntegral y)-      when (foc /= w) $ focus w+      when (foc /= Just w) $ focus w     return (All True) focusOnMouseMove _ = return (All True) 
XMonad/Actions/UpdatePointer.hs view
@@ -26,6 +26,7 @@ import XMonad import Control.Monad import XMonad.StackSet (member, peek, screenDetail, current)+import Data.Maybe  -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:@@ -66,8 +67,10 @@   root <- asks theRoot   mouseIsMoving <- asks mouseFocused   (_sameRoot,_,currentWindow,rootx,rooty,_,_,_) <- io $ queryPointer dpy root+  drag <- gets dragging   unless (pointWithin (fi rootx) (fi rooty) rect           || mouseIsMoving+          || isJust drag           || not (currentWindow `member` ws || currentWindow == none)) $     case p of     Nearest -> do@@ -88,8 +91,10 @@         where fraction x y = floor (x * fromIntegral y)  windowAttributesToRectangle :: WindowAttributes -> Rectangle-windowAttributesToRectangle wa = Rectangle (fi (wa_x wa))     (fi (wa_y wa))-                                           (fi (wa_width wa)) (fi (wa_height wa))+windowAttributesToRectangle wa = Rectangle (fi (wa_x wa))+                                           (fi (wa_y wa))+                                           (fi (wa_width wa + 2 * wa_border_width wa))+                                           (fi (wa_height wa + 2 * wa_border_width wa)) moveWithin :: Ord a => a -> a -> a -> a moveWithin now lower upper =     if now < lower
XMonad/Actions/Warp.hs view
@@ -22,7 +22,6 @@                            warpToWindow                           ) where -import Data.Ratio import Data.List import XMonad import XMonad.StackSet as W@@ -34,11 +33,11 @@  then add appropriate keybindings to warp the pointer; for example: -> , ((modMask x,   xK_z     ), warpToWindow (1%2) (1%2)) -- @@ Move pointer to currently focused window+> , ((modm,   xK_z     ), warpToWindow (1%2) (1%2)) -- @@ Move pointer to currently focused window > >-- mod-ctrl-{w,e,r} @@ Move mouse pointer to screen 1, 2, or 3 >->   [((modMask x .|. controlMask, key), warpToScreen sc (1%2) (1%2))+>   [((modm .|. controlMask, key), warpToScreen sc (1%2) (1%2)) >       | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]]  Note that warping to a particular screen may change the focus.
XMonad/Actions/WindowBringer.hs view
@@ -5,7 +5,7 @@ -- License     :  BSD-style (see LICENSE) -- -- Maintainer  :  Devin Mullins <me@twifkak.com>--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- dmenu operations to bring windows to you, and bring you to windows.@@ -15,11 +15,11 @@ -----------------------------------------------------------------------------  module XMonad.Actions.WindowBringer (-				    -- * Usage-				    -- $usage-				    gotoMenu, gotoMenu', bringMenu, windowMap,-				    bringWindow-				   ) where+                    -- * Usage+                    -- $usage+                    gotoMenu, gotoMenu', bringMenu, windowMap,+                    bringWindow+                   ) where  import Data.Char (toLower) import qualified Data.Map as M@@ -38,8 +38,8 @@ -- -- and define appropriate key bindings: ----- > , ((modMask x .|. shiftMask, xK_g     ), gotoMenu)--- > , ((modMask x .|. shiftMask, xK_b     ), bringMenu)+-- > , ((modm .|. shiftMask, xK_g     ), gotoMenu)+-- > , ((modm .|. shiftMask, xK_b     ), bringMenu) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".
XMonad/Actions/WindowGo.hs view
@@ -28,18 +28,23 @@                  runOrRaiseMaster,                  raiseAndDo,                  raiseMaster,++                 ifWindows,+                 ifWindow,+                 raiseHook,                  module XMonad.ManageHook                 ) where -import Control.Monad (filterM)+import Control.Monad import Data.Char (toLower)--import XMonad (Query(), X(), withWindowSet, spawn, runQuery, liftIO)+import Data.Monoid+import XMonad (Query(), X(), ManageHook, withWindowSet, runQuery, liftIO, ask) import Graphics.X11 (Window) import XMonad.ManageHook import XMonad.Operations (windows) import XMonad.Prompt.Shell (getBrowser, getEditor) import qualified XMonad.StackSet as W (allWindows, peek, swapMaster, focusWindow)+import XMonad.Util.Run (safeSpawnProg) {- $usage  Import the module into your @~\/.xmonad\/xmonad.hs@:@@ -48,31 +53,47 @@  and define appropriate key bindings: -> , ((modMask x .|. shiftMask, xK_g), raise (className =? "Firefox"))-> , ((modMask x .|. shiftMask, xK_b), runOrRaise "firefox" (className =? "Firefox"))+> , ((modm .|. shiftMask, xK_g), raise (className =? "Firefox"))+> , ((modm .|. shiftMask, xK_b), runOrRaise "firefox" (className =? "Firefox"))  (Note that Firefox v3 and up have a class-name of \"Firefox\" and \"Navigator\"; lower versions use other classnames such as \"Firefox-bin\". Either choose the-appropriate one, or cover your bases by using instead something like- @(className =? \"Firefox\" <||> className =? \"Firefox-bin\")@.)+appropriate one, or cover your bases by using instead something like: +> (className =? "Firefox" <||> className =? "Firefox-bin")+ For detailed instructions on editing your key bindings, see "XMonad.Doc.Extending#Editing_key_bindings". -} --- | 'action' is an executable to be run via 'spawn' (of "XMonad.Core") if the Window cannot be found.+-- | If windows that satisfy the query exist, apply the supplied+-- function to them, otherwise run the action given as+-- second parameter.+ifWindows :: Query Bool -> ([Window] -> X ()) -> X () -> X ()+ifWindows qry f el = withWindowSet $ \wins -> do+  matches <- filterM (runQuery qry) $ W.allWindows wins+  case matches of+    [] -> el+    ws -> f ws++-- | The same as ifWindows, but applies a ManageHook to the first match+-- instead and discards the other matches+ifWindow :: Query Bool -> ManageHook -> X () -> X ()+ifWindow qry mh = ifWindows qry (windows . appEndo <=< runQuery mh . head)++-- | 'action' is an executable to be run via 'safeSpawnProg' (of "XMonad.Util.Run") if the Window cannot be found. --   Presumably this executable is the same one that you were looking for. runOrRaise :: String -> Query Bool -> X ()-runOrRaise = raiseMaybe . spawn+runOrRaise = raiseMaybe . safeSpawnProg  -- | See 'raiseMaybe'. If the Window can't be found, quietly give up and do nothing. raise :: Query Bool -> X () raise = raiseMaybe $ return ()  {- | 'raiseMaybe' queries all Windows based on a boolean provided by the-   user. Currently, there are three such useful booleans defined in-   "XMonad.ManageHook": title, resource, className. Each one tests based pretty+   user. Currently, there are 3 such useful booleans defined in+   "XMonad.ManageHook": 'title', 'resource', 'className'. Each one tests based pretty    much as you would think. ManageHook also defines several operators, the most-   useful of which is (=?). So a useful test might be finding a Window whose+   useful of which is (=?). So a useful test might be finding a @Window@ whose    class is Firefox. Firefox 3 declares the class \"Firefox\", so you'd want to    pass in a boolean like @(className =? \"Firefox\")@. @@ -95,15 +116,15 @@   > , ((modm, xK_m), raiseMaybe (runInTerm "-title mutt" "mutt") (title =? "mutt")) -} raiseMaybe :: X () -> Query Bool -> X ()-raiseMaybe f thatUserQuery = withWindowSet $ \s -> do-    maybeResult <- filterM (runQuery thatUserQuery) (W.allWindows s)-    case maybeResult of-      []     -> f-      (x:_)  -> windows $ W.focusWindow x+raiseMaybe f qry = ifWindow qry raiseHook f +-- | A manage hook that raises the window.+raiseHook :: ManageHook+raiseHook = ask >>= doF . W.focusWindow+ -- | See 'runOrRaise' and 'raiseNextMaybe'. Version that allows cycling through matches. runOrRaiseNext :: String -> Query Bool -> X ()-runOrRaiseNext = raiseNextMaybe . spawn+runOrRaiseNext = raiseNextMaybe . safeSpawnProg  -- | See 'raise' and 'raiseNextMaybe'. Version that allows cycling through matches. raiseNext :: Query Bool -> X ()@@ -115,18 +136,14 @@      query the next matching window is raised. If no matches are found      the function f is executed. -}+ raiseNextMaybe :: X () -> Query Bool -> X ()-raiseNextMaybe f thatUserQuery = withWindowSet $ \s -> do-  ws <- filterM (runQuery thatUserQuery) (W.allWindows s)-  case ws of-    []    -> f-    (x:_) -> let go (Just w) | (w `elem` ws) = next w $ cycle ws-                 go _ = windows $ W.focusWindow x-             in go $ W.peek s-  where-    next w (x:y:_) | x==w = windows $ W.focusWindow y-    next w (_:xs)         = next w xs-    next _ _ = error "raiseNextMaybe: empty list"+raiseNextMaybe f qry = flip (ifWindows qry) f $ \ws -> do+  foc <- withWindowSet $ return . W.peek+  case foc of+    Just w | w `elem` ws -> let (_:y:_) = dropWhile (/=w) $ cycle ws -- cannot fail to match+                            in windows $ W.focusWindow y+    _ -> windows . W.focusWindow . head $ ws  -- | Given a function which gets us a String, we try to raise a window with that classname, --   or we then interpret that String as a executable name.@@ -135,38 +152,34 @@  {- | 'raiseBrowser' and 'raiseEditor' grab $BROWSER and $EDITOR respectively and they either      take you to the specified program's window, or they try to run it. This is most useful-     if your variables are simple and look like 'firefox' or 'emacs'. -}+     if your variables are simple and look like \"firefox\" or \"emacs\". -} raiseBrowser, raiseEditor :: X () raiseBrowser = raiseVar getBrowser raiseEditor  = raiseVar getEditor -{- | if the window is found the window is focused and the third argument is called+{- | If the window is found the window is focused and the third argument is called      otherwise, the first argument is called-     See 'raiseMaster' for an example -}+     See 'raiseMaster' for an example. -} raiseAndDo :: X () -> Query Bool -> (Window -> X ())-> X ()-raiseAndDo raisef thatUserQuery afterRaise = withWindowSet $ \s -> do-    maybeResult <- filterM (runQuery thatUserQuery) (W.allWindows s)-    case maybeResult of-      []     -> raisef-      (x:_)  -> do windows $ W.focusWindow x-                   afterRaise x+raiseAndDo f qry after = ifWindow qry (afterRaise `mappend` raiseHook) f+    where afterRaise = ask >>= (>> idHook) . liftX . after -{- | if the window is found the window is focused and the third argument is called-     otherwise, raisef is called -}+{- | If a window matching the second arugment is found, the window is focused and the third argument is called;+     otherwise, the first argument is called. -} runOrRaiseAndDo :: String -> Query Bool -> (Window -> X ()) -> X ()-runOrRaiseAndDo = raiseAndDo . spawn+runOrRaiseAndDo = raiseAndDo . safeSpawnProg  {- | if the window is found the window is focused and set to master-     otherwise, the first argument is called+     otherwise, the first argument is called. -     raiseMaster (runInTerm \"-title ghci\"  \"zsh -c \'ghci\'\") (title =? \"ghci\") -}+     > raiseMaster (runInTerm "-title ghci"  "zsh -c 'ghci'") (title =? "ghci") -} raiseMaster :: X () -> Query Bool -> X () raiseMaster raisef thatUserQuery = raiseAndDo raisef thatUserQuery (\_ -> windows W.swapMaster) -{- |  if the window is found the window is focused and set to master-      otherwise, action is run+{- |  If the window is found the window is focused and set to master+      otherwise, action is run. -      runOrRaiseMaster \"firefox\" (className =? \"Firefox\")) +      > runOrRaiseMaster "firefox" (className =? "Firefox"))   -} runOrRaiseMaster :: String -> Query Bool -> X () runOrRaiseMaster run query = runOrRaiseAndDo run query (\_ -> windows W.swapMaster)
XMonad/Actions/WindowMenu.hs view
@@ -8,9 +8,19 @@ -- Stability   :  unstable -- Portability :  not portable --+-- Uses "XMonad.Actions.GridSelect" to display a number of actions related to+-- window management in the center of the focused window. Actions include: Closing,+-- maximizing, minimizing and shifting the window to another workspace.+--+-- Note: For maximizing and minimizing to actually work, you will need+-- to integrate "XMonad.Layout.Maximize" and "XMonad.Layout.Minimize" into your+-- setup.  See the documentation of those modules for more information.+-- -----------------------------------------------------------------------------  module XMonad.Actions.WindowMenu (+                             -- * Usage+                             -- $usage                              windowMenu                               ) where @@ -19,26 +29,28 @@ import XMonad.Actions.GridSelect import XMonad.Layout.Maximize import XMonad.Layout.Minimize+import XMonad.Util.XUtils (fi) -simpleColorizer :: (Monad m) => t -> t -> t1 -> Bool -> m (t, [Char])-simpleColorizer nBC _ _ False  = return (nBC, "black")-simpleColorizer _ fBC _ True  = return (fBC, "black")+-- $usage+--+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- >    import XMonad.Actions.WindowMenu+--+-- Then add a keybinding, e.g.+--+-- >    , ((modm,               xK_o ), windowMenu)  windowMenu :: X () windowMenu = withFocused $ \w -> do-    nBC <- asks (normalBorderColor . config)-    fBC <- asks (focusedBorderColor . config)     tags <- asks (workspaces . config)     Rectangle x y wh ht <- getSize w     Rectangle sx sy swh sht <- gets $ screenRect . W.screenDetail . W.current . windowset-    let originFractX = (fromIntegral x - fromIntegral sx + (fromIntegral wh / 2))-                        / fromIntegral swh-        originFractY = (fromIntegral y -fromIntegral sy + (fromIntegral ht / 2))-                        / fromIntegral sht-        colorizer = simpleColorizer nBC fBC-        gsConfig = buildDefaultGSConfig colorizer-        gsConfig' = gsConfig { gs_originFractX = originFractX,-                               gs_originFractY = originFractY }+    let originFractX = (fi x - fi sx + fi wh / 2) / fi swh+        originFractY = (fi y - fi sy + fi ht / 2) / fi sht+        gsConfig = defaultGSConfig+                    { gs_originFractX = originFractX+                    , gs_originFractY = originFractY }         actions = [ ("Cancel menu", return ())                   , ("Close"      , kill)                   , ("Maximize"   , sendMessage $ maximizeRestore w)@@ -46,14 +58,14 @@                   ] ++                   [ ("Move to " ++ tag, windows $ W.shift tag)                     | tag <- tags ]-    runSelectedAction gsConfig' actions+    runSelectedAction gsConfig actions  getSize :: Window -> X (Rectangle) getSize w = do   d  <- asks display   wa <- io $ getWindowAttributes d w-  let x = fromIntegral $ wa_x wa-      y = fromIntegral $ wa_y wa-      wh = fromIntegral $ wa_width wa-      ht = fromIntegral $ wa_height wa+  let x = fi $ wa_x wa+      y = fi $ wa_y wa+      wh = fi $ wa_width wa+      ht = fi $ wa_height wa   return (Rectangle x y wh ht)
XMonad/Actions/WindowNavigation.hs view
@@ -5,6 +5,8 @@ --                          Devin Mullins <me@twifkak.com> -- Maintainer  :  Devin Mullins <me@twifkak.com> -- License     :  BSD3-style (see LICENSE)+-- Stability   :  unstable+-- Portability :  unportable -- -- This is a rewrite of "XMonad.Layout.WindowNavigation".  WindowNavigation -- lets you assign keys to move up\/down\/left\/right, based on actual cartesian@@ -34,11 +36,11 @@                                        withWindowNavigationKeys,                                        WNAction(..),                                        go, swap,-                                       Direction(..)+                                       Direction2D(..)                                        ) where  import XMonad-import XMonad.Hooks.ManageDocks (Direction(..))+import XMonad.Util.Types (Direction2D(..)) import qualified XMonad.StackSet as W  import Control.Applicative ((<$>))@@ -50,7 +52,6 @@ import Data.Maybe (catMaybes, fromMaybe, listToMaybe) import Data.Ord (comparing) import qualified Data.Set as S-import Graphics.X11.Xlib  -- $usage --@@ -84,15 +85,15 @@ --  - manageHook to draw window decos?  withWindowNavigation :: (KeySym, KeySym, KeySym, KeySym) -> XConfig l -> IO (XConfig l)-withWindowNavigation (u,l,d,r) conf =-    withWindowNavigationKeys [ ((modMask conf              , u), WNGo   U),-                               ((modMask conf              , l), WNGo   L),-                               ((modMask conf              , d), WNGo   D),-                               ((modMask conf              , r), WNGo   R),-                               ((modMask conf .|. shiftMask, u), WNSwap U),-                               ((modMask conf .|. shiftMask, l), WNSwap L),-                               ((modMask conf .|. shiftMask, d), WNSwap D),-                               ((modMask conf .|. shiftMask, r), WNSwap R) ]+withWindowNavigation (u,l,d,r) conf@XConfig{modMask=modm} =+    withWindowNavigationKeys [ ((modm              , u), WNGo   U),+                               ((modm              , l), WNGo   L),+                               ((modm              , d), WNGo   D),+                               ((modm              , r), WNGo   R),+                               ((modm .|. shiftMask, u), WNSwap U),+                               ((modm .|. shiftMask, l), WNSwap L),+                               ((modm .|. shiftMask, d), WNSwap D),+                               ((modm .|. shiftMask, r), WNSwap R) ]                              conf  withWindowNavigationKeys :: [((KeyMask, KeySym), WNAction)] -> XConfig l -> IO (XConfig l)@@ -104,7 +105,7 @@   where fromWNAction posRef (WNGo dir)   = go   posRef dir         fromWNAction posRef (WNSwap dir) = swap posRef dir -data WNAction = WNGo Direction | WNSwap Direction+data WNAction = WNGo Direction2D | WNSwap Direction2D  type WNState = Map WorkspaceId Point @@ -113,10 +114,10 @@ -- 2. get target windowrect -- 3. focus window -- 4. set new position-go :: IORef WNState -> Direction -> X ()+go :: IORef WNState -> Direction2D -> X () go = withTargetWindow W.focusWindow -swap :: IORef WNState -> Direction -> X ()+swap :: IORef WNState -> Direction2D -> X () swap = withTargetWindow swapWithFocused   where swapWithFocused targetWin winSet =             case W.peek winSet of@@ -128,7 +129,7 @@         mapWindows'' f (W.Stack focused up down) = W.Stack (f focused) (map f up) (map f down)         swapWin win1 win2 win = if win == win1 then win2 else if win == win2 then win1 else win -withTargetWindow :: (Window -> WindowSet -> WindowSet) -> IORef WNState -> Direction -> X ()+withTargetWindow :: (Window -> WindowSet -> WindowSet) -> IORef WNState -> Direction2D -> X () withTargetWindow adj posRef dir = fromCurrentPoint posRef $ \win pos -> do     targets <- filter ((/= win) . fst) <$> navigableTargets pos dir     whenJust (listToMaybe targets) $ \(targetWin, targetRect) -> do@@ -175,12 +176,12 @@ midPoint :: Position -> Dimension -> Position midPoint pos dim = pos + fromIntegral dim `div` 2 -navigableTargets :: Point -> Direction -> X [(Window, Rectangle)]+navigableTargets :: Point -> Direction2D -> X [(Window, Rectangle)] navigableTargets point dir = navigable dir point <$> windowRects  -- Filters and sorts the windows in terms of what is closest from the Point in--- the Direction.-navigable :: Direction -> Point -> [(Window, Rectangle)] -> [(Window, Rectangle)]+-- the Direction2D.+navigable :: Direction2D -> Point -> [(Window, Rectangle)] -> [(Window, Rectangle)] navigable d pt = sortby d . filter (inr d pt . snd)  -- Produces a list of normal-state windows, on any screen. Rectangles are@@ -197,7 +198,7 @@  -- Modified from droundy's implementation of WindowNavigation: -inr :: Direction -> Point -> Rectangle -> Bool+inr :: Direction2D -> Point -> Rectangle -> Bool inr D (Point px py) (Rectangle rx ry w h) = px >= rx && px < rx + fromIntegral w &&                                                         py < ry + fromIntegral h inr U (Point px py) (Rectangle rx ry w _) = px >= rx && px < rx + fromIntegral w &&@@ -207,7 +208,7 @@ inr L (Point px py) (Rectangle rx ry w h) =             px > rx + fromIntegral w &&                                             py >= ry && py < ry + fromIntegral h -sortby :: Direction -> [(a,Rectangle)] -> [(a,Rectangle)]+sortby :: Direction2D -> [(a,Rectangle)] -> [(a,Rectangle)] sortby D = sortBy $ comparing (rect_y . snd) sortby R = sortBy $ comparing (rect_x . snd) sortby U = reverse . sortby D
XMonad/Actions/WithAll.hs view
@@ -18,8 +18,6 @@ import Data.Foldable hiding (foldr)  import XMonad-import XMonad.Core-import XMonad.Operations import XMonad.StackSet  -- $usage@@ -30,7 +28,7 @@ -- -- then add a keybinding; for example: -----     , ((modMask x .|. shiftMask, xK_t), sinkAll)+--     , ((modm .|. shiftMask, xK_t), sinkAll) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".
+ XMonad/Actions/WorkspaceCursors.hs view
@@ -0,0 +1,219 @@+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses #-}+-----------------------------------------------------------------------------+-- |+-- Module       : XMonad.Actions.WorkspaceCursors+-- Copyright    : (c) 2009 Adam Vogt <vogt.adam@gmail.com>+-- License      : BSD+--+-- Maintainer   : Adam Vogt+-- Stability    : unstable+-- Portability  : unportable+--+-- Like "XMonad.Actions.Plane" for an arbitrary number of dimensions.+-----------------------------------------------------------------------------++module XMonad.Actions.WorkspaceCursors+    (+    -- * Usage+    -- $usage++     focusDepth+    ,makeCursors+    ,toList+    ,workspaceCursors++    ,WorkspaceCursors+    ,getFocus++    -- * Modifying the focus+    ,modifyLayer+    ,modifyLayer'+    ,shiftModifyLayer,shiftLayer++    -- * Functions to pass to 'modifyLayer'+    ,focusNth'+    ,noWrapUp,noWrapDown++    -- * Todo+    -- $todo+    ) where++import qualified XMonad.StackSet as W++import XMonad.Actions.FocusNth(focusNth')+import XMonad.Layout.LayoutModifier(ModifiedLayout(..),+                                    LayoutModifier(handleMess, redoLayout))+import XMonad(Typeable, Message, WorkspaceId, X, XState(windowset),+              fromMessage, sendMessage, windows, gets)+import Control.Monad((<=<), guard, liftM, liftM2, when)+import Control.Applicative((<$>))+import Data.Foldable(Foldable(foldMap), toList)+import Data.Maybe(fromJust, listToMaybe)+import Data.Monoid(Monoid(mappend, mconcat))+import Data.Traversable(sequenceA)++-- $usage+--+-- Here is an example config:+--+-- > import XMonad+-- > import XMonad.Actions.WorkspaceCursors+-- > import XMonad.Hooks.DynamicLog+-- > import XMonad.Util.EZConfig+-- > import qualified XMonad.StackSet as W+-- >+-- > main = do+-- >     x <- xmobar conf+-- >     xmonad x+-- >+-- > conf = additionalKeysP defaultConfig+-- >        { layoutHook = workspaceCursors myCursors $ layoutHook defaultConfig+-- >        , workspaces = toList myCursors } $+-- >        [("M-"++shift++control++[k], f direction depth)+-- >          | (f,shift) <- zip [modifyLayer,shiftModifyLayer] ["","S-"]+-- >          , (direction,control) <- zip [W.focusUp',W.focusDown'] ["C-",""]+-- >          , (depth,k) <- zip (reverse [1..focusDepth myCursors]) "asdf"]+-- >        ++ moreKeybindings+-- >+-- > moreKeybindings = []+-- >+-- > myCursors = makeCursors $ map (map (\x -> [x])) [ "1234", "abc", "xyz"]+-- > -- myCursors = makeCursors [["wsA","wsB","wsC"],["-alpha-","-beta-","-gamma-"],["x","y"]]+++-- $todo+--+-- * Find and document how to raise the allowable length of arguments:+--   restoring xmonad's state results in: @xmonad: executeFile: resource+--   exhausted (Argument list too long)@ when you specify more than about 50+--   workspaces. Or change it such that workspaces are created when you try to+--   view it.+--+-- * Function for pretty printing for DynamicLog that groups workspaces by+-- common prefixes+--+-- * Examples of adding workspaces to the cursors, having them appear multiple+--   times for being able to show jumping to some n'th multiple workspace++-- | makeCursors requires a nonempty string, and each sublist must be nonempty+makeCursors ::  [[String]] -> Cursors String+makeCursors [] = error "Workspace Cursors cannot be empty"+makeCursors a = concat . reverse <$> foldl addDim x xs+    where x = end $ map return $ head a+          xs = map (map return) $ tail a+          -- this could probably be simplified, but this true:+          -- toList . makeCursors == map (concat . reverse) . sequence . reverse . map (map (:[]))+          -- the strange order is used because it makes the regular M-1..9+          -- bindings change the prefixes first++addDim ::  (Monoid a) => Cursors a -> [a] -> Cursors a+addDim prev prefixes = Cons . fromJust . W.differentiate+            $ map ((<$> prev) . mappend) prefixes++end :: [a] -> Cursors a+end = Cons . fromJust . W.differentiate . map End++data Cursors a+    = Cons (W.Stack (Cursors a))+    | End a deriving (Eq,Show,Read,Typeable)++instance Foldable Cursors where+    foldMap f (End x) = f x+    foldMap f (Cons (W.Stack x y z)) = foldMap f x `mappend` mconcat (map (foldMap f) $ reverse y ++ z)++instance Functor Cursors where+    fmap f (End a) = End $ f a+    fmap f (Cons (W.Stack x y z)) = Cons $ W.Stack (fmap f x) (fmap (fmap f) y) (fmap (fmap f) z)++changeFocus ::  (Cursors t -> Bool) -> Cursors t -> [Cursors t]+changeFocus p (Cons x) = do+    choose <- chFocus p x+    foc    <- changeFocus p $ W.focus choose+    return . Cons $ choose { W.focus = foc }+changeFocus p x = guard (p x) >> return x++chFocus :: (a -> Bool) -> W.Stack a -> [W.Stack a]+chFocus p st = filter (p . W.focus) $ zipWith const (iterate W.focusDown' st) (W.integrate st)++getFocus ::  Cursors b -> b+getFocus (Cons x) = getFocus $ W.focus x+getFocus (End x) = x++-- This could be made more efficient, if the fact that the suffixes are grouped+focusTo ::  (Eq t) => t -> Cursors t -> Maybe (Cursors t)+focusTo x = listToMaybe . filter ((x==) . getFocus) . changeFocus (const True)++-- | non-wrapping version of 'W.focusUp''+noWrapUp ::  W.Stack t -> W.Stack t+noWrapUp (W.Stack t (l:ls) rs) = W.Stack l ls (t:rs)+noWrapUp x@(W.Stack _ []   _ ) = x++-- | non-wrapping version of 'W.focusDown''+noWrapDown ::  W.Stack t -> W.Stack t+noWrapDown = reverseStack . noWrapUp . reverseStack+    where reverseStack (W.Stack t ls rs) = W.Stack t rs ls++focusDepth ::  Cursors t -> Int+focusDepth (Cons x) = 1 + focusDepth (W.focus x)+focusDepth (End  _) = 0++descend :: Monad m =>(W.Stack (Cursors a) -> m (W.Stack (Cursors a)))-> Int-> Cursors a-> m (Cursors a)+descend f 1 (Cons x) = Cons `liftM` f x+descend f n (Cons x) | n > 1 = liftM Cons $ descend f (pred n) `onFocus` x+descend _ _ x = return x++onFocus :: (Monad m) => (a1 -> m a1) -> W.Stack a1 -> m (W.Stack a1)+onFocus f st = (\x -> st { W.focus = x}) `liftM` f (W.focus st)++-- | @modifyLayer@ is used to change the focus at a given depth+modifyLayer :: (W.Stack (Cursors String) -> W.Stack (Cursors String)) -> Int -> X ()+modifyLayer f depth = modifyCursors (descend (return . f) depth)++-- | @shiftModifyLayer@ is the same as 'modifyLayer', but also shifts the+-- currently focused window to the new workspace+shiftModifyLayer :: (W.Stack (Cursors String) -> W.Stack (Cursors WorkspaceId))-> Int-> X ()+shiftModifyLayer f = modifyLayer' $ \st -> do+    let st' = f st+    windows $ W.shift $ getFocus (Cons st')+    return st'++-- | @shiftLayer@ is the same as 'shiftModifyLayer', but the focus remains on+-- the current workspace.+shiftLayer :: (W.Stack (Cursors String) -> W.Stack (Cursors WorkspaceId))-> Int-> X ()+shiftLayer f = modifyLayer' $ \st -> do+    windows $ W.shift $ getFocus $ Cons $ f st+    return st++-- | example usages are 'shiftLayer' and 'shiftModifyLayer'+modifyLayer' :: (W.Stack (Cursors String) -> X (W.Stack (Cursors String))) -> Int -> X ()+modifyLayer' f depth = modifyCursors (descend f depth)++modifyCursors ::  (Cursors String -> X (Cursors String)) -> X ()+modifyCursors = sendMessage . ChangeCursors . (liftM2 (>>) updateXMD return <=<)++data WorkspaceCursors a = WorkspaceCursors (Cursors String)+    deriving (Typeable,Read,Show)++-- | The state is stored in the 'WorkspaceCursors' layout modifier. Put this as+-- your outermost modifier, unless you want different cursors at different+-- times (using "XMonad.Layout.MultiToggle")+workspaceCursors :: Cursors String -> l a -> ModifiedLayout WorkspaceCursors l a+workspaceCursors = ModifiedLayout . WorkspaceCursors++data ChangeCursors = ChangeCursors { unWrap :: Cursors String -> X (Cursors String) }+    deriving (Typeable)++instance Message ChangeCursors++updateXMD ::  Cursors WorkspaceId -> X ()+updateXMD cs = do+    changed <- gets $ (getFocus cs /=) . W.currentTag . windowset+    when changed $ windows $ W.greedyView $ getFocus cs++instance LayoutModifier WorkspaceCursors a where+    redoLayout (WorkspaceCursors cs) _ _ arrs = do+        cws <- gets $ W.currentTag . windowset+        return (arrs,WorkspaceCursors <$> focusTo cws cs)++    handleMess (WorkspaceCursors cs) m =+        sequenceA $ fmap WorkspaceCursors . ($ cs) . unWrap <$> fromMessage m
+ XMonad/Actions/WorkspaceNames.hs view
@@ -0,0 +1,155 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Actions.WorkspaceNames+-- Copyright   :  (c) Tomas Janousek <tomi@nomi.cz>+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Tomas Janousek <tomi@nomi.cz>+-- Stability   :  experimental+-- Portability :  unportable+--+-- Provides bindings to rename workspaces, show these names in DynamicLog and+-- swap workspaces along with their names. These names survive restart.+-- Together with "XMonad.Layout.WorkspaceDir" this provides for a fully+-- dynamic topic space workflow.+--+-----------------------------------------------------------------------------++{-# LANGUAGE DeriveDataTypeable #-}++module XMonad.Actions.WorkspaceNames (+    -- * Usage+    -- $usage++    -- * Workspace naming+    renameWorkspace,+    workspaceNamesPP,+    getWorkspaceNames,+    setWorkspaceName,+    setCurrentWorkspaceName,++    -- * Workspace swapping+    swapTo,+    swapTo',+    swapWithCurrent,+    ) where++import XMonad+import qualified XMonad.StackSet as W+import qualified XMonad.Util.ExtensibleState as XS++import XMonad.Actions.CycleWS (findWorkspace, WSType(..), Direction1D(..))+import qualified XMonad.Actions.SwapWorkspaces as Swap+import XMonad.Hooks.DynamicLog (PP(..))+import XMonad.Prompt (showXPrompt, mkXPrompt, XPrompt, XPConfig)+import XMonad.Util.WorkspaceCompare (getSortByIndex)++import qualified Data.Map as M+import Data.Maybe (fromMaybe)++-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:+--+-- > import XMonad.Actions.WorkspaceNames+--+-- Then add keybindings like the following:+--+-- >   , ((modm .|. shiftMask, xK_r      ), renameWorkspace defaultXPConfig)+--+-- and apply workspaceNamesPP to your DynamicLog pretty-printer:+--+-- > myLogHook =+-- >     workspaceNamesPP xmobarPP >>= dynamicLogString >>= xmonadPropLog+--+-- We also provide a modification of "XMonad.Actions.SwapWorkspaces"\'s+-- functionality, which may be used this way:+--+-- >   , ((modMask .|. shiftMask, xK_Left  ), swapTo Prev)+-- >   , ((modMask .|. shiftMask, xK_Right ), swapTo Next)+--+-- > [((modm .|. controlMask, k), swapWithCurrent i)+-- >     | (i, k) <- zip workspaces [xK_1 ..]]+--+-- For detailed instructions on editing your key bindings, see+-- "XMonad.Doc.Extending#Editing_key_bindings".++++-- | Workspace names container.+newtype WorkspaceNames = WorkspaceNames (M.Map WorkspaceId String)+    deriving (Typeable, Read, Show)++instance ExtensionClass WorkspaceNames where+    initialValue = WorkspaceNames M.empty+    extensionType = PersistentExtension++-- | Returns a function that maps workspace tag @\"t\"@ to @\"t:name\"@ for+-- workspaces with a name, and to @\"t\"@ otherwise.+getWorkspaceNames :: X (WorkspaceId -> String)+getWorkspaceNames = do+    WorkspaceNames m <- XS.get+    return $ \wks -> case M.lookup wks m of+        Nothing -> wks+        Just s  -> wks ++ ":" ++ s++-- | Sets the name of a workspace. Empty string makes the workspace unnamed+-- again.+setWorkspaceName :: WorkspaceId -> String -> X ()+setWorkspaceName w name = do+    WorkspaceNames m <- XS.get+    XS.put $ WorkspaceNames $ if null name then M.delete w m else M.insert w name m+    refresh++-- | Sets the name of the current workspace. See 'setWorkspaceName'.+setCurrentWorkspaceName :: String -> X ()+setCurrentWorkspaceName name = do+    current <- gets (W.currentTag . windowset)+    setWorkspaceName current name++data Wor = Wor String+instance XPrompt Wor where+    showXPrompt (Wor x) = x++-- | Prompt for a new name for the current workspace and set it.+renameWorkspace :: XPConfig -> X ()+renameWorkspace conf = do+    mkXPrompt pr conf (const (return [])) setCurrentWorkspaceName+    where pr = Wor "Workspace name: "++-- | Modify "XMonad.Hooks.DynamicLog"\'s pretty-printing format to show+-- workspace names as well.+workspaceNamesPP :: PP -> X PP+workspaceNamesPP pp = do+    names <- getWorkspaceNames+    return $+        pp {+            ppCurrent         = ppCurrent         pp . names,+            ppVisible         = ppVisible         pp . names,+            ppHidden          = ppHidden          pp . names,+            ppHiddenNoWindows = ppHiddenNoWindows pp . names,+            ppUrgent          = ppUrgent          pp . names+        }++-- | See 'XMonad.Actions.SwapWorkspaces.swapTo'. This is the same with names.+swapTo :: Direction1D -> X ()+swapTo dir = swapTo' dir AnyWS++-- | Swap with the previous or next workspace of the given type.+swapTo' :: Direction1D -> WSType -> X ()+swapTo' dir which = findWorkspace getSortByIndex dir which 1 >>= swapWithCurrent++-- | See 'XMonad.Actions.SwapWorkspaces.swapWithCurrent'. This is almost the+-- same with names.+swapWithCurrent :: WorkspaceId -> X ()+swapWithCurrent t = do+    current <- gets (W.currentTag . windowset)+    swapNames t current+    windows $ Swap.swapWorkspaces t current++-- | Swap names of the two workspaces.+swapNames :: WorkspaceId -> WorkspaceId -> X ()+swapNames w1 w2 = do+    WorkspaceNames m <- XS.get+    let getname w = fromMaybe "" $ M.lookup w m+        set w name m' = if null name then M.delete w m' else M.insert w name m'+    XS.put $ WorkspaceNames $ set w1 (getname w2) $ set w2 (getname w1) $ m
XMonad/Config/Arossato.hs view
@@ -1,4 +1,5 @@-{-# OPTIONS_GHC -fglasgow-exts -fno-warn-missing-signatures #-}+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}+{-# LANGUAGE NoMonomorphismRestriction #-} ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Config.Arossato
XMonad/Config/Azerty.hs view
@@ -7,6 +7,8 @@ -- License      : BSD -- -- Maintainer   : Devin Mullins <me@twifkak.com>+-- Stability    : stable+-- Portability  : unportable -- -- This module fixes some of the keybindings for the francophone among you who -- use an AZERTY keyboard layout. Config stolen from TeXitoi's config on the@@ -36,7 +38,7 @@ -- > import qualified Data.Map as M -- > main = xmonad someConfig { keys = \c -> azertyKeys c `M.union` keys someConfig c } -azertyConfig = defaultConfig { keys = \c -> azertyKeys c `M.union` keys defaultConfig c }+azertyConfig = defaultConfig { keys = azertyKeys <+> keys defaultConfig }  azertyKeys conf@(XConfig {modMask = modm}) = M.fromList $     [((modm, xK_semicolon), sendMessage (IncMasterN (-1)))]
+ XMonad/Config/Bluetile.hs view
@@ -0,0 +1,217 @@+{-# OPTIONS -fno-warn-missing-signatures #-}+----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Config.Bluetile+-- Copyright   :  (c) Jan Vornberger 2009+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de+-- Stability   :  unstable+-- Portability :  not portable+--+-- This is the default configuration of Bluetile+-- (<http://projects.haskell.org/bluetile/>). If you+-- are migrating from Bluetile to xmonad or want to create+-- a similar setup, then this will give you pretty much+-- the same thing, except for Bluetile's helper applications+-- such as the dock.+--+-----------------------------------------------------------------------------++module XMonad.Config.Bluetile (+    -- * Usage+    -- $usage+    bluetileConfig+    ) where++import XMonad hiding ( (|||) )++import XMonad.Layout.BorderResize+import XMonad.Layout.BoringWindows+import XMonad.Layout.ButtonDecoration+import XMonad.Layout.Decoration+import XMonad.Layout.DecorationAddons+import XMonad.Layout.DraggingVisualizer+import XMonad.Layout.LayoutCombinators+import XMonad.Layout.Maximize+import XMonad.Layout.Minimize+import XMonad.Layout.MouseResizableTile+import XMonad.Layout.Named+import XMonad.Layout.NoBorders+import XMonad.Layout.PositionStoreFloat+import XMonad.Layout.WindowSwitcherDecoration++import XMonad.Actions.BluetileCommands+import XMonad.Actions.CycleWS+import XMonad.Actions.WindowMenu++import XMonad.Hooks.CurrentWorkspaceOnTop+import XMonad.Hooks.EwmhDesktops+import XMonad.Hooks.ManageDocks+import XMonad.Hooks.ManageHelpers+import XMonad.Hooks.PositionStoreHooks+import XMonad.Hooks.RestoreMinimized+import XMonad.Hooks.ServerMode+import XMonad.Hooks.WorkspaceByPos++import XMonad.Config.Gnome++import qualified XMonad.StackSet as W+import qualified Data.Map as M++import System.Exit+import Data.Monoid+import Control.Monad(when)++-- $usage+-- To use this module, start with the following @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad+-- > import XMonad.Config.Bluetile+-- > import XMonad.Util.Replace+-- >+-- > main = replace >> xmonad bluetileConfig+--+-- The invocation of 'replace' will replace a currently running+-- window manager. This is the default behaviour of Bluetile as well.+-- See "XMonad.Util.Replace" for more information.++bluetileWorkspaces :: [String]+bluetileWorkspaces = ["1","2","3","4","5","6","7","8","9","0"]++bluetileKeys :: XConfig Layout -> M.Map (KeyMask, KeySym) (X ())+bluetileKeys conf@(XConfig {XMonad.modMask = modMask'}) = M.fromList $+    -- launching and killing programs+    [ ((modMask'              , xK_Return), spawn $ XMonad.terminal conf) -- %! Launch terminal+    , ((modMask',               xK_p     ), gnomeRun)    --  %! Launch Gnome "Run application" dialog+    , ((modMask' .|. shiftMask, xK_c     ), kill) -- %! Close the focused window++    , ((modMask',               xK_F5 ), refresh) -- %! Resize viewed windows to the correct size+    , ((modMask' .|. shiftMask, xK_F5 ), setLayout $ XMonad.layoutHook conf) -- %!  Reset the layouts on the current workspace to default++    , ((modMask',               xK_o ), windowMenu)++    -- move focus up or down the window stack+    , ((modMask',               xK_Tab   ), focusDown) -- %! Move focus to the next window+    , ((modMask' .|. shiftMask, xK_Tab   ), focusUp) -- %! Move focus to the previous window+    , ((modMask',               xK_j     ), focusDown) -- %! Move focus to the next window+    , ((modMask',               xK_k     ), focusUp) -- %! Move focus to the previous window+    , ((modMask',               xK_space ), focusMaster) -- %! Move focus to the master window++    -- modifying the window order+    , ((modMask' .|. shiftMask, xK_space ), windows W.swapMaster) -- %! Swap the focused window and the master window+    , ((modMask' .|. shiftMask, xK_j     ), windows W.swapDown  ) -- %! Swap the focused window with the next window+    , ((modMask' .|. shiftMask, xK_k     ), windows W.swapUp    ) -- %! Swap the focused window with the previous window++    -- resizing the master/slave ratio+    , ((modMask',               xK_h     ), sendMessage Shrink) -- %! Shrink the master area+    , ((modMask',               xK_l     ), sendMessage Expand) -- %! Expand the master area+    , ((modMask',               xK_u     ), sendMessage ShrinkSlave) -- %! Shrink a slave area+    , ((modMask',               xK_i     ), sendMessage ExpandSlave) -- %! Expand a slave area++    -- floating layer support+    , ((modMask',               xK_t     ), withFocused $ windows . W.sink) -- %! Push window back into tiling+    , ((modMask' .|. shiftMask, xK_t     ), withFocused $ float ) -- %! Float window++    -- increase or decrease number of windows in the master area+    , ((modMask'              , xK_comma ), sendMessage (IncMasterN 1)) -- %! Increment the number of windows in the master area+    , ((modMask'              , xK_period), sendMessage (IncMasterN (-1))) -- %! Deincrement the number of windows in the master area++    -- quit, or restart+    , ((modMask' .|. shiftMask, xK_q     ), io (exitWith ExitSuccess)) -- %! Quit+    , ((modMask'              , xK_q     ), restart "xmonad" True) -- %! Restart++    -- Metacity-like workspace switching+    , ((mod1Mask .|. controlMask, xK_Left), prevWS)+    , ((mod1Mask .|. controlMask, xK_Right), nextWS)+    , ((mod1Mask .|. controlMask .|. shiftMask,   xK_Left), shiftToPrev >> prevWS)+    , ((mod1Mask .|. controlMask .|. shiftMask,   xK_Right), shiftToNext >> nextWS)++    -- more Metacity keys+    , ((mod1Mask             , xK_F2), gnomeRun)+    , ((mod1Mask             , xK_F4), kill)++    -- Switching to layouts+    , ((modMask'              , xK_a), sendMessage $ JumpToLayout "Floating")+    , ((modMask'              , xK_s), sendMessage $ JumpToLayout "Tiled1")+    , ((modMask'              , xK_d), sendMessage $ JumpToLayout "Tiled2")+    , ((modMask'              , xK_f), sendMessage $ JumpToLayout "Fullscreen")++    -- Maximizing+    , ((modMask'              , xK_z), withFocused (sendMessage . maximizeRestore))++    -- Minimizing+    , ((modMask',               xK_m     ), withFocused (\f -> sendMessage (MinimizeWin f)))+    , ((modMask' .|. shiftMask, xK_m     ), sendMessage RestoreNextMinimizedWin)+    ]+    +++    -- mod-[1..9] ++ [0] %! Switch to workspace N+    -- mod-shift-[1..9] ++ [0] %! Move client to workspace N+    [((m .|. modMask', k), windows $ f i)+        | (i, k) <- zip (XMonad.workspaces conf) ([xK_1 .. xK_9] ++ [xK_0])+        , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]+    +++    -- mod-{w,e,r} %! Switch to physical/Xinerama screens 1, 2, or 3+    -- mod-shift-{w,e,r} %! Move client to screen 1, 2, or 3+    [((m .|. modMask', key), screenWorkspace sc >>= flip whenJust (windows . f))+        | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]+        , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]++bluetileMouseBindings :: XConfig Layout -> M.Map (KeyMask, Button) (Window -> X ())+bluetileMouseBindings (XConfig {XMonad.modMask = modMask'}) = M.fromList $+    -- mod-button1 %! Move a floated window by dragging+    [ ((modMask', button1), (\w -> isFloating w >>= \isF -> when (isF) $+                                focus w >> mouseMoveWindow w >> windows W.shiftMaster))+    -- mod-button2 %! Switch to next and first layout+    , ((modMask', button2), (\_ -> sendMessage NextLayout))+    , ((modMask' .|. shiftMask, button2), (\_ -> sendMessage $ JumpToLayout "Floating"))+    -- mod-button3 %! Resize a floated window by dragging+    , ((modMask', button3), (\w -> isFloating w >>= \isF -> when (isF) $+                                focus w >> mouseResizeWindow w >> windows W.shiftMaster))+    ]++isFloating :: Window -> X (Bool)+isFloating w = do+    ws <- gets windowset+    return $ M.member w (W.floating ws)++bluetileManageHook :: ManageHook+bluetileManageHook = composeAll+               [ workspaceByPos, positionStoreManageHook+                , className =? "MPlayer" --> doFloat+                , isFullscreen --> doFullFloat+                , manageDocks]++bluetileLayoutHook = avoidStruts $ minimize $ boringWindows $ (+                        named "Floating" floating |||+                        named "Tiled1" tiled1 |||+                        named "Tiled2" tiled2 |||+                        named "Fullscreen" fullscreen+                        )+        where+            floating = floatingDeco $ maximize $ borderResize $ positionStoreFloat+            tiled1 = tilingDeco $ maximize $ mouseResizableTileMirrored+            tiled2 = tilingDeco $ maximize $ mouseResizableTile+            fullscreen = tilingDeco $ maximize $ smartBorders Full++            tilingDeco l = windowSwitcherDecorationWithButtons shrinkText defaultThemeWithButtons (draggingVisualizer l)+            floatingDeco l = buttonDeco shrinkText defaultThemeWithButtons l++bluetileConfig =+    defaultConfig+        { modMask = mod4Mask,   -- logo key+          manageHook = bluetileManageHook,+          layoutHook = bluetileLayoutHook,+          logHook = currentWorkspaceOnTop >> ewmhDesktopsLogHook,+          handleEventHook = ewmhDesktopsEventHook+                                `mappend` fullscreenEventHook+                                `mappend` restoreMinimizedEventHook+                                `mappend` serverModeEventHook' bluetileCommands+                                `mappend` positionStoreEventHook,+          workspaces = bluetileWorkspaces,+          keys = bluetileKeys,+          mouseBindings = bluetileMouseBindings,+          focusFollowsMouse = False,+          focusedBorderColor = "#000000",+          terminal = "gnome-terminal"+        }
XMonad/Config/Desktop.hs view
@@ -7,30 +7,172 @@ -- License      : BSD -- -- Maintainer   : Spencer Janssen <spencerjanssen@gmail.com>+-- Stability    :  unstable+-- Portability  :  unportable -- -- This module provides a config suitable for use with a desktop -- environment such as KDE or GNOME.-+----------------------------------------------------------------------------- module XMonad.Config.Desktop (++    -- | Several basic integration settings are common to all of xmonad's+    -- desktop integration configurations. The specific desktop environment+    -- (DE) modules like "XMonad.Config.Gnome" use this module's+    -- @desktopConfig@ to set up basic communication between xmonad and+    -- the DE via a subset of the Extended Window Manager Hints (EWMH)+    -- specification. Extra xmonad settings unique to specific DE's are+    -- added by overriding or modifying @desktopConfig@ fields in the+    -- same way that @defaultConfig@ is customized in @~\/.xmonad/xmonad.hs@.+    --+    -- For more information about EWMH see:+    --+    -- <http://standards.freedesktop.org/wm-spec/wm-spec-latest.html>+    --+    -- See also: "XMonad.Hooks.EwmhDesktops", "XMonad.Hooks.ManageDocks",+    -- "XMonad.Util.EZConfig".++    -- * Usage+    -- $usage+     desktopConfig,++    -- * Customizing a desktop config+    -- $customizing++    -- ** Modifying layouts, manageHook, or key bindings+    -- $layouts     desktopLayoutModifiers++    -- ** Modifying the logHook+    -- $logHook++    -- ** Modifying the handleEventHook+    -- $eventHook++    -- ** Modifying the startupHook+    -- $startupHook     ) where  import XMonad-import XMonad.Config (defaultConfig) import XMonad.Hooks.ManageDocks import XMonad.Hooks.EwmhDesktops+import XMonad.Util.Cursor  import qualified Data.Map as M -desktopConfig = defaultConfig-    { logHook    = ewmhDesktopsLogHook-    , layoutHook = desktopLayoutModifiers $ layoutHook defaultConfig-    , manageHook = manageHook defaultConfig <+> manageDocks-    , handleEventHook = ewmhDesktopsEventHook-    , keys       = \c -> desktopKeys c `M.union` keys defaultConfig c }+-- $usage+-- While this document describes how to configure xmonad, you also need+-- to set up your Desktop Environment (DE) and display manager to use+-- xmonad as its window manager. For DE and distro specific tips on+-- how to do so, see the xmonad wiki:+--+-- <http://haskell.org/haskellwiki/Xmonad>+--+-- To configure xmonad for use with a DE or with DE tools like panels+-- and pagers, in place of @defaultConfig@ in your @~\/.xmonad/xmonad.hs@,+-- use @desktopConfig@ or one of the other desktop configs from the+-- @XMonad.Config@ namespace. The following setup and customization examples+-- work the same way for the other desktop configs as for @desktopConfig@.+-- If you are using a specific DE config, import its module instead, and+-- use its config in place of @desktopConfig@ in the following examples.+--+-- > import XMonad+-- > import XMonad.Config.Desktop+-- >+-- > main = xmonad desktopConfig+--+-- @desktopConfig@ is an 'XConfig' that configures xmonad to+-- ignore and leave room for dock type windows like panels and trays, adds+-- the default key binding to toggle panel visibility, and activates basic+-- EWMH support. It also sets a prettier root window mouse pointer. +-- $customizing+-- To customize a desktop config, modify its fields as is illustrated with+-- @defaultConfig@ in "XMonad.Doc.Extending#Extending xmonad".++-- $layouts+-- See also "XMonad.Util.EZConfig" for more options for modifying key bindings.+-- To add to layouts, manageHook or key bindings use something like the following+-- to combine your modifications with the desktop config settings:+--+-- > import XMonad+-- > import XMonad.Config.Desktop+-- > import XMonad.Layout.Tabbed+-- > import XMonad.Util.EZConfig (additionalKeys)+-- >+-- > main =+-- >   xmonad $ desktopConfig {+-- >     -- add manage hooks while still ignoring panels and using default manageHooks+-- >       manageHook = myManageHook <+> manageHook desktopConfig+-- >+-- >     -- add a fullscreen tabbed layout that does not avoid covering+-- >     -- up desktop panels before the desktop layouts+-- >     , layoutHook = simpleTabbed ||| layoutHook desktopConfig+-- >     }+-- >     -- add a screenshot key to the default desktop bindings+-- >     `additionalKeys` [ ((mod4Mask, xK_F8), spawn "scrot") ]+--+-- To replace the desktop layouts with your own choices, but still+-- allow toggling panel visibility, use 'desktopLayoutModifiers' to+-- modify your layouts:+--+-- >  , layoutHook = desktopLayoutModifiers $ simpleTabbed ||| Tall 1 0.03 0.5+--+-- @desktopLayoutModifiers@ modifies a layout to avoid covering docks, panels,+-- etc. that set the @_NET_WM_STRUT_PARTIAL@ property.+-- See also "XMonad.Hooks.ManageDocks".++-- $logHook+-- To add to the logHook while still sending workspace and window information+-- to DE apps use something like:+--+-- >  , logHook = myLogHook >> logHook desktopConfig+--+-- Or for more elaborate logHooks you can use @do@:+--+-- >  , logHook = do+-- >        dynamicLogWithPP xmobarPP+-- >        updatePointer (Relative 0.9 0.9)+-- >        logHook desktopConfig+--++-- $eventHook+-- To customize xmonad's event handling while still having it respond+-- to EWMH events from pagers, task bars, etc. add to your imports:+--+-- > import Data.Monoid+--+-- and use 'Data.Monoid.mappend' to combine event hooks (right to left application like @\<+\>@)+--+-- >  , handleEventHook = mappend myEventHooks (handleEventHook desktopConfig)+--+-- or 'Data.Monoid.mconcat' (like @composeAll@)+--+-- >  , handleEventHook = mconcat+-- >        [ myMouseHandler+-- >        , myMessageHandler+-- >        , handleEventHook desktopConfig ]+--++-- $startupHook+-- To run the desktop startupHook, plus add further actions to be run each+-- time xmonad starts or restarts, use '>>' to combine actions as in the+-- logHook example, or something like:+--+-- >  , startupHook = do+-- >        startupHook desktopConfig+-- >        spawn "xmonad-restart.sh"+-- >        adjustEventInput+--++desktopConfig = ewmh defaultConfig+    { startupHook     = setDefaultCursor xC_left_ptr+    , layoutHook      = desktopLayoutModifiers $ layoutHook defaultConfig+    , manageHook      = manageHook defaultConfig <+> manageDocks+    , keys            = desktopKeys <+> keys defaultConfig }+ desktopKeys (XConfig {modMask = modm}) = M.fromList $     [ ((modm, xK_b), sendMessage ToggleStruts) ]  desktopLayoutModifiers layout = avoidStruts layout+
XMonad/Config/Droundy.hs view
@@ -10,7 +10,6 @@  import XMonad hiding (keys, config, (|||)) import qualified XMonad (keys)-import XMonad.Config ( defaultConfig )  import qualified XMonad.StackSet as W import qualified Data.Map as M@@ -22,7 +21,7 @@ import XMonad.Layout.Named ( named ) import XMonad.Layout.LayoutCombinators import XMonad.Layout.Square ( Square(Square) )-import XMonad.Layout.WindowNavigation ( Navigate(Move,Swap,Go), Direction(U,D,R,L),+import XMonad.Layout.WindowNavigation ( Navigate(Move,Swap,Go), Direction2D(U,D,R,L),                                         windowNavigation ) import XMonad.Layout.BoringWindows ( boringWindows, markBoring, clearBoring,                                      focusUp, focusDown )@@ -40,11 +39,10 @@ import XMonad.Actions.DynamicWorkspaces ( withNthWorkspace, withWorkspace,                                           selectWorkspace, renameWorkspace, removeWorkspace ) import XMonad.Actions.CycleWS ( moveTo, WSType( HiddenNonEmptyWS ),-                                WSDirection( Prev, Next) )+                                Direction1D( Prev, Next) )  import XMonad.Hooks.ManageDocks ( avoidStruts, manageDocks )-import XMonad.Hooks.EwmhDesktops ( ewmhDesktopsLogHook,-                                   ewmhDesktopsEventHook )+import XMonad.Hooks.EwmhDesktops ( ewmh )  myXPConfig :: XPConfig myXPConfig = defaultXPConfig {font="-*-lucida-medium-r-*-*-14-*-*-*-*-*-*-*"@@ -95,7 +93,7 @@     , ((modMask x .|. controlMask .|. shiftMask, xK_Left), sendMessage $ Move L)     , ((modMask x .|. controlMask .|. shiftMask, xK_Up), sendMessage $ Move U)     , ((modMask x .|. controlMask .|. shiftMask, xK_Down), sendMessage $ Move D)- +     , ((0, xK_F2  ), spawn "gnome-terminal") -- %! Launch gnome-terminal     , ((0, xK_F3  ), shellPrompt myXPConfig) -- %! Launch program     , ((0, xK_F11   ), spawn "ksnapshot") -- %! Take snapshot@@ -112,13 +110,13 @@     , ((modMask x, xK_space), sendMessage Toggle)      ]- +     ++     zip (zip (repeat $ modMask x) [xK_F1..xK_F12]) (map (withNthWorkspace W.greedyView) [0..])     ++     zip (zip (repeat (modMask x .|. shiftMask)) [xK_F1..xK_F12]) (map (withNthWorkspace copy) [0..]) -config = defaultConfig+config = ewmh defaultConfig          { borderWidth = 1 -- Width of the window border in pixels.          , XMonad.workspaces = ["mutt","iceweasel"]          , layoutHook = showWName $ workspaceDir "~" $@@ -131,11 +129,9 @@                                                 ****//* combineTwo Square mytab mytab) --   |||                         --mosaic 0.25 0.5          , manageHook = manageHook defaultConfig <+> manageDocks -- add panel-handling-         , logHook = ewmhDesktopsLogHook -- actually, no logging here, just other stuff          , terminal = "xterm" -- The preferred terminal program.          , normalBorderColor = "#222222" -- Border color for unfocused windows.          , focusedBorderColor = "#00ff00" -- Border color for focused windows.-         , handleEventHook = ewmhDesktopsEventHook          , XMonad.modMask = mod1Mask          , XMonad.keys = keys          }@@ -143,12 +139,12 @@ mytab = tabbed CustomShrink defaultTheme  instance Shrinker CustomShrink where-    shrinkIt shr s | Just s' <- dropFromHead " " s = shrinkIt shr s' -    shrinkIt shr s | Just s' <- dropFromTail " " s = shrinkIt shr s' -    shrinkIt shr s | Just s' <- dropFromTail "- Iceweasel" s = shrinkIt shr s' -    shrinkIt shr s | Just s' <- dropFromTail "- KPDF" s = shrinkIt shr s' -    shrinkIt shr s | Just s' <- dropFromHead "file://" s = shrinkIt shr s' -    shrinkIt shr s | Just s' <- dropFromHead "http://" s = shrinkIt shr s' +    shrinkIt shr s | Just s' <- dropFromHead " " s = shrinkIt shr s'+    shrinkIt shr s | Just s' <- dropFromTail " " s = shrinkIt shr s'+    shrinkIt shr s | Just s' <- dropFromTail "- Iceweasel" s = shrinkIt shr s'+    shrinkIt shr s | Just s' <- dropFromTail "- KPDF" s = shrinkIt shr s'+    shrinkIt shr s | Just s' <- dropFromHead "file://" s = shrinkIt shr s'+    shrinkIt shr s | Just s' <- dropFromHead "http://" s = shrinkIt shr s'     shrinkIt _ s | n > 9 = s : map cut [2..(halfn-3)] ++ shrinkIt shrinkText s                  where n = length s                        halfn = n `div` 2
XMonad/Config/Gnome.hs view
@@ -7,6 +7,8 @@ -- License      : BSD -- -- Maintainer   : Spencer Janssen <spencerjanssen@gmail.com>+-- Stability    :  unstable+-- Portability  :  unportable -- -- This module provides a config suitable for use with the GNOME desktop -- environment.@@ -15,14 +17,18 @@     -- * Usage     -- $usage     gnomeConfig,-    gnomeRun+    gnomeRun,+    gnomeRegister     ) where  import XMonad import XMonad.Config.Desktop+import XMonad.Util.Run (safeSpawn)  import qualified Data.Map as M +import System.Environment (getEnvironment)+ -- $usage -- To use this module, start with the following @~\/.xmonad\/xmonad.hs@: --@@ -30,11 +36,13 @@ -- > import XMonad.Config.Gnome -- > -- > main = xmonad gnomeConfig--- +--+-- For examples of how to further customize @gnomeConfig@ see "XMonad.Config.Desktop".  gnomeConfig = desktopConfig     { terminal = "gnome-terminal"-    , keys     = \c -> gnomeKeys c `M.union` keys desktopConfig c }+    , keys     = gnomeKeys <+> keys desktopConfig+    , startupHook = gnomeRegister >> startupHook desktopConfig }  gnomeKeys (XConfig {modMask = modm}) = M.fromList $     [ ((modm, xK_p), gnomeRun)@@ -53,3 +61,22 @@         setClientMessageEvent e rw gnome_panel 32 panel_run 0         sendEvent dpy rw False structureNotifyMask e         sync dpy False++-- | Register xmonad with gnome. 'dbus-send' must be in the $PATH with which+-- xmonad is started.+--+-- This action reduces a delay on startup only only if you have configured+-- gnome-session>=2.26: to start xmonad with a command as such:+--+-- > gconftool-2 -s /desktop/gnome/session/required_components/windowmanager xmonad --type string+gnomeRegister :: MonadIO m => m ()+gnomeRegister = io $ do+    x <- lookup "DESKTOP_AUTOSTART_ID" `fmap` getEnvironment+    whenJust x $ \sessionId -> safeSpawn "dbus-send"+            ["--session"+            ,"--print-reply=string"+            ,"--dest=org.gnome.SessionManager"+            ,"/org/gnome/SessionManager"+            ,"org.gnome.SessionManager.RegisterClient"+            ,"string:xmonad"+            ,"string:"++sessionId]
XMonad/Config/Kde.hs view
@@ -7,6 +7,8 @@ -- License      : BSD -- -- Maintainer   : Spencer Janssen <spencerjanssen@gmail.com>+-- Stability    :  unstable+-- Portability  :  unportable -- -- This module provides a config suitable for use with the KDE desktop -- environment.@@ -32,15 +34,17 @@ -- > main = xmonad kdeConfig -- -- For KDE 4, replace 'kdeConfig' with 'kde4Config'--- +--+-- For examples of how to further customize @kdeConfig@ see "XMonad.Config.Desktop". + kdeConfig = desktopConfig     { terminal = "konsole"-    , keys     = \c -> kdeKeys c `M.union` keys desktopConfig c }+    , keys     = kdeKeys <+> keys desktopConfig }  kde4Config = desktopConfig     { terminal = "konsole"-    , keys     = \c -> kde4Keys c `M.union` keys desktopConfig c }+    , keys     = kde4Keys <+> keys desktopConfig }  kdeKeys (XConfig {modMask = modm}) = M.fromList $     [ ((modm,               xK_p), spawn "dcop kdesktop default popupExecuteCommand")
XMonad/Config/Sjanssen.hs view
@@ -1,58 +1,64 @@ {-# OPTIONS_GHC -fno-warn-missing-signatures #-}-module XMonad.Config.Sjanssen (sjanssenConfig, sjanssenConfigXmobar) where+module XMonad.Config.Sjanssen (sjanssenConfig) where  import XMonad hiding (Tall(..)) import qualified XMonad.StackSet as W import XMonad.Actions.CopyWindow import XMonad.Layout.Tabbed import XMonad.Layout.HintedTile-import XMonad.Config (defaultConfig) import XMonad.Layout.NoBorders-import XMonad.Hooks.DynamicLog hiding (xmobar)+import XMonad.Hooks.DynamicLog import XMonad.Hooks.ManageDocks+import XMonad.Hooks.ManageHelpers (isFullscreen, doFullFloat) import XMonad.Hooks.EwmhDesktops import XMonad.Prompt import XMonad.Actions.SpawnOn+import XMonad.Util.SpawnOnce  import XMonad.Layout.LayoutScreens import XMonad.Layout.TwoPane  import qualified Data.Map as M -sjanssenConfigXmobar = statusBar "xmobar" sjanssenPP strutkey =<< sjanssenConfig- where-    strutkey (XConfig {modMask = modm}) = (modm, xK_b)--sjanssenConfig = do-    sp <- mkSpawner-    return $ defaultConfig-        { terminal = "urxvtc"+sjanssenConfig =+    ewmh $ defaultConfig+        { terminal = "exec urxvt"         , workspaces = ["irc", "web"] ++ map show [3 .. 9 :: Int]         , mouseBindings = \(XConfig {modMask = modm}) -> M.fromList $                 [ ((modm, button1), (\w -> focus w >> mouseMoveWindow w))                 , ((modm, button2), (\w -> focus w >> windows W.swapMaster))                 , ((modm.|. shiftMask, button1), (\w -> focus w >> mouseResizeWindow w)) ]-        , keys = \c -> mykeys sp c `M.union` keys defaultConfig c-        , layoutHook = modifiers layouts-        , logHook    = ewmhDesktopsLogHook-        , manageHook = composeAll [className =? x --> doShift w+        , keys = \c -> mykeys c `M.union` keys defaultConfig c+        , logHook = dynamicLogString sjanssenPP >>= xmonadPropLog+        , layoutHook  = modifiers layouts+        , manageHook  = composeAll [className =? x --> doShift w                                     | (x, w) <- [ ("Firefox", "web")                                                 , ("Ktorrent", "7")                                                 , ("Amarokapp", "7")]]-                       <+> manageHook defaultConfig <+> manageDocks <+> manageSpawn sp+                        <+> manageHook defaultConfig <+> manageDocks <+> manageSpawn+                        <+> (isFullscreen --> doFullFloat)+        , startupHook = mapM_ spawnOnce spawns         }  where     tiled     = HintedTile 1 0.03 0.5 TopLeft     layouts   = (tiled Tall ||| (tiled Wide ||| Full)) ||| tabbed shrinkText myTheme-    modifiers = smartBorders+    modifiers = avoidStruts . smartBorders -    mykeys sp (XConfig {modMask = modm, workspaces = ws}) = M.fromList $-        [((modm,               xK_p     ), shellPromptHere sp myPromptConfig)+    spawns = [ "xmobar"+             , "xset -b", "xset s off", "xset dpms 0 600 1200"+             , "nitrogen --set-tiled wallpaper/wallpaper.jpg"+             , "trayer --transparent true --expand true --align right "+               ++ "--edge bottom --widthtype request" ]++    mykeys (XConfig {modMask = modm}) = M.fromList $+        [((modm,               xK_p     ), shellPromptHere myPromptConfig)+        ,((modm .|. shiftMask, xK_Return), spawnHere =<< asks (terminal . config))         ,((modm .|. shiftMask, xK_c     ), kill1)         ,((modm .|. shiftMask .|. controlMask, xK_c     ), kill)-        ,((modm .|. shiftMask, xK_0     ), windows $ \w -> foldr copy w ws)+        ,((modm .|. shiftMask, xK_0     ), windows $ copyToAll)         ,((modm,               xK_z     ), layoutScreens 2 $ TwoPane 0.5 0.5)         ,((modm .|. shiftMask, xK_z     ), rescreen)+        , ((modm             , xK_b     ), sendMessage ToggleStruts)         ]      myFont = "xft:Bitstream Vera Sans Mono:pixelsize=10"
XMonad/Config/Xfce.hs view
@@ -6,7 +6,9 @@ -- Copyright    : (c) Ivan Miljenovic <Ivan.Miljenovic@gmail.com> -- License      : BSD ----- Maintainer   : Ivan Miljenovic <Ivan.Miljenovic@gmail.com>+-- Maintainer   :  none+-- Stability    :  unstable+-- Portability  :  unportable -- -- This module provides a config suitable for use with the Xfce desktop -- environment.@@ -29,11 +31,12 @@ -- > import XMonad.Config.Xfce -- > -- > main = xmonad xfceConfig--- +--+-- For examples of how to further customize @xfceConfig@ see "XMonad.Config.Desktop".  xfceConfig = desktopConfig     { terminal = "Terminal"-    , keys     = \c -> xfceKeys c `M.union` keys desktopConfig c }+    , keys     = xfceKeys <+> keys desktopConfig }  xfceKeys (XConfig {modMask = modm}) = M.fromList $     [ ((modm,               xK_p), spawn "xfrun4")
XMonad/Doc/Configuring.hs view
@@ -49,16 +49,25 @@ that this file can contain arbitrary Haskell code, which means that you have quite a lot of flexibility in configuring xmonad. -NOTE for users of previous versions (< 0.5) of xmonad: this is a major-change in the way xmonad is configured.  Prior to version 0.5,-configuring xmonad required editing an xmonad source file called-Config.hs, recompiling xmonad, and then restarting.  From version 0.5-onwards, however, you should NOT edit this file.  All you have to do-is edit xmonad.hs and restart with @mod-q@; xmonad does the-recompiling itself.  The format of the configuration file has also-changed; it is now simpler and much shorter, only requiring you to-list those settings which are different from the defaults.+HISTORICAL NOTE regarding upgrading from versions (< 0.5) of xmonad+or using old documentation: +xmonad-0.5 delivered a major change in the way xmonad is configured.  Prior+to version 0.5, configuring xmonad required editing a source file called+Config.hs, manually recompiling xmonad, and then restarting.  From+version 0.5 onwards, however, you should NOT edit this file or manually+compile with ghc --make.  All you have to do is edit xmonad.hs and restart+with @mod-q@; xmonad does the recompiling itself. The format of the+configuration file also changed with version 0.5; enabling simpler and+much shorter xmonad.hs files that only require listing those settings which+are different from the defaults.++While the complicated template.hs (man/xmonad.hs) files listing all default+settings are still provided for reference, once you wish to make substantial+changes to your configuration, the template.hs style configuration is not+recommended. It is fine to use top-level definitions to organize your+xmonad.hs, but wherever possible it is better to leave out settings that+simply duplicate defaults. -}  {- $example@@ -90,8 +99,8 @@  As an alternative, you can copy the template @xmonad.hs@ file (found either in the @man@ directory, if you have the xmonad source, or on-the xmonad wiki at-@http:\/\/haskell.org\/haskellwiki\/Xmonad\/Config_archive\/Template_xmonad.hs@)+the xmonad wiki config archive at+<http://haskell.org/haskellwiki/Xmonad/Config_archive>) into your @~\/.xmonad\/@ directory.  This template file contains all the default settings spelled out, and you should be able to simply change the ones you would like to change.@@ -135,7 +144,8 @@ related to your layouts, you may need to hit @mod-shift-space@ after restarting to see the changes take effect.)  If something goes wrong, the previous (default) settings will be used.  Note this requires that-GHC and xmonad are in your @$PATH@.+GHC and xmonad are in the @$PATH@ in the environment from which xmonad+is started.  -} 
XMonad/Doc/Extending.hs view
@@ -116,82 +116,176 @@ See "XMonad.Doc.Extending#Editing_key_bindings" for instructions on how to edit your key bindings. -* "XMonad.Actions.Commands": running internal xmonad actions-  interactively.+* "XMonad.Actions.Commands":+    Allows you to run internal xmonad commands (X () actions) using+    a dmenu menu in addition to key bindings.  Requires dmenu and+    the Dmenu XMonad.Actions module. -* "XMonad.Actions.ConstrainedResize": an aspect-ratio-constrained-  window resizing mode.+* "XMonad.Actions.ConstrainedResize":+    Lets you constrain the aspect ratio of a floating+    window (by, say, holding shift while you resize).+    Useful for making a nice circular XClock window. -* "XMonad.Actions.CopyWindow": duplicating windows on multiple-  workspaces.+* "XMonad.Actions.CopyWindow":+    Provides bindings to duplicate a window on multiple workspaces,+    providing dwm-like tagging functionality. -* "XMonad.Actions.CycleSelectedLayouts": bind a key to cycle through a-  particular subset of your layouts.+* "XMonad.Actions.CycleRecentWS":+    Provides bindings to cycle through most recently used workspaces+    with repeated presses of a single key (as long as modifier key is+    held down). This is similar to how many window managers handle+    window switching. -* "XMonad.Actions.CycleWS": move between workspaces in various ways.+* "XMonad.Actions.CycleSelectedLayouts":+    This module allows to cycle through the given subset of layouts. -* "XMonad.Actions.DeManage": cease management of a window without-  unmapping it.+* "XMonad.Actions.CycleWS":+    Provides bindings to cycle forward or backward through the list of+    workspaces, to move windows between workspaces, and to cycle+    between screens. Replaces the former XMonad.Actions.RotView. -* "XMonad.Actions.DwmPromote": dwm-like master window swapping.+* "XMonad.Actions.CycleWindows":+    Provides bindings to cycle windows up or down on the current workspace+    stack while maintaining focus in place. -* "XMonad.Actions.DynamicWorkspaces": add, delete, and rename workspaces.+* "XMonad.Actions.DeManage":+    This module provides a method to cease management of a window+    without unmapping it. "XMonad.Hooks.ManageDocks" is a+    more automated solution if your panel supports it. -* "XMonad.Actions.FindEmptyWorkspace": find an empty workspace.+* "XMonad.Actions.DwmPromote":+    Dwm-like swap function for xmonad.+    Swaps focused window with the master window. If focus is in the+    master, swap it with the next window in the stack. Focus stays in the+    master. -* "XMonad.Actions.FlexibleManipulate": move\/resize windows without-  warping the mouse.+* "XMonad.Actions.DynamicWorkspaces":+    Provides bindings to add and delete workspaces.  Note that you may only+    delete a workspace that is already empty. -* "XMonad.Actions.FlexibleResize": resize windows from any corner.+* "XMonad.Actions.FindEmptyWorkspace":+    Find an empty workspace. -* "XMonad.Actions.FloatKeys": move\/resize floating windows with-  keybindings.+* "XMonad.Actions.FlexibleManipulate":+    Move and resize floating windows without warping the mouse. -* "XMonad.Actions.FocusNth": focus the nth window on the screen.+* "XMonad.Actions.FlexibleResize":+    Resize floating windows from any corner. -* "XMonad.Actions.MouseGestures": bind mouse gestures to actions.+* "XMonad.Actions.FloatKeys":+    Move and resize floating windows. -* "XMonad.Actions.MouseResize": use with-  "XMonad.Layout.WindowArranger" to resize windows with the mouse when-  using a floating layout.+* "XMonad.Layout.FloatSnap":+    Move and resize floating windows using other windows and the edge of the+    screen as guidelines. -* "XMonad.Actions.NoBorders": forcibly remove borders from a window.-  Not to be confused with "XMonad.Layout.NoBorders".+* "XMonad.Actions.FocusNth":+    Focus the nth window of the current workspace. -* "XMonad.Actions.PerWorkspaceKeys": configure keybindings-  per-workspace.+* "XMonad.Actions.GridSelect":+    GridSelect displays items(e.g. the opened windows) in a 2D grid and lets+    the user select from it with the cursor/hjkl keys or the mouse. -* "XMonad.Actions.Promote": An action to move the focused window to-  the master pane, or swap the master with the next window.+* "XMonad.Actions.MessageFeedback":+    Alternative to 'XMonad.Operations.sendMessage' that provides knowledge+    of whether the message was handled, and utility functions based on+    this facility. -* "XMonad.Actions.RotSlaves": rotate non-master windows.+* "XMonad.Actions.MouseGestures":+    Support for simple mouse gestures. -* "XMonad.Actions.Search": provide helpful functions for easily-  running web searchs.+* "XMonad.Actions.MouseResize":+    A layout modifier to resize windows with the mouse by grabbing the+    window's lower right corner. -* "XMonad.Actions.SimpleDate": display the date in a popup menu.+* "XMonad.Actions.NoBorders":+    This module provides helper functions for dealing with window borders. -* "XMonad.Actions.SinkAll": sink all floating windows.+* "XMonad.Actions.OnScreen":+    Control workspaces on different screens (in xinerama mode). -* "XMonad.Actions.Submap": create key submaps, i.e. the ability to-  bind actions to key sequences rather than being limited to single-  key combinations.+* "XMonad.Actions.PerWorkspaceKeys":+    Define key-bindings on per-workspace basis. -* "XMonad.Actions.SwapWorkspaces": swap workspace tags.+* "XMonad.Actions.PhysicalScreens":+    Manipulate screens ordered by physical location instead of ID -* "XMonad.Actions.TagWindows": tag windows and select by tag.+* "XMonad.Actions.Plane":+    This module has functions to navigate through workspaces in a bidimensional+    manner. -* "XMonad.Actions.UpdatePointer": mouse-follows-focus.+* "XMonad.Actions.Promote":+    Alternate promote function for xmonad. -* "XMonad.Actions.Warp": warp the pointer.+* "XMonad.Actions.RandomBackground":+    An action to start terminals with a random background color -* "XMonad.Actions.WindowBringer": bring windows to you, and you to-  windows.+* "XMonad.Actions.RotSlaves":+    Rotate all windows except the master window and keep the focus in+    place. -* "XMonad.Actions.WindowGo": travel to windows based on various-  criteria; conditionally start a program if a window does not exist,-  or travel to that window if it does.+* "XMonad.Actions.Search":+    A module for easily running Internet searches on web sites through xmonad.+    Modeled after the handy Surfraw CLI search tools at <https://secure.wikimedia.org/wikipedia/en/wiki/Surfraw>. +* "XMonad.Actions.SimpleDate":+    An example external contrib module for XMonad.+    Provides a simple binding to dzen2 to print the date as a popup menu.++* "XMonad.Actions.SinkAll":+    (Deprecated) Provides a simple binding that pushes all floating windows on the+    current workspace back into tiling. Instead, use the more general+    "XMonad.Actions.WithAll"++* "XMonad.Actions.SpawnOn":+    Provides a way to modify a window spawned by a command(e.g shift it to the workspace+    it was launched on) by using the _NET_WM_PID property that most windows set on creation.++* "XMonad.Actions.Submap":+    A module that allows the user to create a sub-mapping of key bindings.++* "XMonad.Actions.SwapWorkspaces":+    Lets you swap workspace tags, so you can keep related ones next to+    each other, without having to move individual windows.++* "XMonad.Actions.TagWindows":+    Functions for tagging windows and selecting them by tags.++* "XMonad.Actions.TopicSpace":+    Turns your workspaces into a more topic oriented system.++* "XMonad.Actions.UpdateFocus":+    Updates the focus on mouse move in unfocused windows.++* "XMonadContrib.UpdatePointer":+    Causes the pointer to follow whichever window focus changes to.++* "XMonad.Actions.Warp":+    Warp the pointer to a given window or screen.++* "XMonad.Actions.WindowBringer":+    dmenu operations to bring windows to you, and bring you to windows.+    That is to say, it pops up a dmenu with window names, in case you forgot+    where you left your XChat.++* "XMonad.Actions.WindowGo":+    Defines a few convenient operations for raising (traveling to) windows based on XMonad's Query+    monad, such as 'runOrRaise'.++* "XMonad.Actions.WindowMenu":+    Uses "XMonad.Actions.GridSelect" to display a number of actions related to+    window management in the center of the focused window.++* "XMonad.Actions.WindowNavigation":+    Experimental rewrite of "XMonad.Layout.WindowNavigation".++* "XMonad.Actions.WithAll":+    Provides functions for performing a given action on all windows of+    the current workspace.++* "XMonad.Actions.WorkspaceCursors":+    Like "XMonad.Actions.Plane" for an arbitrary number of dimensions.+ -}  {- $configs@@ -202,14 +296,27 @@ configuration; you can also simply import them and use them as your own configuration, possibly with some modifications. + * "XMonad.Config.Arossato"+    This module specifies my xmonad defaults. -* "XMonad.Config.Dons"+* "XMonad.Config.Azerty"+    Fixes some keybindings for users of French keyboard layouts. -* "XMonad.Config.Droundy"+* "XMonad.Config.Desktop"+    This module provides core desktop environment settings used+    in the Gnome, Kde, and Xfce config configs. It is also useful+    for people using other environments such as lxde, or using+    tray or panel applications without full desktop environments. +* "XMonad.Config.Gnome"++* "XMonad.Config.Kde"+ * "XMonad.Config.Sjanssen" +* "XMonad.Config.Xfce"+ -}  {- $hooks@@ -236,35 +343,80 @@   See "XMonad.Doc.Extending#The_log_hook_and_external_status_bars" for more   information. +* 'XMonad.Core.handleEventHook': this hook is called on all events handled+  by xmonad, thus it is extremely powerful. See "Graphics.X11.Xlib.Extras"+  and xmonad source and development documentation for more details.+ Here is a list of the modules found in @XMonad.Hooks@: +* "XMonad.Hooks.DynamicHooks":+    One-shot and permanent ManageHooks that can be updated at runtime.+ * "XMonad.Hooks.DynamicLog": for use with 'XMonad.Core.logHook'; send   information about xmonad's state to standard output, suitable for   putting in a status bar of some sort. See   "XMonad.Doc.Extending#The_log_hook_and_external_status_bars". -* "XMonad.Hooks.EventHook": a hook to handle X events at the layout level.+* "XMonad.Hooks.EwmhDesktops":+    Makes xmonad use the EWMH hints to tell panel applications about its+    workspaces and the windows therein. It also allows the user to interact+    with xmonad by clicking on panels and window lists. -* "XMonad.Hooks.EwmhDesktops": support for pagers in panel applications.+* "XMonad.Hooks.FadeInactive":+    Makes XMonad set the _NET_WM_WINDOW_OPACITY atom for inactive windows,+    which causes those windows to become slightly translucent if something+    like xcompmgr is running -* "XMonad.Hooks.ManageDocks": handle DOCK and STRUT windows (such as-  status bars) appropriately, by de-managing them and creating-  appropriate gaps so as not to place other windows covering them.+* "XMonad.Hooks.FloatNext":+    Hook and keybindings for automatically sending the next+    spawned window(s) to the floating layer. +* "XMonad.Hooks.InsertPosition":+    Configure where new windows should be added and which window should be+    focused.++* "XMonad.Hooks.ManageDocks":+    This module provides tools to automatically manage 'dock' type programs,+    such as gnome-panel, kicker, dzen, and xmobar.+ * "XMonad.Hooks.ManageHelpers": provide helper functions to be used   in @manageHook@. -* "XMonad.Hooks.ServerMode": example use of "XMonad.Hooks.EventHook".+* "XMonad.Hooks.Place":+    Automatic placement of floating windows. -* "XMonad.Hooks.SetWMName": set the WM name.  Useful when e.g. running-  Java GUI programs.+* "XMonad.Hooks.RestoreMinimized":+    Lets you restore minimized windows (see "XMonad.Layout.Minimize")+    by selecting them on a taskbar (listens for _NET_ACTIVE_WINDOW+    and WM_CHANGE_STATE). -* "XMonad.Hooks.UrgencyHook": configure an action to occur when a window-  sets the urgent flag.+* "XMonad.Hooks.Script":+    Provides a simple interface for running a ~\/.xmonad\/hooks script with the+    name of a hook. -* "XMonad.Hooks.XPropManage": match on XProperties in your-  'XMonad.Core.manageHook'.+* "XMonad.Hooks.ServerMode": Allows sending commands to a running xmonad process. +* "XMonad.Hooks.SetCursor":+    Set a default mouse cursor on startup.++* "XMonad.Hooks.SetWMName":+    Sets the WM name to a given string, so that it could be detected using+    _NET_SUPPORTING_WM_CHECK protocol.  May be useful for making Java GUI+    programs work.++* "XMonad.Hooks.UrgencyHook":+    UrgencyHook lets you configure an action to occur when a window demands+    your attention. (In traditional WMs, this takes the form of \"flashing\"+    on your \"taskbar.\" Blech.)++* "XMonad.Hooks.WorkspaceByPos":+    Useful in a dual-head setup: Looks at the requested geometry of+    new windows and moves them to the workspace of the non-focused+    screen if necessary.++* "XMonad.Hooks.XPropManage":+    A ManageHook matching on XProperties.+ -}  {- $layouts@@ -274,7 +426,8 @@ three columns, and so on.  You will also find modules which provide facilities for combining-different layouts, such as "XMonad.Layout.Combo", or+different layouts, such as "XMonad.Layout.Combo", "XMonad.Layout.ComboP",+"XMonad.Layout.LayoutBuilder", "XMonad.Layout.SubLayouts", or "XMonad.Layout.LayoutCombinators".  Layouts can be also modified with layout modifiers. A general@@ -284,109 +437,297 @@ For more information on using those modules for customizing your 'XMonad.Core.layoutHook' see "XMonad.Doc.Extending#Editing_the_layout_hook". -* "XMonad.Layout.Accordion": put non-focused windows in ribbons at the-  top and bottom of the screen.+* "XMonad.Layout.Accordion":+    LayoutClass that puts non-focused windows in ribbons at the top and bottom+    of the screen. -* "XMonad.Layout.Circle": an elliptical, overlapping layout.+* "XMonad.Layout.AutoMaster":+    Provides layout modifier AutoMaster. It separates screen in two parts -+    master and slave. Size of slave area automatically changes depending on+    number of slave windows. -* "XMonad.Layout.Combo": combine multiple layouts into one.+* "XMonad.Layout.BorderResize":+    This layout modifier will allow to resize windows by dragging their+    borders with the mouse. However, it only works in layouts or modified+    layouts that react to the SetGeometry message.+    "XMonad.Layout.WindowArranger" can be used to create such a setup.+    BorderResize is probably most useful in floating layouts. -* "XMonad.Layout.Decoration": decorated layouts.+* "XMonad.Layout.BoringWindows":+    BoringWindows is an extension to allow windows to be marked boring -* "XMonad.Layout.DecorationMadness": some examples of decorated layouts.+* "XMonad.Layout.CenteredMaster":+    Two layout modifiers. centerMaster places master window at center,+    on top of all other windows, which are managed by base layout.+    topRightMaster is similar, but places master window in top right corner+    instead of center. -* "XMonad.Layout.Dishes": stack extra windows underneath the master windows.+* "XMonad.Layout.Circle":+    Circle is an elliptical, overlapping layout. -* "XMonad.Layout.DragPane": split the screen into two windows with a-  draggable divider.+* "XMonad.Layout.Column":+    Provides Column layout that places all windows in one column. Windows+    heights are calculated from equation: H1/H2 = H2/H3 = ... = q, where q is+    given. With Shrink/Expand messages you can change the q value. -* "XMonad.Layout.DwmStyle": windows decorated in a dwm-like style.+* "XMonad.Layout.Combo":+    A layout that combines multiple layouts. -* "XMonad.Layout.Grid": put windows in a square grid.+* "XMonad.Layout.ComboP":+    A layout that combines multiple layouts and allows to specify where to put+    new windows. -* "XMonad.Layout.HintedTile": gapless tiled layout that attempts to-  obey window size hints.+* "XMonad.Layout.Cross":+    A Cross Layout with the main window in the center. -* "XMonad.Layout.IM": a layout for multi-window instant message clients.+* "XMonad.Layout.Decoration":+    A layout modifier and a class for easily creating decorated+    layouts. -* "XMonad.Layout.LayoutCombinators": general layout combining.+* "XMonad.Layout.DecorationMadness":+    A collection of decorated layouts: some of them may be nice, some+    usable, others just funny. -* "XMonad.Layout.LayoutHints": make layouts respect window size hints.+* "XMonad.Layout.Dishes":+    Dishes is a layout that stacks extra windows underneath the master+    windows. -* "XMonad.Layout.LayoutModifier": a general framework for creating-  layout \"modifiers\"; useful for creating new layout modules.+* "XMonad.Layout.DragPane":+    Layouts that splits the screen either horizontally or vertically and+    shows two windows.  The first window is always the master window, and+    the other is either the currently focused window or the second window in+    layout order. See also "XMonad.Layout.MouseResizableTall" -* "XMonad.Layout.LayoutScreens": divide the screen into multiple-  virtual \"screens\".+* "XMonad.Layout.DwmStyle":+    A layout modifier for decorating windows in a dwm like style. -* "XMonad.Layout.MagicFocus": automagically put the focused window in-  the master area.+* "XMonad.Layout.FixedColumn":+    A layout much like Tall, but using a multiple of a window's minimum+    resize amount instead of a percentage of screen to decide where to+    split. This is useful when you usually leave a text editor or+    terminal in the master pane and like it to be 80 columns wide. -* "XMonad.Layout.Magnifier": increase the size of the focused window+* "XMonad.Layout.Gaps":+    Create manually-sized gaps along edges of the screen which will not+    be used for tiling, along with support for toggling gaps on and+    off. You probably want "XMonad.Hooks.ManageDocks". -* "XMonad.Layout.Maximize": temporarily maximize the focused window.+* "XMonad.Layout.Grid":+    A simple layout that attempts to put all windows in a square grid. -* "XMonad.Layout.MosaicAlt": give each window a specified relative-  amount of screen space.+* "XMonad.Layout.GridVariants":+    Two layouts: one is a variant of the Grid layout that allows the+    desired aspect ratio of windows to be specified.  The other is like+    Tall but places a grid with fixed number of rows and columns in the+    master area and uses an aspect-ratio-specified layout for the+    slaves. -* "XMonad.Layout.MultiToggle": dynamically apply and unapply layout-  transformers.+* "XMonad.Layout.HintedGrid":+    A not so simple layout that attempts to put all windows in a square grid+    while obeying their size hints. -* "XMonad.Layout.Named": change the names of layouts (as reported by-  e.g. "XMonad.Hooks.DynamicLog").+* "XMonad.Layout.HintedTile":+    A gapless tiled layout that attempts to obey window size hints,+    rather than simply ignoring them. -* "XMonad.Layout.NoBorders": display windows without borders.+* "XMonad.Layout.IM":+    Layout modfier suitable for workspace with multi-windowed instant messenger+    (like Psi or Tkabber). -* "XMonad.Layout.PerWorkspace": configure layouts on a per-workspace basis.+* "XMonad.Layout.IndependentScreens":+    Utility functions for simulating independent sets of workspaces on+    each screen (like dwm's workspace model), using internal tags to+    distinguish workspaces associated with each screen. -* "XMonad.Layout.Reflect": reflect any layout vertically or horizontally.+* "XMonad.Layout.LayoutBuilder":+    A layout combinator that sends a specified number of windows to one rectangle+    and the rest to another. -* "XMonad.Layout.ResizableTile": tiled layout allowing you to change-  width and height of windows.+* "XMonad.Layout.LayoutCombinators":+    The "XMonad.Layout.LayoutCombinators" module provides combinators+    for easily combining multiple layouts into one composite layout, as+    well as a way to jump directly to any particular layout (say, with+    a keybinding) without having to cycle through other layouts to get+    to it. -* "XMonad.Layout.ResizeScreen": a layout modifier to change the screen-  geometry on one side.+* "XMonad.Layout.LayoutHints":+    Make layouts respect size hints. -* "XMonad.Layout.Roledex": a \"completely pointless layout which acts-  like Microsoft's Flip 3D\".+* "XMonad.Layout.LayoutModifier":+    A module for writing easy layout modifiers, which do not define a+    layout in and of themselves, but modify the behavior of or add new+    functionality to other layouts.  If you ever find yourself writing+    a layout which takes another layout as a parameter, chances are you+    should be writing a LayoutModifier instead! -* "XMonad.Layout.ScratchWorkspace": implements a scratch workspace-  which can be shown and hidden with keybindings.+    In case it is not clear, this module is not intended to help you+    configure xmonad, it is to help you write other extension modules.+    So get hacking! -* "XMonad.Layout.ShowWName": Show the name of the current workspace when switching.+* "XMonad.Layout.LayoutScreens":+    Divide a single screen into multiple screens. -* "XMonad.Layout.SimpleDecoration": add simple decorations to windows.+* "XMonad.Layout.LimitWindows":+    A layout modifier that limits the number of windows that can be shown. -* "XMonad.Layout.SimpleFloat": a basic floating layout.+* "XMonad.Layout.MagicFocus":+    Automagically put the focused window in the master area. -* "XMonad.Layout.Simplest": a basic, simple layout that just lays out-  all windows with a fullscreen geometry.  Used by-  "XMonad.Layout.Tabbed".+* "XMonad.Layout.Magnifier":+    Screenshot  :  <http://caladan.rave.org/magnifier.png>+    This is a layout modifier that will make a layout increase the size+    of the window that has focus. -* "XMonad.Layout.Spiral": Fibonacci spiral layout.+* "XMonad.Layout.Master":+    Layout modfier that adds a master window to another layout. -* "XMonad.Layout.Square": split the screen into a square area plus the rest.+* "XMonad.Layout.Maximize":+    Temporarily yanks the focused window out of the layout to mostly fill+    the screen. -* "XMonad.Layout.TabBarDecoration": add a bar of tabs to any layout.+* "XMonad.Layout.MessageControl":+    Provides message escaping and filtering facilities which+    help control complex nested layouts. -* "XMonad.Layout.Tabbed": a tabbed layout.+* "XMonad.Layout.Minimize":+    Makes it possible to minimize windows, temporarily removing them+    from the layout until they are restored. -* "XMonad.Layout.ThreeColumns": a layout with three columns instead of two.+* "XMonad.Layout.Monitor":+    Layout modfier for displaying some window (monitor) above other windows -* "XMonad.Layout.ToggleLayouts": toggle between two layouts.+* "XMonad.Layout.Mosaic":+    Based on MosaicAlt, but aspect ratio messages always change the aspect+    ratios, and rearranging the window stack changes the window sizes. -* "XMonad.Layout.TwoPane": split the screen horizontally and show two-  windows.+* "XMonad.Layout.MosaicAlt":+    A layout which gives each window a specified amount of screen space+    relative to the others. Compared to the 'Mosaic' layout, this one+    divides the space in a more balanced way. -* "XMonad.Layout.WindowArranger": make any layout into a-  pseudo-floating layout by allowing you to move and resize windows.+* "XMonad.Layout.MouseResizableTile":+    A layout in the spirit of "XMonad.Layout.ResizableTile", but with the option+    to use the mouse to adjust the layout. -* "XMonad.Layout.WindowNavigation": navigate around a workspace-  directionally instead of using mod-j\/k.+* "XMonad.Layout.MultiToggle":+    Dynamically apply and unapply transformers to your window layout. This can+    be used to rotate your window layout by 90 degrees, or to make the+    currently focused window occupy the whole screen (\"zoom in\") then undo+    the transformation (\"zoom out\"). -* "XMonad.Layout.WorkspaceDir": set the current working directory in a-  workspace.+* "XMonad.Layout.Named":+    A module for assigning a name to a given layout. +* "XMonad.Layout.NoBorders":+    Make a given layout display without borders.  This is useful for+    full-screen or tabbed layouts, where you don't really want to waste a+    couple of pixels of real estate just to inform yourself that the visible+    window has focus.++* "XMonad.Layout.NoFrillsDecoration":+    Most basic version of decoration for windows without any additional+    modifications. In contrast to "XMonad.Layout.SimpleDecoration" this will+    result in title bars that span the entire window instead of being only the+    length of the window title.++* "XMonad.Layout.OneBig":+    Places one (master) window at top left corner of screen, and other (slave)+    windows at the top.++* "XMonad.Layout.PerWorkspace":+    Configure layouts on a per-workspace basis: use layouts and apply+    layout modifiers selectively, depending on the workspace.++* "XMonad.Layout.Reflect":+    Reflect a layout horizontally or vertically.++* "XMonad.Layout.ResizableTile":+    More useful tiled layout that allows you to change a width\/height of window.+    See also "XMonad.Layout.MouseResizableTile".++* "XMonad.Layout.ResizeScreen":+    A layout transformer to have a layout respect a given screen+    geometry. Mostly used with "Decoration" (the Horizontal and the+    Vertical version will react to SetTheme and change their dimension+    accordingly.++* "XMonad.Layout.Roledex":+    This is a completely pointless layout which acts like Microsoft's Flip 3D++* "XMonad.Layout.ShowWName":+    This is a layout modifier that will show the workspace name++* "XMonad.Layout.SimpleDecoration":+    A layout modifier for adding simple decorations to the windows of a+    given layout. The decorations are in the form of ion-like tabs+    for window titles.++* "XMonad.Layout.SimpleFloat":+    A basic floating layout.++* "XMonad.Layout.Simplest":+    A very simple layout. The simplest, afaik. Used as a base for+    decorated layouts.++* "XMonad.Layout.SimplestFloat":+    A basic floating layout like SimpleFloat but without the decoration.++* "XMonad.Layout.Spacing":+    Add a configurable amount of space around windows.++* "XMonad.Layout.Spiral":+    A spiral tiling layout.++* "XMonad.Layout.Square":+    A layout that splits the screen into a square area and the rest of the+    screen.+    This is probably only ever useful in combination with+    "XMonad.Layout.Combo".+    It sticks one window in a square region, and makes the rest+    of the windows live with what's left (in a full-screen sense).++* "XMonad.Layout.StackTile":+    A stacking layout, like dishes but with the ability to resize master pane.+    Mostly useful on small screens.++* "XMonad.Layout.SubLayouts":+    A layout combinator that allows layouts to be nested.++* "XMonad.Layout.TabBarDecoration":+    A layout modifier to add a bar of tabs to your layouts.++* "XMonad.Layout.Tabbed":+    A tabbed layout for the Xmonad Window Manager++* "XMonad.Layout.ThreeColumns":+    A layout similar to tall but with three columns. With 2560x1600 pixels this+    layout can be used for a huge main window and up to six reasonable sized+    slave windows.++* "XMonad.Layout.ToggleLayouts":+    A module to toggle between two layouts.++* "XMonad.Layout.TwoPane":+    A layout that splits the screen horizontally and shows two windows.  The+    left window is always the master window, and the right is either the+    currently focused window or the second window in layout order.++* "XMonad.Layout.WindowArranger":+    This is a pure layout modifier that will let you move and resize+    windows with the keyboard in any layout.++* "XMonad.Layout.WindowNavigation":+    WindowNavigation is an extension to allow easy navigation of a workspace.+    See also "XMonad.Actions.WindowNavigation".++* "XMonad.Layout.WorkspaceDir":+    WorkspaceDir is an extension to set the current directory in a workspace.+    Actually, it sets the current directory in a layout, since there's no way I+    know of to attach a behavior to a workspace.  This means that any terminals+    (or other programs) pulled up in that workspace (with that layout) will+    execute in that working directory.  Sort of handy, I think.+    Note this extension requires the 'directory' package to be installed.+ -}  {- $prompts@@ -400,39 +741,69 @@  These are the available prompts: -* "XMonad.Prompt.AppendFile": append lines of text to a file.+* "XMonad.Prompt.AppLauncher":+    A module for launch applicationes that receive parameters in the command+    line. The launcher call a prompt to get the parameters. -* "XMonad.Prompt.Directory": prompt for a directory.+* "XMonad.Prompt.AppendFile":+    A prompt for appending a single line of text to a file.  Useful for+    keeping a file of notes, things to remember for later, and so on---+    using a keybinding, you can write things down just about as quickly+    as you think of them, so it doesn't have to interrupt whatever else+    you're doing.+    Who knows, it might be useful for other purposes as well! -* "XMonad.Prompt.DirExec": put a bunch of scripts you want in a-  directory, then choose from among them with this prompt.+* "XMonad.Prompt.DirExec":+    A directory file executables prompt for XMonad. This might be useful if you+    don't want to have scripts in your PATH environment variable (same+    executable names, different behavior) - otherwise you might want to use+    "XMonad.Prompt.Shell" instead - but you want to have easy access to these+    executables through the xmonad's prompt. -* "XMonad.Prompt.Email": an example of "XMonad.Prompt.Input", send-  simple short e-mails from a prompt.+* "XMonad.Prompt.Directory":+    A directory prompt for XMonad -* "XMonad.Prompt.Input": useful for building general actions requiring-  input from a prompt.+* "XMonad.Prompt.Email":+    A prompt for sending quick, one-line emails, via the standard GNU+    \'mail\' utility (which must be in your $PATH).  This module is+    intended mostly as an example of using "XMonad.Prompt.Input" to+    build an action requiring user input. -* "XMonad.Prompt.Layout": choose a layout from a prompt.+* "XMonad.Prompt.Input":+    A generic framework for prompting the user for input and passing it+    along to some other action. -* "XMonad.Prompt.Man": open man pages.+* "XMonad.Prompt.Layout":+    A layout-selection prompt for XMonad -* "XMonad.Prompt.RunOrRaise": choose a program, and run it if not-  already running, or raise its window if it is.+* "XMonad.Prompt.Man":+    A manual page prompt for XMonad window manager.+    TODO+    * narrow completions by section number, if the one is specified+    (like @\/etc\/bash_completion@ does) -* "XMonad.Prompt.Shell": run a shell command.+* "XMonad.Prompt.RunOrRaise":+    A prompt for XMonad which will run a program, open a file,+    or raise an already running program, depending on context. -* "XMonad.Prompt.Ssh": open an ssh connection.+* "XMonad.Prompt.Shell":+    A shell prompt for XMonad -* "XMonad.Prompt.Theme": choose a decoration theme.+* "XMonad.Prompt.Ssh":+    A ssh prompt for XMonad -* "XMonad.Prompt.Window": choose an open window.+* "XMonad.Prompt.Theme":+    A prompt for changing the theme of the current workspace -* "XMonad.Prompt.Workspace": choose a workspace.+* "XMonad.Prompt.Window":+    xprompt operations to bring windows to you, and bring you to windows. -* "XMonad.Prompt.XMonad": perform various xmonad actions by choosing-  one from a prompt.+* "XMonad.Prompt.Workspace":+    A workspace prompt for XMonad +* "XMonad.Prompt.XMonad":+    A prompt for running XMonad commands+ Usually a prompt is called by some key binding. See "XMonad.Doc.Extending#Editing_key_bindings", which includes examples of adding some prompts.@@ -450,13 +821,17 @@  A non complete list with a brief description: +* "XMonad.Util.Cursor": configure the default cursor/pointer glyph.+ * "XMonad.Util.CustomKeys": configure key bindings (see   "XMonad.Doc.Extending#Editing_key_bindings"). -* "XMonad.Util.Dmenu": a dmenu binding.+* "XMonad.Util.Dmenu":+    A convenient binding to dmenu.+    Requires the process-1.0 package -* "XMonad.Util.Dzen" "XMonad.Util.Dmenu" provide useful functions for-  running dzen as a xmonad status bar and dmenu as a program launcher;+* "XMonad.Util.Dzen":+    Handy wrapper for dzen. Requires dzen >= 0.2.4.  * "XMonad.Util.EZConfig": configure key bindings easily, including a   parser for writing key bindings in "M-C-x" style.@@ -464,41 +839,68 @@ * "XMonad.Util.Font": A module for abstracting a font facility over   Core fonts and Xft -* "XMonad.Util.Invisible": a wrapper data type to store layout state-  which should not be persisted across restarts.+* "XMonad.Util.Invisible":+    A data type to store the layout state -* "XMonad.Util.Loggers": a collection of loggers that can be used in-  conjunction with "XMonad.Hooks.DynamicLog".+* "XMonad.Util.Loggers":+    A collection of simple logger functions and formatting utilities+    which can be used in the 'XMonad.Hooks.DynamicLog.ppExtras' field of+    a pretty-printing status logger format. See "XMonad.Hooks.DynamicLog"+    for more information. -* "XMonad.Util.NamedWindows": associate windows with their X titles.-  Used by, e.g. "XMonad.Layout.Tabbed".+* "XMonad.Util.NamedActions":+    A wrapper for keybinding configuration that can list the available+    keybindings. -* "XMonad.Util.Run": a collection of functions for running external-  processes.+* "XMonad.Util.NamedScratchpad":+    Like "XMonad.Util.Scratchpad" toggle windows to and from the current+    workspace. Supports several arbitrary applications at the same time. -* "XMonad.Util.Scratchpad": hotkey-launched floating terminal window.+* "XMonad.Util.NamedWindows":+    This module allows you to associate the X titles of windows with+    them. -* "XMonad.Util.Themes": a collection of themes to be used with-  floating layouts.+* "XMonad.Util.Paste":+    A module for sending key presses to windows. This modules provides generalized+    and specialized functions for this task. -* "XMonad.Util.Timer": set up a timer to handle deferred events.+* "XMonad.Util.Replace":+    Implements a @--replace@ flag outside of core. -* "XMonad.Util.WindowProperties": an EDSL for specifying and matching-  on window properties.+* "XMonad.Util.Run":+    This modules provides several commands to run an external process.+    It is composed of functions formerly defined in "XMonad.Util.Dmenu" (by+    Spencer Janssen), "XMonad.Util.Dzen" (by glasser\@mit.edu) and+    XMonad.Util.RunInXTerm (by Andrea Rossato). -* "XMonad.Util.WorkspaceCompare": general combinators for sorting-  workspaces in various ways, used by several other modules which need-  to sort workspaces (e.g. "XMonad.Hooks.DynamicLog").+* "XMonad.Util.Scratchpad":+    Very handy hotkey-launched toggleable floating terminal window. -* "XMonad.Util.Paste" provides utilities for pasting or sending keys and-  strings to windows;+* "XMonad.Util.StringProp":+    Internal utility functions for storing Strings with the root window.+    Used for global state like IORefs with string keys, but more latency,+    persistent between xmonad restarts. -* "XMonad.Util.XSelection" provide utilities for using the mouse-  selection;+* "XMonad.Util.Themes":+    A (hopefully) growing collection of themes for decorated layouts. -* "XMonad.Util.XUtils" and "XMonad.Util.Font" are libraries for-  accessing Xlib and XFT function in a convenient way.+* "XMonad.Util.Timer":+    A module for setting up timers +* "XMonad.Util.Types":+    Miscellaneous commonly used types.++* "XMonad.Util.WindowProperties":+    EDSL for specifying window properties; various utilities related to window+    properties.++* "XMonad.Util.XSelection":+    A module for accessing and manipulating X Window's mouse selection (the buffer used in copy and pasting).+    'getSelection' and 'putSelection' are adaptations of Hxsel.hs and Hxput.hs from the XMonad-utils++* "XMonad.Util.XUtils":+    A module for painting on the screen+ -}  --------------------------------------------------------------------------------@@ -530,9 +932,9 @@  and provide an appropriate definition of @myKeys@, such as: ->    myKeys x =->             [ ((modMask x, xK_F12), xmonadPrompt defaultXPConfig)->             , ((modMask x, xK_F3 ), shellPrompt  defaultXPConfig)+> myKeys conf@(XConfig {XMonad.modMask = modm}) =+>             [ ((modm, xK_F12), xmonadPrompt defaultXPConfig)+>             , ((modm, xK_F3 ), shellPrompt  defaultXPConfig) >             ]  This particular definition also requires importing "XMonad.Prompt",@@ -543,7 +945,7 @@  For a list of the names of particular keys (such as xK_F12, and so on), see-<http://hackage.haskell.org/packages/archive/X11/1.4.1/doc/html/Graphics-X11-Types.html>.+<http://hackage.haskell.org/packages/archive/X11/latest/doc/html/Graphics-X11-Types.html>  Usually, rather than completely redefining the key bindings, as we did above, we want to simply add some new bindings and\/or remove existing@@ -554,8 +956,9 @@ {- $keyAdding #Adding_key_bindings# -Adding key bindings can be done in different ways. The type signature-of 'XMonad.Core.XConfig.keys' is:+Adding key bindings can be done in different ways. See the end of this+section for the easiest ways. The type signature of+'XMonad.Core.XConfig.keys' is:  >    keys :: XConfig Layout -> M.Map (ButtonMask,KeySym) (X ()) @@ -574,21 +977,27 @@ For instance, if you have defined some additional key bindings like these: ->    myKeys x =->             [ ((modMask x, xK_F12), xmonadPrompt defaultXPConfig)->             , ((modMask x, xK_F3 ), shellPrompt  defaultXPConfig)+>    myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList+>             [ ((modm, xK_F12), xmonadPrompt defaultXPConfig)+>             , ((modm, xK_F3 ), shellPrompt  defaultXPConfig) >             ]  then you can create a new key bindings map by joining the default one with yours: ->    newKeys x  = M.union (keys defaultConfig x) (M.fromList (myKeys x))+>    newKeys x  = myKeys x `M.union` keys defaultConfig x  Finally, you can use @newKeys@ in the 'XMonad.Core.XConfig.keys' field of the configuration:  >    main = xmonad $ defaultConfig { keys = newKeys } +Alternatively, the '<+>' operator can be used which in this usage does exactly+the same as the explicit usage of 'M.union' and propagation of the config+argument, thanks to appropriate instances in "Data.Monoid".++>    main = xmonad $ defaultConfig { keys = myKeys <+> keys defaultConfig }+ All together, your @~\/.xmonad\/xmonad.hs@ would now look like this:  @@ -603,13 +1012,11 @@ >    import XMonad.Prompt.XMonad > >    main :: IO ()->    main = xmonad $ defaultConfig { keys = newKeys }->->    newKeys x = M.union (keys defaultConfig x) (M.fromList (myKeys x))+>    main = xmonad $ defaultConfig { keys = myKeys <+> keys defaultConfig } >->    myKeys x =->             [ ((modMask x, xK_F12), xmonadPrompt defaultXPConfig)->             , ((modMask x, xK_F3 ), shellPrompt  defaultXPConfig)+>    myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList+>             [ ((modm, xK_F12), xmonadPrompt defaultXPConfig)+>             , ((modm, xK_F3 ), shellPrompt  defaultXPConfig) >             ]  There are much simpler ways to accomplish this, however, if you are@@ -631,12 +1038,12 @@ to define @newKeys@ as a 'Data.Map.difference' between the default map and the map of the key bindings you want to remove.  Like so: ->    newKeys x = M.difference (keys defaultConfig x) (M.fromList $ keysToRemove x)+>    newKeys x = keys defaultConfig x `M.difference` keysToRemove x >->    keysToRemove :: XConfig Layout ->    [((KeyMask, KeySym),X ())]->    keysToRemove x =->             [ ((modMask x              , xK_q ), return ())->             , ((modMask x .|. shiftMask, xK_q ), return ())+>    keysToRemove :: XConfig Layout ->    M.Map (KeyMask, KeySym) (X ())+>    keysToRemove x = M.fromList+>             [ ((modm              , xK_q ), return ())+>             , ((modm .|. shiftMask, xK_q ), return ()) >             ]  As you can see, it doesn't matter what actions we associate with the@@ -651,8 +1058,8 @@ > >    keysToRemove :: XConfig Layout -> [(KeyMask, KeySym)] >    keysToRemove x =->             [ (modMask x              , xK_q )->             , (modMask x .|. shiftMask, xK_q )+>             [ (modm              , xK_q )+>             , (modm .|. shiftMask, xK_q ) >             ]  Another even simpler possibility is the use of some of the utilities@@ -672,23 +1079,23 @@ >    delKeys x  = foldr M.delete           (defKeys x) (toRemove x) >    newKeys x  = foldr (uncurry M.insert) (delKeys x) (toAdd    x) >    -- remove some of the default key bindings->    toRemove x =->        [ (modMask x              , xK_j     )->        , (modMask x              , xK_k     )->        , (modMask x              , xK_p     )->        , (modMask x .|. shiftMask, xK_p     )->        , (modMask x .|. shiftMask, xK_q     )->        , (modMask x              , xK_q     )+>    toRemove XConfig{modMask = modm} =+>        [ (modm              , xK_j     )+>        , (modm              , xK_k     )+>        , (modm              , xK_p     )+>        , (modm .|. shiftMask, xK_p     )+>        , (modm .|. shiftMask, xK_q     )+>        , (modm              , xK_q     ) >        ] ++->        -- I want modMask .|. shiftMask 1-9 to be free!->        [(shiftMask .|. modMask x, k) | k <- [xK_1 .. xK_9]]+>        -- I want modm .|. shiftMask 1-9 to be free!+>        [(shiftMask .|. modm, k) | k <- [xK_1 .. xK_9]] >    -- These are my personal key bindings->    toAdd x   =->        [ ((modMask x              , xK_F12   ), xmonadPrompt defaultXPConfig )->        , ((modMask x              , xK_F3    ), shellPrompt  defaultXPConfig )+>    toAdd XConfig{modMask = modm} =+>        [ ((modm              , xK_F12   ), xmonadPrompt defaultXPConfig )+>        , ((modm              , xK_F3    ), shellPrompt  defaultXPConfig ) >        ] ++->        -- Use modMask .|. shiftMask .|. controlMask 1-9 instead->        [( (m .|. modMask x, k), windows $ f i)+>        -- Use modm .|. shiftMask .|. controlMask 1-9 instead+>        [( (m .|. modm, k), windows $ f i) >         | (i, k) <- zip (workspaces x) [xK_1 .. xK_9] >        ,  (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask .|. controlMask)] >        ]@@ -697,6 +1104,8 @@ module; take a look at the 'XMonad.Util.CustomKeys.customKeys' function in particular. +NOTE: modm is defined as the modMask you defined (or left as the default) in+your config. -}  {- $mouse
− XMonad/Hooks/BluetileDock.hs
@@ -1,43 +0,0 @@-------------------------------------------------------------------------------- |--- Module      :  XMonad.Hooks.BluetileDock--- Copyright   :  (c) Jan Vornberger 2009--- License     :  BSD3-style (see LICENSE)------ Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de--- Stability   :  unstable--- Portability :  not portable-----------------------------------------------------------------------------------module XMonad.Hooks.BluetileDock (-    bluetileDock-  ) where--import XMonad-import qualified XMonad.StackSet as S-import System.IO-import Control.Monad(forM_)--data DockOutput = DO Int String String deriving (Show, Read)--bluetileDock :: Handle -> X ()-bluetileDock outputHandle = do-    ws <- gets windowset-    let allscreens = S.screens ws-    let outputs = for allscreens $ \s -> DO (getScreenId (S.screen s))-                                            (getLayoutDesc s)-                                            (getCurrentWorkspace s)-    forM_ outputs $ \o -> io $ hPutStrLn outputHandle $ show o--getScreenId :: ScreenId -> Int-getScreenId (S sid) = sid--getLayoutDesc :: S.Screen i (Layout Window) a sid sd -> String-getLayoutDesc = description . S.layout . S.workspace--getCurrentWorkspace :: S.Screen i l a sid sd -> i-getCurrentWorkspace = S.tag . S.workspace--for :: [a] -> (a -> b) -> [b]-for = flip map
+ XMonad/Hooks/CurrentWorkspaceOnTop.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE DeriveDataTypeable #-}+----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Hooks.CurrentWorkspaceOnTop+-- Copyright   :  (c) Jan Vornberger 2009+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de+-- Stability   :  unstable+-- Portability :  not portable+--+-- Ensures that the windows of the current workspace are always in front+-- of windows that are located on other visible screens. This becomes important+-- if you use decoration and drag windows from one screen to another. Using this+-- module, the dragged window will always be in front of other windows.+--+-----------------------------------------------------------------------------++module XMonad.Hooks.CurrentWorkspaceOnTop (+    -- * Usage+    -- $usage+    currentWorkspaceOnTop+    ) where++import XMonad+import qualified XMonad.StackSet as S+import qualified XMonad.Util.ExtensibleState as XS+import Control.Monad(when)++-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Hooks.CurrentWorkspaceOnTop+-- >+-- > main = xmonad $ defaultConfig {+-- >    ...+-- >    logHook = currentWorkspaceOnTop+-- >    ...+-- >  }+--++data CWOTState = CWOTS String deriving Typeable++instance ExtensionClass CWOTState where+  initialValue = CWOTS ""++currentWorkspaceOnTop :: X ()+currentWorkspaceOnTop = withDisplay $ \d -> do+    ws <- gets windowset+    (CWOTS lastTag) <- XS.get+    let curTag = S.tag . S.workspace . S.current $ ws+    when (curTag /= lastTag) $ do+        let s = S.current ws+            wsp = S.workspace s+            viewrect = screenRect $ S.screenDetail s+            tmpStack = S.stack . S.workspace $ s+        (rs, _) <- runLayout wsp { S.stack = tmpStack } viewrect+        let wins = map fst rs+        when (not . null $ wins) $ do+            io $ raiseWindow d (head wins)  -- raise first window of current workspace to the very top,+            io $ restackWindows d wins      -- then use restackWindows to let all other windows from the workspace follow+        XS.put(CWOTS curTag)
− XMonad/Hooks/CustomRestart.hs
@@ -1,32 +0,0 @@-------------------------------------------------------------------------------- |--- Module      :  XMonad.Hooks.CustomRestart--- Copyright   :  (c) Jan Vornberger 2009--- License     :  BSD3-style (see LICENSE)------ Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de--- Stability   :  unstable--- Portability :  not portable-----------------------------------------------------------------------------------module XMonad.Hooks.CustomRestart-    ( CustomRestart (..)-    , customRestartEventHook-    ) where--import Control.Monad (when)-import Data.Monoid--import XMonad--data CustomRestart = CustomRestart deriving ( Show, Read )--customRestartEventHook :: String -> Event -> X All-customRestartEventHook prog (ClientMessageEvent {ev_message_type = mt}) = do-        d <- asks display-        a <- io $ internAtom d "XMONAD_CUSTOM_RESTART" False-        when (mt == a) $ do-            restart prog True-        return (All True)-customRestartEventHook _ _ = return (All True)
XMonad/Hooks/DynamicHooks.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveDataTypeable #-} ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Hooks.DynamicHooks@@ -15,20 +16,18 @@ module XMonad.Hooks.DynamicHooks (   -- * Usage   -- $usage-  initDynamicHooks-  ,dynamicMasterHook+  dynamicMasterHook   ,addDynamicHook   ,updateDynamicHook   ,oneShotHook   ) where  import XMonad-import System.IO+import qualified XMonad.Util.ExtensibleState as XS  import Data.List import Data.Maybe (listToMaybe) import Data.Monoid-import Data.IORef  -- $usage -- Provides two new kinds of 'ManageHooks' that can be defined at runtime.@@ -40,83 +39,55 @@ -- Note that you will lose all dynamically defined 'ManageHook's when you @mod+q@! -- If you want them to last, you should create them as normal in your @xmonad.hs@. ----- First, you must execute 'initDynamicHooks' from 'main' in your @xmonad.hs@:------ > dynHooksRef <- initDynamicHooks------ and then pass this value to the other functions in this module.------ You also need to add the base 'ManageHook':+-- To use this module, add 'dynamicMasterHook' to your 'manageHook': ----- > xmonad { manageHook = myManageHook <+> dynamicMasterHook dynHooksRef }+-- > xmonad { manageHook = myManageHook <+> dynamicMasterHook } ----- You must include this @dynHooksRef@ value when using the functions in this--- module:+-- You can then use the supplied functions in your keybindings: ----- > xmonad { keys = myKeys `Data.Map.union` Data.Map.fromList --- >                   [((modMask conf, xK_i), oneShotHook dynHooksRef --- >                    "FFlaunchHook" (className =? "firefox") (doShift "3") --- >                    >> spawn "firefox")--- >                   ,((modMask conf, xK_u), addDynamicHook dynHooksRef --- >                     (className =? "example" --> doFloat))--- >                   ,((modMask conf, xK_y), updatePermanentHook dynHooksRef--- >                     (const idHook))) ]  -- resets the permanent hook.+-- > ((modMask,xK_a), oneShotHook (className =? "example") doFloat) --  data DynamicHooks = DynamicHooks     { transients :: [(Query Bool, ManageHook)]     , permanent  :: ManageHook }-      ---- | Creates the 'IORef' that stores the dynamically created 'ManageHook's.-initDynamicHooks :: IO (IORef DynamicHooks)-initDynamicHooks = newIORef (DynamicHooks { transients = [],-                                            permanent = idHook })+                    deriving Typeable +instance ExtensionClass DynamicHooks where+    initialValue = DynamicHooks [] idHook --- this hook is always executed, and the IORef's contents checked.+-- this hook is always executed, and the contents of the stored hooks checked. -- note that transient hooks are run second, therefore taking precedence -- over permanent ones on matters such as which workspace to shift to. -- doFloat and doIgnore are idempotent. -- | Master 'ManageHook' that must be in your @xmonad.hs@ 'ManageHook'.-dynamicMasterHook :: IORef DynamicHooks -> ManageHook-dynamicMasterHook ref = return True --> -                  (ask >>= \w -> liftX (do-  dh <- io $ readIORef ref+dynamicMasterHook :: ManageHook+dynamicMasterHook = (ask >>= \w -> liftX (do+  dh <- XS.get   (Endo f)  <- runQuery (permanent dh) w   ts <- mapM (\(q,a) -> runQuery q w >>= \x -> return (x,(q, a))) (transients dh)   let (ts',nts) = partition fst ts   gs <- mapM (flip runQuery w . snd . snd) ts'   let (Endo g) = maybe (Endo id) id $ listToMaybe gs-  io $ writeIORef ref $ dh { transients = map snd nts }+  XS.put $ dh { transients = map snd nts }   return $ Endo $ f . g                                        ))- -- | Appends the given 'ManageHook' to the permanent dynamic 'ManageHook'.-addDynamicHook :: IORef DynamicHooks -> ManageHook -> X ()-addDynamicHook ref m = updateDynamicHook ref (<+> m)-+addDynamicHook :: ManageHook -> X ()+addDynamicHook m = updateDynamicHook (<+> m)  -- | Modifies the permanent 'ManageHook' with an arbitrary function.-updateDynamicHook :: IORef DynamicHooks -> (ManageHook -> ManageHook) -> X ()-updateDynamicHook ref f = -    io $ modifyIORef ref $ \dh -> dh { permanent = f (permanent dh) }-+updateDynamicHook :: (ManageHook -> ManageHook) -> X ()+updateDynamicHook f = XS.modify $ \dh -> dh { permanent = f (permanent dh) }  -- | Creates a one-shot 'ManageHook'. Note that you have to specify the two -- parts of the 'ManageHook' separately. Where you would usually write: -- -- > className =? "example" --> doFloat ----- you must call 'oneShotHook' as +-- you must call 'oneShotHook' as -- -- > oneShotHook dynHooksRef (className =? "example) doFloat--- -oneShotHook :: IORef DynamicHooks -> Query Bool -> ManageHook -> X ()-oneShotHook ref q a =-  io $ modifyIORef ref-         $ \dh -> dh { transients = (q,a):(transients dh) }----+--+oneShotHook :: Query Bool -> ManageHook -> X ()+oneShotHook q a = XS.modify $ \dh -> dh { transients = (q,a):(transients dh) }
XMonad/Hooks/DynamicLog.hs view
@@ -29,6 +29,8 @@     dynamicLog,     dynamicLogXinerama, +    xmonadPropLog,+     -- * Build your own formatter     dynamicLogWithPP,     dynamicLogString,@@ -56,13 +58,16 @@ -- import XMonad import Control.Monad-import Data.Char ( isSpace )+import Data.Char ( isSpace, ord ) import Data.Maybe ( isJust, catMaybes ) import Data.List import qualified Data.Map as M import Data.Ord ( comparing ) import qualified XMonad.StackSet as S import System.IO++import Foreign.C (CChar)+ import XMonad.Util.WorkspaceCompare import XMonad.Util.NamedWindows import XMonad.Util.Run@@ -81,7 +86,9 @@ -- If you just want a quick-and-dirty status bar with zero effort, try -- the 'xmobar' or 'dzen' functions: ----- > main = xmonad =<< xmobar conf+-- > main = xmonad =<< xmobar myConfig+-- >+-- > myConfig = defaultConfig { ... } -- -- There is also 'statusBar' if you'd like to use another status bar, or would -- like to use different formatting options.  The 'xmobar', 'dzen', and@@ -144,7 +151,9 @@  -- | Run xmonad with a dzen status bar set to some nice defaults. ----- > main = xmonad =<< dzen conf+-- > main = xmonad =<< dzen myConfig+-- >+-- > myConfig = defaultConfig { ... } -- -- The intent is that the above config file should provide a nice -- status bar with minimal effort.@@ -167,7 +176,9 @@  -- | Run xmonad with a xmobar status bar set to some nice defaults. ----- > main = xmonad =<< xmobar conf+-- > main = xmonad =<< xmobar myConfig+-- >+-- > myConfig = defaultConfig { ... } -- -- This works pretty much the same as 'dzen' function above. --@@ -198,6 +209,20 @@  where     keys' = (`M.singleton` sendMessage ToggleStruts) . k +-- | Write a string to the property _XMONAD_LOG on the root window.  This+-- property is of type UTF8_STRING. The string must have been processed by+-- encodeString (dynamicLogString does this).+xmonadPropLog :: String -> X ()+xmonadPropLog msg = do+    d <- asks display+    r <- asks theRoot+    xlog <- getAtom "_XMONAD_LOG"+    ustring <- getAtom "UTF8_STRING"+    io $ changeProperty8 d r xlog ustring propModeReplace (encodeCChar msg)+ where+    encodeCChar :: String -> [CChar]+    encodeCChar = map (fromIntegral . ord)+ -- | -- Helper function which provides ToggleStruts keybinding --@@ -245,7 +270,7 @@     wt <- maybe (return "") (fmap show . getName) . S.peek $ winset      -- run extra loggers, ignoring any that generate errors.-    extras <- sequence $ map (flip catchX (return Nothing)) $ ppExtras pp+    extras <- mapM (flip catchX (return Nothing)) $ ppExtras pp      return $ encodeOutput . sepBy (ppSep pp) . ppOrder pp $                         [ ws@@ -264,9 +289,9 @@          visibles = map (S.tag . S.workspace) (S.visible s)           fmt w = printer pp (S.tag w)-          where printer | S.tag w == this                                               = ppCurrent+          where printer | any (\x -> maybe False (== S.tag w) (S.findTag x s)) urgents  = ppUrgent+                        | S.tag w == this                                               = ppCurrent                         | S.tag w `elem` visibles                                       = ppVisible-                        | any (\x -> maybe False (== S.tag w) (S.findTag x s)) urgents  = \ppC -> ppUrgent ppC . ppHidden ppC                         | isJust (S.stack w)                                            = ppHidden                         | otherwise                                                     = ppHiddenNoWindows @@ -312,7 +337,7 @@ -- | Limit a string to a certain length, adding "..." if truncated. shorten :: Int -> String -> String shorten n xs | length xs < n = xs-             | otherwise     = (take (n - length end) xs) ++ end+             | otherwise     = take (n - length end) xs ++ end  where     end = "..." @@ -339,11 +364,7 @@ dzenEscape :: String -> String dzenEscape = concatMap (\x -> if x == '^' then "^^" else [x]) --- | Strip dzen formatting or commands. Useful to remove ppHidden---   formatting in ppUrgent field. For example:------ >     , ppHidden          = dzenColor "gray20" "" . wrap "(" ")"--- >     , ppUrgent          = dzenColor "dark orange" "" .  dzenStrip+-- | Strip dzen formatting or commands. dzenStrip :: String -> String dzenStrip = strip [] where     strip keep x@@ -364,11 +385,7 @@  -- ??? add an xmobarEscape function? --- | Strip xmobar markup. Useful to remove ppHidden color from ppUrgent---   field. For example:------ >     , ppHidden          = xmobarColor "gray20" "" . wrap "<" ">"--- >     , ppUrgent          = xmobarColor "dark orange" "" .  xmobarStrip+-- | Strip xmobar markup. xmobarStrip :: String -> String xmobarStrip = strip [] where     strip keep x@@ -394,8 +411,6 @@                -- ^ how to print tags of empty hidden workspaces              , ppUrgent :: WorkspaceId -> String                -- ^ format to be applied to tags of urgent workspaces.-               -- NOTE that 'ppUrgent' is applied /in addition to/-               -- 'ppHidden'!              , ppSep :: String                -- ^ separator to use between different log sections                -- (window name, layout, workspaces)@@ -451,31 +466,31 @@                , ppExtras          = []                } --- | Settings to emulate dwm's statusbar, dzen only. Uses dzenStrip in--- ppUrgent.+-- | Settings to emulate dwm's statusbar, dzen only. dzenPP :: PP dzenPP = defaultPP { ppCurrent  = dzenColor "white" "#2b4f98" . pad-                     , ppVisible  = dzenColor "black" "#999999" . pad-                     , ppHidden   = dzenColor "black" "#cccccc" . pad-                     , ppHiddenNoWindows = const ""-                     , ppUrgent   = dzenColor "red" "yellow" . dzenStrip-                     , ppWsSep    = ""-                     , ppSep      = ""-                     , ppLayout   = dzenColor "black" "#cccccc" .-                                    (\ x -> case x of-                                              "TilePrime Horizontal" -> " TTT "-                                              "TilePrime Vertical"   -> " []= "-                                              "Hinted Full"          -> " [ ] "-                                              _                      -> pad x-                                    )-                     , ppTitle    = ("^bg(#324c80) " ++) . dzenEscape-                     }+                   , ppVisible  = dzenColor "black" "#999999" . pad+                   , ppHidden   = dzenColor "black" "#cccccc" . pad+                   , ppHiddenNoWindows = const ""+                   , ppUrgent   = dzenColor "red" "yellow" . pad+                   , ppWsSep    = ""+                   , ppSep      = ""+                   , ppLayout   = dzenColor "black" "#cccccc" .+                                  (\ x -> pad $ case x of+                                            "TilePrime Horizontal" -> "TTT"+                                            "TilePrime Vertical"   -> "[]="+                                            "Hinted Full"          -> "[ ]"+                                            _                      -> x+                                  )+                   , ppTitle    = ("^bg(#324c80) " ++) . dzenEscape+                   }  -- | Some nice xmobar defaults. xmobarPP :: PP xmobarPP = defaultPP { ppCurrent = xmobarColor "yellow" "" . wrap "[" "]"                      , ppTitle   = xmobarColor "green"  "" . shorten 40                      , ppVisible = wrap "(" ")"+                     , ppUrgent  = xmobarColor "red" "yellow"                      }  -- | The options that sjanssen likes to use with xmobar, as an@@ -491,7 +506,7 @@ byorgeyPP = defaultPP { ppHiddenNoWindows = showNamedWorkspaces                       , ppHidden  = dzenColor "black"  "#a8a3f7" . pad                       , ppCurrent = dzenColor "yellow" "#a8a3f7" . pad-                      , ppUrgent  = dzenColor "red"    "yellow"+                      , ppUrgent  = dzenColor "red"    "yellow"  . pad                       , ppSep     = " | "                       , ppWsSep   = ""                       , ppTitle   = shorten 70@@ -500,4 +515,3 @@   where showNamedWorkspaces wsId = if any (`elem` wsId) ['a'..'z']                                        then pad wsId                                        else ""-
− XMonad/Hooks/EventHook.hs
@@ -1,107 +0,0 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- for deriving Typeable-{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}---------------------------------------------------------------------------------- |--- Module      :  XMonad.Hooks.EventHook--- Copyright   :  (c) 2007 Andrea Rossato--- License     :  BSD-style (see xmonad/LICENSE)------ Maintainer  :  andrea.rossato@unibz.it--- Stability   :  unstable--- Portability :  unportable------ A layout modifier that implements an event hook at the layout level.------ Since it operates at the 'Workspace' level, it will install itself--- on the first current 'Workspace' and will broadcast a 'Message' to--- all other 'Workspace's not to handle events.--------------------------------------------------------------------------------module XMonad.Hooks.EventHook-    ( -- * Usage-      -- $usage--      -- * Writing a hook-      -- $hook-      EventHook (..)-    , eventHook-    , HandleEvent-    ) where--import Data.Maybe--import XMonad-import XMonad.StackSet (Workspace (..), currentTag)---- $usage--- You can use this module with the following in your--- @~\/.xmonad\/xmonad.hs@:------ > import XMonad.Hooks.EventHook------ Then edit your @layoutHook@ by adding the 'eventHook':------ > layoutHook = eventHook EventHookExample $ avoidStruts $ simpleTabbed ||| Full ||| etc..------ and then:------ > main = xmonad defaultConfig { layoutHook = myLayouts }------ For more detailed instructions on editing the layoutHook see:------ "XMonad.Doc.Extending#Editing_the_layout_hook"---- $hook--- Writing a hook is very simple.------ This is a basic example to log all events:------ > data EventHookExample = EventHookExample deriving ( Show, Read )--- > instance EventHook EventHookExample where--- >     handleEvent _ e = io $ hPutStrLn stderr . show $ e --return ()------ This is an 'EventHook' to log mouse button events:------ > data EventHookButton = EventHookButton deriving ( Show, Read )--- > instance EventHook EventHookButton where--- >    handleEvent _ (ButtonEvent {ev_window = w}) = do--- >         io $ hPutStrLn stderr $ "This is a button event on window " ++ (show w)--- >    handleEvent _ _ = return ()------ Obviously you can compose event hooks:------ > layoutHook = eventHook EventHookButton $ eventHook EventHookExample $ avoidStruts $ simpleTabbed ||| Full ||| etc..--eventHook :: EventHook eh => eh -> l a -> (HandleEvent eh l) a-eventHook = HandleEvent Nothing True--class (Read eh, Show eh) => EventHook eh where-    handleEvent :: eh -> Event -> X ()-    handleEvent _ _ = return ()--data HandleEvent eh l a = HandleEvent (Maybe WorkspaceId) Bool eh (l a) deriving ( Show, Read )--data EventHandleMsg = HandlerOff deriving ( Typeable )-instance Message EventHandleMsg--instance (EventHook eh, LayoutClass l a) => LayoutClass (HandleEvent eh l) a where-    runLayout (Workspace i (HandleEvent Nothing True eh l) ms) r = do-      broadcastMessage HandlerOff-      iws       <- gets (currentTag . windowset)-      (wrs, ml) <- runLayout (Workspace i l ms) r-      return (wrs, Just $ HandleEvent (Just iws) True eh (fromMaybe l ml))--    runLayout (Workspace i (HandleEvent mi b eh l) ms) r = do-      (wrs, ml) <- runLayout (Workspace i l ms) r-      return (wrs, Just $ HandleEvent mi b eh (fromMaybe l ml))--    handleMessage (HandleEvent i True eh l) m-        | Just HandlerOff <- fromMessage m = return . Just $ HandleEvent i False eh l-        | Just e          <- fromMessage m = handleMessage l (SomeMessage e) >>= \ml ->-                                             handleEvent eh e >>-                                             maybe (return Nothing) (\l' -> return . Just $ HandleEvent i True eh l') ml-    handleMessage (HandleEvent i b eh l) m = handleMessage l m >>=-                                             maybe (return Nothing) (\l' -> return . Just $ HandleEvent i b    eh l')--    description (HandleEvent _ _ _ l) = description l
XMonad/Hooks/EwmhDesktops.hs view
@@ -15,9 +15,12 @@ module XMonad.Hooks.EwmhDesktops (     -- * Usage     -- $usage+    ewmh,+    ewmhDesktopsStartup,     ewmhDesktopsLogHook,     ewmhDesktopsLogHookCustom,-    ewmhDesktopsEventHook+    ewmhDesktopsEventHook,+    fullscreenEventHook     ) where  import Codec.Binary.UTF8.String (encode)@@ -30,7 +33,9 @@ import qualified XMonad.StackSet as W  import XMonad.Hooks.SetWMName+import XMonad.Util.XUtils (fi) import XMonad.Util.WorkspaceCompare+import XMonad.Util.WindowProperties (getProp32)  -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:@@ -38,34 +43,29 @@ -- > import XMonad -- > import XMonad.Hooks.EwmhDesktops -- >--- > myLogHook :: X ()--- > myLogHook = ewmhDesktopsLogHook--- >--- > myHandleEventHook = ewmhDesktopsEventHook--- >--- > main = xmonad defaultConfig { handleEventHook = myHandleEventHook, logHook = myLogHook }------ 'avoidStruts' is used to automatically leave space for dock programs, and--- can be found in 'XMonad.Hooks.ManageDocks'.------ For more detailed instructions on editing the layoutHook see:------ "XMonad.Doc.Extending#The_log_hook_and_external_status_bars"------ For more detailed instructions on editing the layoutHook see:+-- > main = xmonad $ ewmh defaultConfig ----- "XMonad.Doc.Extending#Editing_the_layout_hook"+-- You may also be interested in 'avoidStruts' from XMonad.Hooks.ManageDocks.  +-- | Add EWMH functionality to the given config.  See above for an example.+ewmh :: XConfig a -> XConfig a+ewmh c = c { startupHook     = startupHook c +++ ewmhDesktopsStartup+           , handleEventHook = handleEventHook c +++ ewmhDesktopsEventHook+           , logHook         = logHook c +++ ewmhDesktopsLogHook }+ where x +++ y = mappend x y +-- |+-- Initializes EwmhDesktops and advertises EWMH support to the X+-- server+ewmhDesktopsStartup :: X ()+ewmhDesktopsStartup = setSupported  -- | -- Notifies pagers and window lists, such as those in the gnome-panel -- of the current state of workspaces and windows. ewmhDesktopsLogHook :: X () ewmhDesktopsLogHook = ewmhDesktopsLogHookCustom id-- -- | -- Generalized version of ewmhDesktopsLogHook that allows an arbitrary -- user-specified function to transform the workspace list (post-sorting)@@ -74,8 +74,6 @@     sort' <- getSortByIndex     let ws = f $ sort' $ W.workspaces s -    setSupported-     -- Number of Workspaces     setNumberOfDesktops (length ws) @@ -100,7 +98,7 @@                 setWindowDesktop win curr      forM_ (W.hidden s) $ \w ->-        case elemIndex (W.tag w) (map W.tag ws) of +        case elemIndex (W.tag w) (map W.tag ws) of           Nothing -> return ()           Just wn -> forM_ (W.integrate' (W.stack w)) $ \win -> do                          setWindowDesktop win wn@@ -137,26 +135,57 @@        a_cw <- getAtom "_NET_CLOSE_WINDOW"        a_ignore <- mapM getAtom ["XMONAD_TIMER"]        if  mt == a_cd then do-               let n = fromIntegral (head d)-               if 0 <= n && n < length ws then-                       windows $ W.view (W.tag (ws !! n))+               let n = head d+               if 0 <= n && fi n < length ws then+                       windows $ W.view (W.tag (ws !! fi n))                  else  trace $ "Bad _NET_CURRENT_DESKTOP with data[0]="++show n         else if mt == a_d then do-               let n = fromIntegral (head d)-               if 0 <= n && n < length ws then-                       windows $ W.shiftWin (W.tag (ws !! n)) w+               let n = head d+               if 0 <= n && fi n < length ws then+                       windows $ W.shiftWin (W.tag (ws !! fi n)) w                  else  trace $ "Bad _NET_DESKTOP with data[0]="++show n         else if mt == a_aw then do                windows $ W.focusWindow w         else if mt == a_cw then do                killWindow w         else if mt `elem` a_ignore then do-	       return ()-        else return ()-            -- no warnings about unknown messages for now-            --trace $ "Unknown ClientMessageEvent " ++ show mt+           return ()+        else do+          -- The Message is unknown to us, but that is ok, not all are meant+          -- to be handled by the window manager+          return () handle _ = return () +-- |+-- An event hook to handle applications that wish to fullscreen using the+-- _NET_WM_STATE protocol. This includes users of the gtk_window_fullscreen()+-- function, such as Totem, Evince and OpenOffice.org.+fullscreenEventHook :: Event -> X All+fullscreenEventHook (ClientMessageEvent _ _ _ dpy win typ (action:dats)) = do+  state <- getAtom "_NET_WM_STATE"+  fullsc <- getAtom "_NET_WM_STATE_FULLSCREEN"+  wstate <- fromMaybe [] `fmap` getProp32 state win++  let isFull = fromIntegral fullsc `elem` wstate++      -- Constants for the _NET_WM_STATE protocol:+      remove = 0+      add = 1+      toggle = 2+      ptype = 4 -- The atom property type for changeProperty+      chWstate f = io $ changeProperty32 dpy win state ptype propModeReplace (f wstate)++  when (typ == state && fi fullsc `elem` dats) $ do+    when (action == add || (action == toggle && not isFull)) $ do+      chWstate (fi fullsc:)+      windows $ W.float win $ W.RationalRect 0 0 1 1+    when (action == remove || (action == toggle && isFull)) $ do+      chWstate $ delete (fi fullsc)+      windows $ W.sink win++  return $ All True++fullscreenEventHook _ = return $ All True  setNumberOfDesktops :: (Integral a) => a -> X () setNumberOfDesktops n = withDisplay $ \dpy -> do
XMonad/Hooks/FadeInactive.hs view
@@ -19,6 +19,7 @@     isUnfocused,     fadeIn,     fadeOut,+    fadeIf,     fadeInactiveLogHook,     fadeOutLogHook     ) where@@ -35,15 +36,15 @@ -- > -- > myLogHook :: X () -- > myLogHook = fadeInactiveLogHook fadeAmount--- >     where fadeAmount = 0xdddddddd+-- >     where fadeAmount = 0.8 -- > -- > main = xmonad defaultConfig { logHook = myLogHook } ----- fadeAmount can be any integer+-- fadeAmount can be any rational between 0 and 1. -- you will need to have xcompmgr <http://freedesktop.org/wiki/Software/xapps> -- or something similar for this to do anything ----- For more detailed instructions on editing the layoutHook see:+-- For more detailed instructions on editing the logHook see: -- -- "XMonad.Doc.Extending#The_log_hook_and_external_status_bars" --@@ -51,40 +52,43 @@ -- -- "XMonad.Doc.Extending#Editing_the_layout_hook" --- |--- sets the opacity of a window-setOpacity :: Window -> Integer -> X ()+-- | Converts a percentage to the format required for _NET_WM_WINDOW_OPACITY+rationalToOpacity :: Integral a => Rational -> a+rationalToOpacity perc+    | perc < 0 || perc > 1 = round perc -- to maintain backwards-compatability+    | otherwise = round $ perc * 0xffffffff++-- | sets the opacity of a window+setOpacity :: Window -> Rational -> X () setOpacity w t = withDisplay $ \dpy -> do     a <- getAtom "_NET_WM_WINDOW_OPACITY"     c <- getAtom "CARDINAL"-    io $ changeProperty32 dpy w a c propModeReplace [fromIntegral t]+    io $ changeProperty32 dpy w a c propModeReplace [rationalToOpacity t] --- |--- fades a window out by setting the opacity-fadeOut :: Integer -> Window -> X ()-fadeOut amt = flip setOpacity amt+-- | fades a window out by setting the opacity+fadeOut :: Rational -> Window -> X ()+fadeOut = flip setOpacity --- |--- makes a window completely opaque+-- | makes a window completely opaque fadeIn :: Window -> X ()-fadeIn = flip setOpacity 0xffffffff+fadeIn = fadeOut 1 --- |--- lowers the opacity of inactive windows to the specified amount-fadeInactiveLogHook :: Integer -> X ()-fadeInactiveLogHook amt = fadeOutLogHook isUnfocused amt+-- | Fades a window by the specified amount if it satisfies the first query, otherwise+-- makes it opaque.+fadeIf :: Query Bool -> Rational -> Query Rational+fadeIf qry amt = qry >>= \b -> return $ if b then amt else 1 +-- | sets the opacity of inactive windows to the specified amount+fadeInactiveLogHook :: Rational -> X ()+fadeInactiveLogHook = fadeOutLogHook . fadeIf isUnfocused+ -- | returns True if the window doesn't have the focus.-isUnfocused :: Window -> X Bool-isUnfocused w = withWindowSet $ \s -> return $-                case W.stack . W.workspace . W.current $ s of-                  Nothing -> False-                  Just stack -> W.focus stack /= w+isUnfocused :: Query Bool+isUnfocused = ask >>= \w -> liftX . gets $ maybe True (w /=) . W.peek . windowset --- | fades out every window that satisfies a given property.-fadeOutLogHook :: (Window -> X Bool) -> Integer -> X ()-fadeOutLogHook p amt = withWindowSet $ \s -> do+-- | fades out every window by the amount returned by the query.+fadeOutLogHook :: Query Rational -> X ()+fadeOutLogHook qry = withWindowSet $ \s -> do     let visibleWins = (W.integrate' . W.stack . W.workspace . W.current $ s) ++                       concatMap (W.integrate' . W.stack . W.workspace) (W.visible s)-    mapM_ fadeIn =<< filterM (fmap not . p) visibleWins-    mapM_ (fadeOut amt) =<< filterM p visibleWins+    forM_ visibleWins $ liftM2 (=<<) setOpacity (runQuery qry)
XMonad/Hooks/FloatNext.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveDataTypeable #-} ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Hooks.FloatNext@@ -8,7 +9,7 @@ -- Stability   :  unstable -- Portability :  unportable ----- Hook and keybindings for automatically sending the next +-- Hook and keybindings for automatically sending the next -- spawned window(s) to the floating layer. -- -----------------------------------------------------------------------------@@ -38,45 +39,43 @@ import Prelude hiding (all)  import XMonad+import qualified XMonad.Util.ExtensibleState as XS -import Control.Monad (join)+import Control.Monad (join,guard) import Control.Applicative ((<$>)) import Control.Arrow (first, second)-import Control.Concurrent.MVar-import System.IO.Unsafe (unsafePerformIO) - {- Helper functions -} -modifyMVar2 :: MVar a -> (a -> a) -> IO ()-modifyMVar2 v f = modifyMVar_ v (return . f)- _set :: ((a -> a) -> (Bool, Bool) -> (Bool, Bool)) -> a -> X ()-_set f b = io $ modifyMVar2 floatModeMVar (f $ const b)+_set f b = modify' (f $ const b)  _toggle :: ((Bool -> Bool) -> (Bool, Bool) -> (Bool, Bool)) -> X ()-_toggle f = io $ modifyMVar2 floatModeMVar (f not)+_toggle f = modify' (f not)  _get :: ((Bool, Bool) -> a) -> X a-_get f = io $ f <$> readMVar floatModeMVar+_get f = XS.gets (f . getFloatMode)  _pp :: ((Bool, Bool) -> Bool) -> String -> (String -> String) -> X (Maybe String)-_pp f s st = _get f >>= \b -> if b then return $ Just $ st s else return Nothing-+_pp f s st = (\b -> guard b >> Just (st s)) <$> _get f  {- The current state is kept here -} -floatModeMVar :: MVar (Bool, Bool)-floatModeMVar = unsafePerformIO $ newMVar (False, False)+data FloatMode = FloatMode { getFloatMode :: (Bool,Bool) } deriving (Typeable) +instance ExtensionClass FloatMode where+    initialValue = FloatMode (False,False) +modify' :: ((Bool,Bool) -> (Bool,Bool)) -> X ()+modify' f = XS.modify (FloatMode . f . getFloatMode)+ -- $usage -- This module provides actions (that can be set as keybindings)--- to automatically send the next spawned window(s) to the floating +-- to automatically send the next spawned window(s) to the floating -- layer. -- -- You can use it by including the following in your @~\/.xmonad\/xmonad.hs@:--- +-- -- > import XMonad.Hooks.FloatNext -- -- and adding 'floatNextHook' to your 'ManageHook':@@ -86,22 +85,20 @@ -- The 'floatNext' and 'toggleFloatNext' functions can be used in key -- bindings to float the next spawned window: ----- > , ((modMask, xK_e), toggleFloatNext)+-- > , ((modm, xK_e), toggleFloatNext) -- -- 'floatAllNew' and 'toggleFloatAllNew' are similar but float all -- spawned windows until disabled again. ----- > , ((modMask, xK_r), toggleFloatAllNew)-+-- > , ((modm, xK_r), toggleFloatAllNew)  -- | This 'ManageHook' will selectively float windows as set -- by 'floatNext' and 'floatAllNew'. floatNextHook :: ManageHook-floatNextHook = do (next, all) <- io $ takeMVar floatModeMVar-                   io $ putMVar floatModeMVar (False, all)+floatNextHook = do (next, all) <- liftX $ XS.gets getFloatMode+                   liftX $ XS.put $ FloatMode (False, all)                    if next || all then doFloat else idHook - -- | @floatNext True@ arranges for the next spawned window to be -- sent to the floating layer, @floatNext False@ cancels it. floatNext :: Bool -> X ()@@ -118,7 +115,6 @@ toggleFloatAllNew :: X () toggleFloatAllNew = _toggle second - -- | Whether the next window will be set floating willFloatNext :: X Bool willFloatNext = _get fst@@ -127,26 +123,25 @@ willFloatAllNew :: X Bool willFloatAllNew = _get snd - -- $pp -- The following functions are used to display the current--- state of 'floatNext' and 'floatAllNew' in your +-- state of 'floatNext' and 'floatAllNew' in your -- 'XMonad.Hooks.DynamicLog.dynamicLogWithPP'. -- 'willFloatNextPP' and 'willFloatAllNewPP' should be added--- to the 'XMonad.Hooks.DynamicLog.ppExtras' field of your +-- to the 'XMonad.Hooks.DynamicLog.ppExtras' field of your -- 'XMonad.Hooks.DynamicLog.PP'. -- -- Use 'runLogHook' to refresh the output of your 'logHook', so -- that the effects of a 'floatNext'/... will be visible -- immediately:--- --- > , ((modMask, xK_e), toggleFloatNext >> runLogHook) --+-- > , ((modm, xK_e), toggleFloatNext >> runLogHook)+-- -- The @String -> String@ parameters to 'willFloatNextPP' and--- 'willFloatAllNewPP' will be applied to their output, you +-- 'willFloatAllNewPP' will be applied to their output, you -- can use them to set the text color, etc., or you can just -- pass them 'id'.- + willFloatNextPP :: (String -> String) -> X (Maybe String) willFloatNextPP = _pp fst "Next" 
XMonad/Hooks/InsertPosition.hs view
@@ -46,7 +46,7 @@ insertPosition :: Position -> Focus -> ManageHook insertPosition pos foc = Endo . g <$> ask   where-    g w = viewingWs w (updateFocus w . ins w . W.delete w)+    g w = viewingWs w (updateFocus w . ins w . W.delete' w)     ins w = (\f ws -> fromMaybe id (W.focusWindow <$> W.peek ws) $ f ws) $         case pos of             Master -> W.insertUp w . W.focusMaster
XMonad/Hooks/ManageDocks.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE PatternGuards, FlexibleInstances, MultiParamTypeClasses #-} {-# OPTIONS -fglasgow-exts #-}--- deriving Typeable+-- deriving Typeable for ghc-6.6 compatibility, which is retained in the core ----------------------------------------------------------------------------- -- | -- Module       : XMonad.Hooks.ManageDocks@@ -18,18 +18,23 @@     -- * Usage     -- $usage     manageDocks, checkDock, AvoidStruts, avoidStruts, avoidStrutsOn,-    ToggleStruts(..), Direction(..), calcGap+    ToggleStruts(..),+    SetStruts(..),+    module XMonad.Util.Types,++    -- for XMonad.Actions.FloatSnap+    calcGap     ) where   ----------------------------------------------------------------------------- import XMonad import Foreign.C.Types (CLong)-import Control.Monad import XMonad.Layout.LayoutModifier+import XMonad.Util.Types import XMonad.Util.WindowProperties (getProp32s) -import Data.List (delete)+import qualified Data.Set as S  -- $usage -- To use this module, add the following import to @~\/.xmonad\/xmonad.hs@:@@ -53,12 +58,12 @@ -- 'AvoidStruts' also supports toggling the dock gaps; add a keybinding -- similar to: ----- > ,((modMask x, xK_b     ), sendMessage ToggleStruts)+-- > ,((modm, xK_b     ), sendMessage ToggleStruts) -- -- If you have multiple docks, you can toggle their gaps individually. -- For example, to toggle only the top gap: ----- > ,((modMask x .|. controlMask, xK_t), sendMessage $ ToggleStrut U)+-- > ,((modm .|. controlMask, xK_t), sendMessage $ ToggleStrut U) -- -- Similarly, you can use 'D', 'L', and 'R' to individually toggle -- gaps on the bottom, left, or right.@@ -80,18 +85,6 @@ -- "XMonad.Doc.Extending#Editing_key_bindings". -- --- | An enumeration of the four cardinal directions\/sides of the---   screen.------   Ideally this would go in its own separate module in Util,---   but ManageDocks is angling for inclusion into the xmonad core,---   so keep the dependencies to a minimum.-data Direction = U   -- ^ Up\/top-               | D   -- ^ Down\/bottom-               | R   -- ^ Right-               | L   -- ^ Left-  deriving ( Read, Show, Eq, Ord, Enum, Bounded )- -- | Detects if the given window is of type DOCK and if so, reveals --   it, but does not manage it. If the window has the STRUT property --   set, adjust the gap accordingly.@@ -126,7 +119,7 @@  -- | Goes through the list of windows and find the gap so that all --   STRUT settings are satisfied.-calcGap :: [Direction] -> X (Rectangle -> Rectangle)+calcGap :: S.Set Direction2D -> X (Rectangle -> Rectangle) calcGap ss = withDisplay $ \dpy -> do     rootw <- asks theRoot     -- We don't keep track of dock like windows, so we find all of them here@@ -139,7 +132,7 @@     wa <- io $ getWindowAttributes dpy rootw     let screen = r2c $ Rectangle (fi $ wa_x wa) (fi $ wa_y wa) (fi $ wa_width wa) (fi $ wa_height wa)     return $ \r -> c2r $ foldr (reduce screen) (r2c r) struts-  where careAbout (s,_,_,_) = s `elem` ss+  where careAbout (s,_,_,_) = s `S.member` ss  -- | Adjust layout automagically: don't cover up any docks, status --   bars, etc.@@ -150,39 +143,68 @@ --   etc. on the indicated sides of the screen.  Valid sides are U --   (top), D (bottom), R (right), or L (left). avoidStrutsOn :: LayoutClass l a =>-                 [Direction]+                 [Direction2D]               -> l a               -> ModifiedLayout AvoidStruts l a-avoidStrutsOn ss = ModifiedLayout (AvoidStruts ss)+avoidStrutsOn ss = ModifiedLayout $ AvoidStruts $ S.fromList ss -data AvoidStruts a = AvoidStruts [Direction] deriving ( Read, Show )+data AvoidStruts a = AvoidStruts (S.Set Direction2D) deriving ( Read, Show )  -- | Message type which can be sent to an 'AvoidStruts' layout --   modifier to alter its behavior. data ToggleStruts = ToggleStruts-                  | ToggleStrut Direction+                  | ToggleStrut Direction2D   deriving (Read,Show,Typeable)  instance Message ToggleStruts +-- | SetStruts is a message constructor used to set or unset specific struts,+-- regardless of whether or not the struts were originally set. Here are some+-- example bindings:+--+-- Show all gaps:+--+-- >   ,((modm .|. shiftMask  ,xK_b),sendMessage $ SetStruts [minBound .. maxBound] [])+--+-- Hide all gaps:+--+-- >   ,((modm .|. controlMask,xK_b),sendMessage $ SetStruts [] [minBound .. maxBound])+--+-- Show only upper and left gaps:+--+-- >   ,((modm .|. controlMask .|. shiftMask,xK_b),sendMessage $ SetStruts [U,L] [minBound .. maxBound])+--+-- Hide the bottom keeping whatever the other values were:+--+-- >   ,((modm .|. controlMask .|. shiftMask,xK_g),sendMessage $ SetStruts [] [D])+data SetStruts = SetStruts { addedStruts   :: [Direction2D]+                           , removedStruts :: [Direction2D] -- ^ These are removed from the currently set struts before 'addedStruts' are added.+                           }+  deriving (Read,Show,Typeable)++instance Message SetStruts+ instance LayoutModifier AvoidStruts a where     modifyLayout (AvoidStruts ss) w r = do         nr <- fmap ($ r) (calcGap ss)         runLayout w nr -    handleMess (AvoidStruts ss) m-        | Just ToggleStruts    <- fromMessage m = return $ Just $ AvoidStruts (toggleAll ss)-        | Just (ToggleStrut s) <- fromMessage m = return $ Just $ AvoidStruts (toggleOne s ss)-        | otherwise = return Nothing-      where toggleAll []   = [U,D,L,R]-            toggleAll _    = []-            toggleOne x xs | x `elem` xs = delete x xs-                           | otherwise   = x : xs+    pureMess (AvoidStruts ss) m+        | Just ToggleStruts    <- fromMessage m = Just $ AvoidStruts (toggleAll ss)+        | Just (ToggleStrut s) <- fromMessage m = Just $ AvoidStruts (toggleOne s ss)+        | Just (SetStruts n k) <- fromMessage m+        , let newSS = S.fromList n `S.union` (ss S.\\ S.fromList k)+        , newSS /= ss = Just $ AvoidStruts newSS+        | otherwise = Nothing+      where toggleAll x | S.null x = S.fromList [minBound .. maxBound]+                        | otherwise = S.empty+            toggleOne x xs | x `S.member` xs = S.delete x xs+                           | otherwise   = x `S.insert` xs   -- | (Direction, height\/width, initial pixel, final pixel). -type Strut = (Direction, CLong, CLong, CLong)+type Strut = (Direction2D, CLong, CLong, CLong)  -- | (Initial x pixel, initial y pixel, --    final x pixel, final y pixel).@@ -213,15 +235,18 @@  reduce :: RectC -> Strut -> RectC -> RectC reduce (sx0, sy0, sx1, sy1) (s, n, l, h) (x0, y0, x1, y1) = case s of-    L | p (y0, y1) -> (mx x0 sx0    , y0       , x1       , y1       )-    R | p (y0, y1) -> (x0           , y0       , mn x1 sx1, y1       )-    U | p (x0, x1) -> (x0           , mx y0 sy0, x1       , y1       )-    D | p (x0, x1) -> (x0           , y0       , x1       , mn y1 sy1)-    _              -> (x0           , y0       , x1       , y1       )+    L | p (y0, y1) && qh x1     -> (mx x0 sx0, y0       , x1       , y1       )+    R | p (y0, y1) && qv sx1 x0 -> (x0       , y0       , mn x1 sx1, y1       )+    U | p (x0, x1) && qh y1     -> (x0       , mx y0 sy0, x1       , y1       )+    D | p (x0, x1) && qv sy1 y0 -> (x0       , y0       , x1       , mn y1 sy1)+    _                           -> (x0       , y0       , x1       , y1       )  where     mx a b = max a (b + n)     mn a b = min a (b - n)     p r = r `overlaps` (l, h)+    -- Filter out struts that cover the entire rectangle:+    qh d1 = n <= d1+    qv sd1 d0 = sd1 - n >= d0  -- | Do the two ranges overlap? --
XMonad/Hooks/ManageHelpers.hs view
@@ -28,6 +28,7 @@     Side(..),     composeOne,     (-?>), (/=?), (<==?), (</=?), (-->>), (-?>>),+    currentWs,     isInProperty,     isKDETrayWindow,     isFullscreen,@@ -42,6 +43,8 @@     doFullFloat,     doCenterFloat,     doSideFloat,+    doFloatAt,+    doFloatDep,     doHideIgnore ) where @@ -54,7 +57,7 @@  import System.Posix (ProcessID) --- | Denotes a side of a screen. @S@ stands for South, @NE@ for Northwest+-- | Denotes a side of a screen. @S@ stands for South, @NE@ for Northeast -- etc. @C@ stands for Center. data Side = SC | NC | CE | CW | SE | SW | NE | NW | C     deriving (Read, Show, Eq)@@ -116,6 +119,10 @@     Match b m <- p     if b then fmap  Just (f m) else return Nothing +-- | Return the current workspace+currentWs :: Query WorkspaceId+currentWs = liftX (withWindowSet $ return . W.currentTag)+ -- | A predicate to check whether a window is a KDE system tray icon. isKDETrayWindow :: Query Bool isKDETrayWindow = ask >>= \w -> liftX $ do@@ -185,19 +192,31 @@ doFullFloat :: ManageHook doFullFloat = doRectFloat $ W.RationalRect 0 0 1 1 +-- | Floats a new window using a rectangle computed as a function of+--   the rectangle that it would have used by default.+doFloatDep :: (W.RationalRect -> W.RationalRect) -> ManageHook+doFloatDep move = ask >>= \w -> doF . W.float w . move . snd =<< liftX (floatLocation w)++-- | Floats a new window with its original size, and its top left+--   corner at a specific point on the screen (both coordinates should+--   be in the range 0 to 1).+doFloatAt :: Rational -> Rational -> ManageHook+doFloatAt x y = doFloatDep move+  where+    move (W.RationalRect _ _ w h) = W.RationalRect x y w h+ -- | Floats a new window with its original size on the specified side of a -- screen doSideFloat :: Side -> ManageHook-doSideFloat side = ask >>= \w -> doF . W.float w . move . snd =<< liftX (floatLocation w)-    where+doSideFloat side = doFloatDep move+  where     move (W.RationalRect _ _ w h) = W.RationalRect cx cy w h-        where-        cx =      if side `elem` [SC,C ,NC] then (1-w)/2-             else if side `elem` [SW,CW,NW] then 0-             else {- side `elem` [SE,CE,NE] -}   1-w-        cy =      if side `elem` [CE,C ,CW] then (1-h)/2-             else if side `elem` [NE,NC,NW] then 0-             else {- side `elem` [SE,SC,SW] -}   1-h+      where cx =      if side `elem` [SC,C ,NC] then (1-w)/2+                 else if side `elem` [SW,CW,NW] then 0+                 else {- side `elem` [SE,CE,NE] -}   1-w+            cy =      if side `elem` [CE,C ,CW] then (1-h)/2+                 else if side `elem` [NE,NC,NW] then 0+                 else {- side `elem` [SE,SC,SW] -}   1-h  -- | Floats a new window with its original size, but centered. doCenterFloat :: ManageHook
XMonad/Hooks/Place.hs view
@@ -14,7 +14,7 @@  module XMonad.Hooks.Place   ( -- * Usage                               -- $usage-                                                            +                               -- * Placement actions                               placeFocused                             , placeHook@@ -42,7 +42,7 @@ import qualified Data.Map as M import Data.Ratio ((%)) import Data.List (sortBy, minimumBy, partition)-import Data.Maybe (maybe, fromMaybe, catMaybes)+import Data.Maybe (fromMaybe, catMaybes) import Data.Monoid (Endo(..)) import Control.Monad (guard, join) import Control.Monad.Trans (lift)@@ -53,7 +53,7 @@ -- as an 'X' action to manually trigger repositioning. -- -- You can use this module by including the following in your @~\/.xmonad\/xmonad.hs@:--- +-- -- > import XMonad.Hooks.Place -- -- and adding 'placeHook' to your 'manageHook', for example:@@ -61,17 +61,17 @@ -- > main = xmonad $ defaultConfig { manageHook = placeHook simpleSmart -- >                                              <+> manageHook defaultConfig } ----- Note that 'placeHook' should be applied after most other hooks, especially hooks +-- Note that 'placeHook' should be applied after most other hooks, especially hooks -- such as 'doFloat' and 'doShift'. Since hooks combined with '<+>' are applied from -- right to left, this means that 'placeHook' should be the /first/ hook in your chain. -- -- You can also define a key to manually trigger repositioning with 'placeFocused' by -- adding the following to your keys definition: ----- > , ((modMask, xK_w), placeFocused simpleSmart)+-- > , ((modm, xK_w), placeFocused simpleSmart) -- -- Both 'placeHook' and 'placeFocused' take a 'Placement' parameter, which specifies--- the placement policy to use (smart, under the mouse, fixed position, etc.). See +-- the placement policy to use (smart, under the mouse, fixed position, etc.). See -- 'Placement' for a list of available policies.  @@ -118,12 +118,12 @@   -- | Place windows at a fixed position-fixed :: (Rational, Rational) -- ^ Where windows should go. -                              -- -                              --     * (0,0) -> top left of the screen -                              -- +fixed :: (Rational, Rational) -- ^ Where windows should go.+                              --+                              --     * (0,0) -> top left of the screen+                              --                               --     * (1,0) -> top right of the screen-                              -- +                              --                               --     * etc       -> Placement fixed = Fixed@@ -136,14 +136,14 @@ underMouse = UnderMouse  --- | Apply the given placement policy, constraining the +-- | Apply the given placement policy, constraining the -- placed windows inside the screen boundaries.-inBounds :: Placement -> Placement +inBounds :: Placement -> Placement inBounds = Bounds (0,0,0,0)   -- | Same as 'inBounds', but allows specifying gaps along the screen's edges-withGaps :: (Dimension, Dimension, Dimension, Dimension) +withGaps :: (Dimension, Dimension, Dimension, Dimension)          -- ^ top, right, bottom and left gaps          -> Placement -> Placement withGaps = Bounds@@ -160,7 +160,7 @@ placeFocused p = withFocused $ \window -> do                    info <- gets $ screenInfo . S.current . windowset                    floats <- gets $ M.keys . S.floating . windowset-                   +                    r'@(Rectangle x' y' _ _) <- placeWindow p window info floats                       -- use X.A.FloatKeys if the window is floating, send@@ -182,8 +182,8 @@                           floats = M.keys $ S.floating theWS                        guard(window `elem` floats )-                      -                        -- Look for the workspace(s) on which the window is to be ++                        -- Look for the workspace(s) on which the window is to be                         -- spawned. Each of them also needs an associated screen                         -- rectangle; for hidden workspaces, we use the current                         -- workspace's screen.@@ -191,7 +191,7 @@                                      $ [screenInfo $ S.current theWS]                                         ++ (map screenInfo $ S.visible theWS)                                         ++ zip (S.hidden theWS) (repeat currentRect)-                                           +                       guard(not $ null infos)                        let (workspace, screen) = head infos@@ -223,7 +223,7 @@                 -> (Position, Position) -- ^ The pointer's position.                 -> Rectangle -- ^ The window to be placed                 -> Rectangle-purePlaceWindow (Bounds (t,r,b,l) p') (Rectangle sx sy sw sh) rs p w +purePlaceWindow (Bounds (t,r,b,l) p') (Rectangle sx sy sw sh) rs p w   = let s' = (Rectangle (sx + fi l) (sy + fi t) (sw - l - r) (sh - t - b))     in checkBounds s' $ purePlaceWindow p' s' rs p w @@ -267,9 +267,9 @@  r2rr :: Rectangle -> Rectangle -> S.RationalRect r2rr (Rectangle x0 y0 w0 h0) (Rectangle x y w h)-  = S.RationalRect ((fi x-fi x0) % fi w0) -                   ((fi y-fi y0) % fi h0) -                   (fi w % fi w0) +  = S.RationalRect ((fi x-fi x0) % fi w0)+                   ((fi y-fi y0) % fi h0)+                   (fi w % fi w0)                    (fi h % fi h0)  @@ -286,7 +286,7 @@ getWindowRectangle window   = do d <- asks display        (_, x, y, w, h, _, _) <- io $ getGeometry d window-       +          -- We can't use the border width returned by          -- getGeometry because it will be 0 if the          -- window isn't mapped yet.@@ -305,11 +305,11 @@                       return $ M.fromList $ zip allWindows allRects  organizeClients :: S.Workspace a b Window -> Window -> [Window] -> [Window]-organizeClients ws w floats -  = let (floatCs, layoutCs) = partition (`elem` floats) $ filter (/= w) +organizeClients ws w floats+  = let (floatCs, layoutCs) = partition (`elem` floats) $ filter (/= w)                               $ stackContents $ S.stack ws     in reverse layoutCs ++ reverse floatCs-      -- About the ordering: the smart algorithm will overlap windows +      -- About the ordering: the smart algorithm will overlap windows       -- starting ith the head of the list. So:       --  - we put the non-floating windows first since they'll       --    probably be below the floating ones,@@ -323,18 +323,18 @@  -- | Return values are, in order: window's rectangle, -- other windows' rectangles and pointer's coordinates.-getNecessaryData :: Window +getNecessaryData :: Window                  -> S.Workspace WorkspaceId (Layout Window) Window                  -> [Window]                  -> X (Rectangle, [Rectangle], (Position, Position)) getNecessaryData window ws floats   = do r <- getWindowRectangle window-       +        rs <- return (organizeClients ws window floats)              >>= mapM getWindowRectangle         pointer <- getPointer window-                        +        return (r, rs, pointer)  @@ -343,7 +343,7 @@ {- Smart placement algorithm -}  -- | Alternate representation for rectangles.-data SmartRectangle a = SR +data SmartRectangle a = SR   { sr_x0, sr_y0 :: a -- ^ Top left coordinates, inclusive   , sr_x1, sr_y1 :: a -- ^ Bottom right coorsinates, exclusive   } deriving (Show, Eq)@@ -380,12 +380,12 @@            -> Rectangle placeSmart (rx, ry) s@(Rectangle sx sy sw sh) rs w h   = let free = map sr2r $ findSpace (r2sr s) (map r2sr rs) (fi w) (fi h)-    in position free (scale rx sx (sx + fi sw - fi w)) -                     (scale ry sy (sy + fi sh - fi h)) +    in position free (scale rx sx (sx + fi sw - fi w))+                     (scale ry sy (sy + fi sh - fi h))                      w h --- | Second part of the algorithm: --- Chooses the best position in which to place a window, +-- | Second part of the algorithm:+-- Chooses the best position in which to place a window, -- according to a list of free areas and an ideal position for -- the top-left corner. -- We can't use semi-open surfaces for this, so we go back to@@ -395,41 +395,41 @@          -> Dimension -> Dimension -- ^ Width and height of the window          -> Rectangle position rs x y w h = minimumBy distanceOrder $ map closest rs-  where distanceOrder r1 r2 +  where distanceOrder r1 r2           = compare (distance (rect_x r1,rect_y r1) (x,y) :: Dimension)                     (distance (rect_x r2,rect_y r2) (x,y) :: Dimension)-        distance (x1,y1) (x2,y2) = truncate $ (sqrt :: Double -> Double) -                                   $ fi $ (x1 - x2)^(2::Int) +        distance (x1,y1) (x2,y2) = truncate $ (sqrt :: Double -> Double)+                                   $ fi $ (x1 - x2)^(2::Int)                                         + (y1 - y2)^(2::Int)         closest r = checkBounds r (Rectangle x y w h)   -- | First part of the algorithm:--- Tries to find an area in which to place a new +-- Tries to find an area in which to place a new -- rectangle so that it overlaps as little as possible with--- other rectangles aready present. The first rectangles in+-- other rectangles already present. The first rectangles in -- the list will be overlapped first. findSpace :: Real a =>              SmartRectangle a -- ^ The total available area-          -> [SmartRectangle a] -- ^ The parts aready in use+          -> [SmartRectangle a] -- ^ The parts already in use           -> a -- ^ Width of the rectangle to place           -> a -- ^ Height of the rectangle to place           -> [SmartRectangle a] findSpace total [] _ _ = [total] findSpace total rs@(_:rs') w h-  = case filter largeEnough $ cleanup $ substractRects total rs of+  = case filter largeEnough $ cleanup $ subtractRects total rs of       [] -> findSpace total rs' w h       as -> as     where largeEnough r = width r >= w && height r >= h  --- | Substracts smaller rectangles from a total rectangle+-- | Subtracts smaller rectangles from a total rectangle -- , returning a list of remaining rectangular areas.-substractRects :: Real a => SmartRectangle a +subtractRects :: Real a => SmartRectangle a                -> [SmartRectangle a] -> [SmartRectangle a]-substractRects total [] = [total]-substractRects total (r:rs) -  = do total' <- substractRects total rs+subtractRects total [] = [total]+subtractRects total (r:rs)+  = do total' <- subtractRects total rs        filter (not . isEmpty)                 [ total' {sr_y1 = min (sr_y1 total') (sr_y0 r)} -- Above                 , total' {sr_x0 = max (sr_x0 total') (sr_x1 r)} -- Right@@ -439,7 +439,7 @@   -- | "Nubs" a list of rectangles, dropping all those that are--- already contained in another rectangle of the list. +-- already contained in another rectangle of the list. cleanup :: Real a => [SmartRectangle a] -> [SmartRectangle a] cleanup rs = foldr dropIfContained [] $ sortBy sizeOrder rs @@ -453,7 +453,7 @@                       h1 = height r1                       h2 = height r2 -dropIfContained :: Real a => SmartRectangle a +dropIfContained :: Real a => SmartRectangle a                 -> [SmartRectangle a] -> [SmartRectangle a] dropIfContained r rs  = if any (`contains` r) rs                         then rs
+ XMonad/Hooks/PositionStoreHooks.hs view
@@ -0,0 +1,95 @@+----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Hooks.PositionStoreHooks+-- Copyright   :  (c) Jan Vornberger 2009+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de+-- Stability   :  unstable+-- Portability :  not portable+--+-- This module contains two hooks for the+-- PositionStore (see "XMonad.Util.PositionStore") - a ManageHook and+-- an EventHook.+--+-- The ManageHook can be used to fill the PositionStore with position and size+-- information about new windows. The advantage of using this hook is, that the+-- information is recorded independent of the currently active layout. So the+-- floating shape of the window can later be restored even if it was opened in a+-- tiled layout initially.+--+-- For windows, that do not request a particular position, a random position will+-- be assigned. This prevents windows from piling up exactly on top of each other.+--+-- The EventHook makes sure that windows are deleted from the PositionStore+-- when they are closed.+--+-----------------------------------------------------------------------------++module XMonad.Hooks.PositionStoreHooks (+    -- * Usage+    -- $usage+    positionStoreManageHook,+    positionStoreEventHook+    ) where++import XMonad+import qualified XMonad.StackSet as W+import XMonad.Util.PositionStore+import XMonad.Util.XUtils (fi)++import System.Random(randomRIO)+import Control.Applicative((<$>))+import Control.Monad(when)+import Data.Maybe+import Data.Monoid++-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Hooks.PositionStoreHooks+--+-- and adding 'positionStoreManageHook' to your 'ManageHook' as well+-- as 'positionStoreEventHook' to your event hooks:+--+-- > myManageHook = positionStoreManageHook <+> manageHook defaultConfig+-- > myHandleEventHook = positionStoreEventHook+-- >+-- > main = xmonad defaultConfig { manageHook = myManageHook+-- >                             , handleEventHook = myHandleEventHook+-- >                             }+--++positionStoreManageHook :: ManageHook+positionStoreManageHook = ask >>= liftX . positionStoreInit >> idHook++positionStoreInit :: Window -> X ()+positionStoreInit w = withDisplay $ \d -> do+        wa <- io $ getWindowAttributes d w+        ws <- gets windowset+        arbitraryOffsetX <- randomIntOffset+        arbitraryOffsetY <- randomIntOffset+        if (wa_x wa == 0) && (wa_y wa == 0)+            then do+                let sr@(Rectangle srX srY _ _) = screenRect . W.screenDetail . W.current $ ws+                modifyPosStore (\ps -> posStoreInsert ps w+                                        (Rectangle (srX + fi arbitraryOffsetX)+                                                   (srY + fi arbitraryOffsetY)+                                                    (fi $ wa_width wa)+                                                    (fi $ wa_height wa)) sr )+            else do+                sc <- fromMaybe (W.current ws) <$> pointScreen (fi $ wa_x wa) (fi $ wa_y wa)+                let sr = screenRect . W.screenDetail $ sc+                modifyPosStore (\ps -> posStoreInsert ps w+                                        (Rectangle (fi $ wa_x wa) (fi $ wa_y wa)+                                            (fi $ wa_width wa) (fi $ wa_height wa)) sr )+    where+        randomIntOffset :: X (Int)+        randomIntOffset = io $ randomRIO (42, 242)++positionStoreEventHook :: Event -> X All+positionStoreEventHook (DestroyWindowEvent {ev_window = w, ev_event_type = et}) = do+    when (et == destroyNotify) $ do+        modifyPosStore (\ps -> posStoreRemove ps w)+    return (All True)+positionStoreEventHook _ = return (All True)
XMonad/Hooks/RestoreMinimized.hs view
@@ -8,10 +8,16 @@ -- Stability   :  unstable -- Portability :  not portable --+-- Lets you restore minimized windows (see "XMonad.Layout.Minimize")+-- by selecting them on a taskbar (listens for _NET_ACTIVE_WINDOW+-- and WM_CHANGE_STATE).+-- -----------------------------------------------------------------------------  module XMonad.Hooks.RestoreMinimized-    ( RestoreMinimized (..)+    ( -- * Usage+      -- $usage+      RestoreMinimized (..)     , restoreMinimizedEventHook     ) where @@ -20,6 +26,15 @@  import XMonad import XMonad.Layout.Minimize++-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Hooks.RestoreMinimized+-- >+-- > myHandleEventHook = restoreMinimizedEventHook+-- >+-- > main = xmonad defaultConfig { handleEventHook = myHandleEventHook }  data RestoreMinimized = RestoreMinimized deriving ( Show, Read ) 
+ XMonad/Hooks/ScreenCorners.hs view
@@ -0,0 +1,170 @@+{-# LANGUAGE DeriveDataTypeable #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Hooks.ScreenCorners+-- Copyright   :  (c) 2009 Nils Schweinsberg+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Nils Schweinsberg <mail@n-sch.de>+-- Stability   :  unstable+-- Portability :  unportable+--+-- Run @X ()@ actions by touching the edge of your screen with your mouse.+--+-----------------------------------------------------------------------------++module XMonad.Hooks.ScreenCorners+    (+    -- * Usage+    -- $usage++    -- * Adding screen corners+      ScreenCorner (..)+    , addScreenCorner+    , addScreenCorners++    -- * Event hook+    , screenCornerEventHook+    ) where++import Data.Monoid+import Data.List (find)+import XMonad+import XMonad.Util.XUtils (fi)++import qualified Data.Map as M+import qualified XMonad.Util.ExtensibleState as XS++data ScreenCorner = SCUpperLeft+                  | SCUpperRight+                  | SCLowerLeft+                  | SCLowerRight+                  deriving (Eq, Ord, Show)++++--------------------------------------------------------------------------------+-- ExtensibleState modifications+--------------------------------------------------------------------------------++newtype ScreenCornerState = ScreenCornerState (M.Map Window (ScreenCorner, X ()))+    deriving Typeable++instance ExtensionClass ScreenCornerState where+    initialValue = ScreenCornerState M.empty++-- | Add one single @X ()@ action to a screen corner+addScreenCorner :: ScreenCorner -> X () -> X ()+addScreenCorner corner xF = do++    ScreenCornerState m <- XS.get+    (win,xFunc) <- case find (\(_,(sc,_)) -> sc == corner) (M.toList m) of++                        Just (w, (_,xF')) -> return (w, xF' >> xF) -- chain X actions+                        Nothing           -> flip (,) xF `fmap` createWindowAt corner++    XS.modify $ \(ScreenCornerState m') -> ScreenCornerState $ M.insert win (corner,xFunc) m'++-- | Add a list of @(ScreenCorner, X ())@ tuples+addScreenCorners :: [ (ScreenCorner, X ()) ] -> X ()+addScreenCorners = mapM_ (\(corner, xF) -> addScreenCorner corner xF)+++--------------------------------------------------------------------------------+-- Xlib functions+--------------------------------------------------------------------------------++-- "Translate" a ScreenCorner to real (x,y) Positions+createWindowAt :: ScreenCorner -> X Window+createWindowAt SCUpperLeft = createWindowAt' 0 0+createWindowAt SCUpperRight = withDisplay $ \dpy ->+    let w = displayWidth  dpy (defaultScreen dpy) - 1+    in createWindowAt' (fi w) 0++createWindowAt SCLowerLeft = withDisplay $ \dpy ->+    let h = displayHeight dpy (defaultScreen dpy) - 1+    in createWindowAt' 0 (fi h)++createWindowAt SCLowerRight = withDisplay $ \dpy ->+    let w = displayWidth  dpy (defaultScreen dpy) - 1+        h = displayHeight dpy (defaultScreen dpy) - 1+    in createWindowAt' (fi w) (fi h)++-- Create a new X window at a (x,y) Position+createWindowAt' :: Position -> Position -> X Window+createWindowAt' x y = withDisplay $ \dpy -> io $ do++    rootw <- rootWindow dpy (defaultScreen dpy)++    let+        visual   = defaultVisualOfScreen $ defaultScreenOfDisplay dpy+        attrmask = cWOverrideRedirect++    w <- allocaSetWindowAttributes $ \attributes -> do++        set_override_redirect attributes True+        createWindow dpy        -- display+                     rootw      -- parent window+                     x          -- x+                     y          -- y+                     1          -- width+                     1          -- height+                     0          -- border width+                     0          -- depth+                     inputOnly  -- class+                     visual     -- visual+                     attrmask   -- valuemask+                     attributes -- attributes++    -- we only need mouse entry events+    selectInput dpy w enterWindowMask+    mapWindow dpy w+    sync dpy False+    return w+++--------------------------------------------------------------------------------+-- Event hook+--------------------------------------------------------------------------------++-- | Handle screen corner events+screenCornerEventHook :: Event -> X All+screenCornerEventHook CrossingEvent { ev_window = win } = do++    ScreenCornerState m <- XS.get++    case M.lookup win m of+         Just (_, xF) -> xF+         Nothing      -> return ()++    return (All True)++screenCornerEventHook _ = return (All True)+++--------------------------------------------------------------------------------+-- $usage+--+-- This extension adds KDE-like screen corners to XMonad. By moving your cursor+-- into one of your screen corners you can trigger an @X ()@ action, for+-- example @"XMonad.Actions.GridSelect".goToSelected@ or+-- @"XMonad.Actions.CycleWS".nextWS@ etc.+--+-- To use it, import it on top of your @xmonad.hs@:+--+-- > import XMonad.Hooks.ScreenCorners+--+-- Then add your screen corners in our startup hook:+--+-- > myStartupHook = do+-- >     ...+-- >     addScreenCorner SCUpperRight (goToSelected defaultGSConfig { gs_cellwidth = 200})+-- >     addScreenCorners [ (SCLowerRight, nextWS)+-- >                      , (SCLowerLeft,  prevWS)+-- >                      ]+--+-- And finally wait for screen corner events in your event hook:+--+-- > myEventHook e = do+-- >     ...+-- >     screenCornerEventHook e
XMonad/Hooks/Script.hs view
@@ -26,7 +26,6 @@ -- import XMonad -import Control.Monad.Trans import System.Directory  -- $usage@@ -43,7 +42,7 @@ -- >   ... -- >   } ----- Now, everytime the startup hook runs, the command+-- Now, every time the startup hook runs, the command -- @~\/.xmonad\/hooks startup@ will also.  -- | Execute a named script hook
XMonad/Hooks/ServerMode.hs view
@@ -60,11 +60,10 @@       -- $usage       ServerMode (..)     , serverModeEventHook-    , serverModeEventHookCustom+    , serverModeEventHook'     ) where  import Control.Monad (when)-import Data.List import Data.Monoid import System.IO @@ -76,6 +75,7 @@ -- @~\/.xmonad\/xmonad.hs@: -- -- > import XMonad.Hooks.ServerMode+-- > import XMonad.Actions.Commands -- -- Then edit your @handleEventHook@ by adding the 'serverModeEventHook': --@@ -84,18 +84,22 @@  data ServerMode = ServerMode deriving ( Show, Read ) +-- | Executes a command of the list when receiving its index via a special ClientMessageEvent+-- (indexing starts at 1) serverModeEventHook :: Event -> X All-serverModeEventHook = serverModeEventHookCustom defaultCommands+serverModeEventHook = serverModeEventHook' defaultCommands -serverModeEventHookCustom :: X [(String, X ())] -> Event -> X All-serverModeEventHookCustom commands (ClientMessageEvent {ev_message_type = mt, ev_data = dt}) = do+-- | serverModeEventHook' additionally takes an action to generate the list of+-- commands.+serverModeEventHook' :: X [(String,X ())] -> Event -> X All+serverModeEventHook' cmdAction (ClientMessageEvent {ev_message_type = mt, ev_data = dt}) = do         d <- asks display         a <- io $ internAtom d "XMONAD_COMMAND" False         when (mt == a && dt /= []) $ do-             cl <- commands+             cl <- cmdAction              let listOfCommands = map (uncurry (++)) . zip (map show ([1..] :: [Int])) . map ((++) " - " . fst)              case lookup (fromIntegral (head dt) :: Int) (zip [1..] cl) of                   Just (_,action) -> action                   Nothing         -> mapM_ (io . hPutStrLn stderr) . listOfCommands $ cl         return (All True)-serverModeEventHookCustom _ _ = return (All True)+serverModeEventHook' _ _ = return (All True)
XMonad/Hooks/UrgencyHook.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, TypeSynonymInstances, PatternGuards #-}+{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, TypeSynonymInstances, PatternGuards, DeriveDataTypeable,+  FlexibleInstances #-}  ----------------------------------------------------------------------------- -- |@@ -71,17 +72,16 @@ import qualified XMonad.StackSet as W  import XMonad.Util.Dzen (dzenWithArgs, seconds)+import qualified XMonad.Util.ExtensibleState as XS import XMonad.Util.NamedWindows (getName) import XMonad.Util.Timer (TimerId, startTimer, handleTimer)  import Control.Applicative ((<$>)) import Control.Monad (when) import Data.Bits (testBit)-import Data.IORef import Data.List (delete) import Data.Maybe (listToMaybe, maybeToList) import qualified Data.Set as S-import Foreign (unsafePerformIO)  -- $usage --@@ -138,7 +138,7 @@ --    two parts: -- --      * The console app must send a ^G (bell). In bash, a helpful trick is---        @sleep 1; echo -e \'\a\'@.+--        @sleep 1; echo -e \'\\a\'@. -- --      * The terminal must convert the bell into UrgencyHint. --@@ -195,7 +195,7 @@ -- hopefully you know where to find it.  -- | This is the method to enable an urgency hook. It uses the default--- 'urgencyConfig' to control behavior. To change this, use 'withUrgencyHook'+-- 'urgencyConfig' to control behavior. To change this, use 'withUrgencyHookC' -- instead. withUrgencyHook :: (LayoutClass l Window, UrgencyHook h) =>                    h -> XConfig l -> XConfig l@@ -213,6 +213,15 @@         logHook = cleanupUrgents (suppressWhen urgConf) >> logHook conf     } +data Urgents = Urgents { fromUrgents :: [Window] } deriving (Read,Show,Typeable)++onUrgents :: ([Window] -> [Window]) -> Urgents -> Urgents+onUrgents f = Urgents . f . fromUrgents++instance ExtensionClass Urgents where+    initialValue = Urgents []+    extensionType = PersistentExtension+ -- | Global configuration, applied to all types of 'UrgencyHook'. See -- 'urgencyConfig' for the defaults. data UrgencyConfig = UrgencyConfig@@ -251,36 +260,29 @@ -- | Focuses the most recently urgent window. Good for what ails ya -- I mean, your keybindings. -- Example keybinding: ----- > , ((modMask              , xK_BackSpace), focusUrgent)+-- > , ((modm              , xK_BackSpace), focusUrgent) focusUrgent :: X () focusUrgent = withUrgents $ flip whenJust (windows . W.focusWindow) . listToMaybe  -- | Just makes the urgents go away. -- Example keybinding: ----- > , ((modMask .|. shiftMask, xK_BackSpace), clearUrgents)+-- > , ((modm .|. shiftMask, xK_BackSpace), clearUrgents) clearUrgents :: X () clearUrgents = adjustUrgents (const []) >> adjustReminders (const []) --- | Stores the global set of all urgent windows, across workspaces. Not exported -- use--- 'readUrgents' or 'withUrgents' instead.-{-# NOINLINE urgents #-}-urgents :: IORef [Window]-urgents = unsafePerformIO (newIORef [])--- (Hey, I don't like it any more than you do.)- -- | X action that returns a list of currently urgent windows. You might use -- it, or 'withUrgents', in your custom logHook, to display the workspaces that -- contain urgent windows. readUrgents :: X [Window]-readUrgents = io $ readIORef urgents+readUrgents = XS.gets fromUrgents  -- | An HOF version of 'readUrgents', for those who prefer that sort of thing. withUrgents :: ([Window] -> X a) -> X a withUrgents f = readUrgents >>= f  adjustUrgents :: ([Window] -> [Window]) -> X ()-adjustUrgents f = io $ modifyIORef urgents f+adjustUrgents = XS.modify . onUrgents  type Interval = Rational @@ -290,18 +292,19 @@                          , window    :: Window                          , interval  :: Interval                          , remaining :: Maybe Int-                         } deriving Eq+                         } deriving (Show,Read,Eq,Typeable) +instance ExtensionClass [Reminder] where+    initialValue = []+    extensionType = PersistentExtension+ -- | Stores the list of urgency reminders.-{-# NOINLINE reminders #-}-reminders :: IORef [Reminder]-reminders = unsafePerformIO (newIORef [])  readReminders :: X [Reminder]-readReminders = io $ readIORef reminders+readReminders = XS.get  adjustReminders :: ([Reminder] -> [Reminder]) -> X ()-adjustReminders f = io $ modifyIORef reminders f+adjustReminders = XS.modify  clearUrgency :: Window -> X () clearUrgency w = adjustUrgents (delete w) >> adjustReminders (filter $ (w /=) . window)@@ -332,7 +335,7 @@                   callUrgencyHook wuh w                 else                   clearUrgency w-              userCodeDef () =<< asks (logHook . config) -- call *after* IORef has been modified+              userCodeDef () =<< asks (logHook . config)       DestroyWindowEvent {ev_window = w} ->           clearUrgency w       _ ->
XMonad/Hooks/WorkspaceByPos.hs view
@@ -8,43 +8,47 @@ -- Stability   :  unstable -- Portability :  not portable --+-- Useful in a dual-head setup: Looks at the requested geometry of+-- new windows and moves them to the workspace of the non-focused+-- screen if necessary.+-- -----------------------------------------------------------------------------  module XMonad.Hooks.WorkspaceByPos (+    -- * Usage+    -- $usage     workspaceByPos     ) where  import XMonad import qualified XMonad.StackSet as W+import XMonad.Util.XUtils (fi)  import Data.Maybe import Control.Applicative((<$>))+import Control.Monad.Error ((<=<),guard,lift,runErrorT,throwError) +-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Hooks.WorkspaceByPos+-- >+-- > myManageHook = workspaceByPos <+> manageHook defaultConfig+-- >+-- > main = xmonad defaultConfig { manageHook = myManageHook }+ workspaceByPos :: ManageHook-workspaceByPos = ask >>= \w -> do-                    b <- liftX $ needsMoving w-                    case b of-                        Nothing       -> idHook-                        Just wkspc    -> doShift wkspc+workspaceByPos = (maybe idHook doShift <=< liftX . needsMoving) =<< ask  needsMoving :: Window -> X (Maybe WorkspaceId) needsMoving w = withDisplay $ \d -> do-                    -- only relocate windows with non-zero position-                    wa <- io $ getWindowAttributes d w-                    if ((wa_x wa) == 0) && ((wa_y wa) == 0)-                        then return Nothing-                        else do-                            ws <- gets windowset-                            sc <- fromMaybe (W.current ws)-                                    <$> pointScreen (fi $ wa_x wa) (fi $ wa_y wa)-                            maybeWkspc <- screenWorkspace (W.screen sc)-                            case maybeWkspc of-                                Nothing -> return Nothing-                                Just wkspc -> do-                                    let currentWksp = W.currentTag ws-                                    if currentWksp == wkspc-                                        then return Nothing-                                        else return (Just wkspc)--fi ::  (Integral a, Num b) => a -> b-fi = fromIntegral+    -- only relocate windows with non-zero position+    wa <- io $ getWindowAttributes d w+    fmap (const Nothing `either` Just) . runErrorT $ do+        guard $ wa_x wa /= 0 || wa_y wa /= 0+        ws <- gets windowset+        sc <- lift $ fromMaybe (W.current ws)+                <$> pointScreen (fi $ wa_x wa) (fi $ wa_y wa)+        Just wkspc <- lift $ screenWorkspace (W.screen sc)+        guard $ W.currentTag ws /= wkspc+        return wkspc `asTypeOf` throwError ""
XMonad/Hooks/XPropManage.hs view
@@ -18,13 +18,11 @@                  ) where  import Data.Char (chr)-import Data.List (concat) import Data.Monoid (mconcat, Endo(..))  import Control.Monad.Trans (lift)  import XMonad-import XMonad.ManageHook ((-->))  -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:@@ -34,7 +32,7 @@ -- > import XMonad.Actions.TagWindows -- > import Data.List ----- > manageHook = xPropManageHook xPropMatches +-- > manageHook = xPropManageHook xPropMatches -- > -- > xPropMatches :: [XPropMatch] -- > xPropMatches = [ ([ (wM_CLASS, any ("gimp"==))], (\w -> float w >> return (W.shift "2")))@@ -71,7 +69,7 @@     where       propToHook (ms, f) = fmap and (mapM mkQuery ms) --> mkHook f       mkQuery (a, tf)    = fmap tf (getQuery a)-      mkHook func        = ask >>= Query . lift . fmap Endo . func +      mkHook func        = ask >>= Query . lift . fmap Endo . func  getProp :: Display -> Window -> Atom -> X ([String]) getProp d w p = do
XMonad/Layout/Accordion.hs view
@@ -7,7 +7,7 @@ -- License     :  BSD -- -- Maintainer  :  glasser@mit.edu--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- LayoutClass that puts non-focused windows in ribbons at the top and bottom@@ -30,8 +30,8 @@ -- -- Then edit your @layoutHook@ by adding the Accordion layout: ----- > myLayouts = Accordion ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = Accordion ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -42,7 +42,7 @@ instance LayoutClass Accordion Window where     pureLayout _ sc ws = zip ups tops ++ [(W.focus ws, mainPane)] ++ zip dns bottoms      where-       ups    = W.up ws+       ups    = reverse $ W.up ws        dns    = W.down ws        (top,  allButTop) = splitVerticallyBy (1%8 :: Ratio Int) sc        (center,  bottom) = splitVerticallyBy (6%7 :: Ratio Int) allButTop
+ XMonad/Layout/AutoMaster.hs view
@@ -0,0 +1,123 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances, FlexibleContexts #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.AutoMaster+-- Copyright   :  (c) 2009 Ilya Portnov+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Ilya Portnov <portnov84@rambler.ru>+-- Stability   :  unstable+-- Portability :  unportable+--+-- Provides layout modifier AutoMaster. It separates screen in two parts -+-- master and slave. Size of slave area automatically changes depending on+-- number of slave windows.+--+-----------------------------------------------------------------------------++module XMonad.Layout.AutoMaster (+                             -- * Usage+                             -- $usage+                             autoMaster+                            ) where+import Control.Monad++import XMonad+import qualified XMonad.StackSet as W+import XMonad.Layout.LayoutModifier++-- $usage+-- This module defines layout modifier named autoMaster. It separates+-- screen in two parts - master and slave. Master windows are arranged+-- in one row, in slave area underlying layout is run. Size of slave area+-- automatically increases when number of slave windows is increasing.+--+-- You can use this module by adding folowing in your @xmonad.hs@:+--+-- > import XMonad.Layout.AutoMaster+--+-- Then add layouts to your layoutHook:+--+-- > myLayoutHook = autoMaster 1 (1/100) Grid ||| ...+--+-- In this example, master area by default contains 1 window (you can+-- change this number in runtime with usual IncMasterN message), changing+-- slave area size with 1/100 on each Shrink/Expand message.++-- | Data type for layout modifier+data AutoMaster a = AutoMaster Int Float Float+    deriving (Read,Show)++instance LayoutModifier AutoMaster Window where+    modifyLayout (AutoMaster k bias _) = autoLayout k bias+    pureMess = autoMess++-- | Handle Shrink/Expand and IncMasterN messages+autoMess :: AutoMaster a -> SomeMessage -> Maybe (AutoMaster a)+autoMess (AutoMaster k bias delta) m = msum [fmap resize (fromMessage m),+                                             fmap incmastern (fromMessage m)]+    where incmastern (IncMasterN d) = AutoMaster (max 1 (k+d)) bias delta+          resize Expand = AutoMaster k (min ( 0.4)  $ bias+delta) delta+          resize Shrink = AutoMaster k (max (-0.4)  $ bias-delta) delta++-- | Main layout function+autoLayout :: (LayoutClass l Window) =>+              Int ->+              Float ->+              W.Workspace WorkspaceId (l Window) Window+              -> Rectangle+              -> X ([(Window, Rectangle)], Maybe (l Window))+autoLayout k bias wksp rect = do+    let stack = W.stack wksp+    let ws = W.integrate' stack+    let n = length ws+    if null ws then+        runLayout wksp rect+        else do+          if (n<=k) then+              return ((divideRow rect ws),Nothing)+              else do+              let master = take k ws+              let filtStack = stack >>= W.filter (\w -> not (w `elem` master))+              wrs <- runLayout (wksp {W.stack = filtStack}) (slaveRect rect n bias)+              return ((divideRow (masterRect rect n bias) master) ++ (fst wrs),+                      snd wrs)++-- | Calculates height of master area, depending on number of windows.+masterHeight :: Int -> Float -> Float+masterHeight n bias = (calcHeight n) + bias+    where calcHeight :: Int -> Float+          calcHeight 1 = 1.0+          calcHeight m = if (m<9) then (43/45) - (fromIntegral m)*(7/90) else (1/3)++-- | Rectangle for master area+masterRect :: Rectangle -> Int -> Float -> Rectangle+masterRect (Rectangle sx sy sw sh) n bias = Rectangle sx sy sw h+    where h = round $ (fromIntegral sh)*(masterHeight n bias)++-- | Rectangle for slave area+slaveRect :: Rectangle -> Int -> Float -> Rectangle+slaveRect (Rectangle sx sy sw sh) n bias = Rectangle sx (sy+mh) sw h+    where mh = round $ (fromIntegral sh)*(masterHeight n bias)+          h  = round $ (fromIntegral sh)*(1-masterHeight n bias)++-- | Divide rectangle between windows+divideRow :: Rectangle -> [a] -> [(a, Rectangle)]+divideRow (Rectangle x y w h) ws = zip ws rects+    where n = length ws+          oneW = fromIntegral w `div` n+          oneRect = Rectangle x y (fromIntegral oneW) h+          rects = take n $ iterate (shiftR (fromIntegral oneW)) oneRect++-- | Shift rectangle right+shiftR :: Position -> Rectangle -> Rectangle+shiftR s (Rectangle x y w h) = Rectangle (x+s) y w h++-- | User interface function+autoMaster :: LayoutClass l a =>+              Int ->      -- Number of master windows+              Float ->    -- Step for which to increment/decrement master area size with Shrink/Expand+              l a ->+              ModifiedLayout AutoMaster l a+autoMaster nmaster delta = ModifiedLayout (AutoMaster nmaster 0 delta)+
XMonad/Layout/BorderResize.hs view
@@ -9,10 +9,20 @@ -- Stability   :  unstable -- Portability :  not portable --+-- This layout modifier will allow to resize windows by dragging their+-- borders with the mouse. However, it only works in layouts or modified+-- layouts that react to the 'SetGeometry' message.+-- "XMonad.Layout.WindowArranger" can be used to create such a setup,+-- but it is probably must useful in a floating layout such as+-- "XMonad.Layout.PositionStoreFloat" with which it has been mainly tested.+-- See the documentation of PositionStoreFloat for a typical usage example.+-- -----------------------------------------------------------------------------  module XMonad.Layout.BorderResize-    ( borderResize+    ( -- * Usage+      -- $usage+      borderResize     , BorderResize (..)     ) where @@ -20,113 +30,164 @@ import XMonad.Layout.Decoration import XMonad.Layout.WindowArranger import XMonad.Util.XUtils-import Control.Monad(when,forM)+import Control.Monad(when)+import qualified Data.Map as M -data BorderInfo = RightSideBorder Window Rectangle-                    | LeftSideBorder Window Rectangle-                    | TopSideBorder Window Rectangle-                    | BottomSideBorder Window Rectangle+-- $usage+-- You can use this module with the following in your+-- @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.BorderResize+-- > myLayout = borderResize (... layout setup that reacts to SetGeometry ...)+-- > main = xmonad defaultConfig { layoutHook = myLayout }+--++type BorderBlueprint = (Rectangle, Glyph, BorderType)++data BorderType = RightSideBorder+                    | LeftSideBorder+                    | TopSideBorder+                    | BottomSideBorder                     deriving (Show, Read, Eq)-type BorderWithRect = (Rectangle, Rectangle, Glyph, BorderInfo)-type BorderWithWin = (Window, BorderInfo)+data BorderInfo = BI { bWin :: Window,+                        bRect :: Rectangle,+                        bType :: BorderType+                     } deriving (Show, Read) -data BorderResize a = BR [BorderWithWin] deriving (Show, Read)+type RectWithBorders = (Rectangle, [BorderInfo]) +data BorderResize a = BR (M.Map Window RectWithBorders) deriving (Show, Read)+ brBorderOffset :: Position brBorderOffset = 5 brBorderSize :: Dimension brBorderSize = 10 -brCursorRightSide :: Glyph-brCursorRightSide = 96-brCursorLeftSide :: Glyph-brCursorLeftSide = 70-brCursorTopSide :: Glyph-brCursorTopSide = 138-brCursorBottomSide :: Glyph-brCursorBottomSide = 16- borderResize :: l a -> ModifiedLayout BorderResize l a-borderResize = ModifiedLayout (BR [])+borderResize = ModifiedLayout (BR M.empty)  instance LayoutModifier BorderResize Window where     redoLayout _       _ Nothing  wrs = return (wrs, Nothing)-    redoLayout (BR borders) _ _ wrs =-        let preparedBorders = for wrs $ \wr -> (wr, prepareBorders wr)-        in do-            mapM_ deleteBorder borders-            newBorders <- forM preparedBorders $ \(wr, (b1, b2, b3, b4)) -> do-                                (b1WR, b1BWW) <- createBorder b1-                                (b2WR, b2BWW) <- createBorder b2-                                (b3WR, b3BWW) <- createBorder b3-                                (b4WR, b4BWW) <- createBorder b4-                                return ([b1WR, b2WR, b3WR, b4WR, wr],-                                        [b1BWW, b2BWW, b3BWW, b4BWW])-            let wrs' = concat $ map fst newBorders-                newBordersSerialized = concat $ map snd newBorders-            return (wrs', Just $ BR newBordersSerialized)-                -- What we return is the original wrs with the new border-                -- windows inserted at the correct positions - this way, the core-                -- will restack the borders correctly.-                -- We also return information about our borders, so that we-                -- can handle events that they receive and destroy them when-                -- they are no longer needed.+    redoLayout (BR wrsLastTime) _ _ wrs = do+            let correctOrder = map fst wrs+                wrsCurrent = M.fromList wrs+                wrsGone = M.difference wrsLastTime wrsCurrent+                wrsAppeared = M.difference wrsCurrent wrsLastTime+                wrsStillThere = M.intersectionWith testIfUnchanged wrsLastTime wrsCurrent+            handleGone wrsGone+            wrsCreated <- handleAppeared wrsAppeared+            let wrsChanged = handleStillThere wrsStillThere+                wrsThisTime = M.union wrsChanged wrsCreated+            return (compileWrs wrsThisTime correctOrder, Just $ BR wrsThisTime)+            -- What we return is the original wrs with the new border+            -- windows inserted at the correct positions - this way, the core+            -- will restack the borders correctly.+            -- We also return information about our borders, so that we+            -- can handle events that they receive and destroy them when+            -- they are no longer needed.+        where+            testIfUnchanged entry@(rLastTime, _) rCurrent =+                if rLastTime == rCurrent+                    then (Nothing, entry)+                    else (Just rCurrent, entry) -    handleMess (BR borders) m-        | Just e <- fromMessage m :: Maybe Event = handleResize borders e >> return Nothing-        | Just Hide             <- fromMessage m = releaseResources >> return (Just $ BR [])-        | Just ReleaseResources <- fromMessage m = releaseResources >> return (Just $ BR [])-        where releaseResources = mapM_ deleteBorder borders+    handleMess (BR wrsLastTime) m+        | Just e <- fromMessage m :: Maybe Event =+            handleResize (createBorderLookupTable wrsLastTime) e >> return Nothing+        | Just _ <- fromMessage m :: Maybe LayoutMessages =+            handleGone wrsLastTime >> return (Just $ BR M.empty)     handleMess _ _ = return Nothing -prepareBorders :: (Window, Rectangle) -> (BorderWithRect, BorderWithRect, BorderWithRect, BorderWithRect)-prepareBorders (w, r@(Rectangle x y wh ht)) =-    ((r, (Rectangle (x + fi wh - brBorderOffset) y brBorderSize ht) , brCursorRightSide     , RightSideBorder w r),-     (r, (Rectangle (x - brBorderOffset) y brBorderSize ht)         , brCursorLeftSide      , LeftSideBorder w r),-     (r, (Rectangle x (y - brBorderOffset) wh brBorderSize)         , brCursorTopSide       , TopSideBorder w r),-     (r, (Rectangle x (y + fi ht - brBorderOffset) wh brBorderSize) , brCursorBottomSide    , BottomSideBorder w r)-    )+compileWrs :: M.Map Window RectWithBorders -> [Window] -> [(Window, Rectangle)]+compileWrs wrsThisTime correctOrder = let wrs = reorder (M.toList wrsThisTime) correctOrder+                                      in concat $ map compileWr wrs -handleResize :: [BorderWithWin] -> Event -> X ()+compileWr :: (Window, RectWithBorders) -> [(Window, Rectangle)]+compileWr (w, (r, borderInfos)) =+    let borderWrs = for borderInfos $ \bi -> (bWin bi, bRect bi)+    in borderWrs ++ [(w, r)]++handleGone :: M.Map Window RectWithBorders -> X ()+handleGone wrsGone = mapM_ deleteWindow borderWins+    where+        borderWins = map bWin . concat . map snd . M.elems $ wrsGone++handleAppeared :: M.Map Window Rectangle -> X (M.Map Window RectWithBorders)+handleAppeared wrsAppeared = do+    let wrs = M.toList wrsAppeared+    wrsCreated <- mapM handleSingleAppeared wrs+    return $ M.fromList wrsCreated++handleSingleAppeared :: (Window, Rectangle) -> X (Window, RectWithBorders)+handleSingleAppeared (w, r) = do+    let borderBlueprints = prepareBorders r+    borderInfos <- mapM createBorder borderBlueprints+    return (w, (r, borderInfos))++handleStillThere :: M.Map Window (Maybe Rectangle, RectWithBorders) -> M.Map Window RectWithBorders+handleStillThere wrsStillThere = M.map handleSingleStillThere wrsStillThere++handleSingleStillThere :: (Maybe Rectangle, RectWithBorders) -> RectWithBorders+handleSingleStillThere (Nothing, entry) = entry+handleSingleStillThere (Just rCurrent, (_, borderInfos)) = (rCurrent, updatedBorderInfos)+    where+        changedBorderBlueprints = prepareBorders rCurrent+        updatedBorderInfos = map updateBorderInfo . zip borderInfos $ changedBorderBlueprints+          -- assuming that the four borders are always in the same order++updateBorderInfo :: (BorderInfo, BorderBlueprint) -> BorderInfo+updateBorderInfo (borderInfo, (r, _, _)) = borderInfo { bRect = r }++createBorderLookupTable :: M.Map Window RectWithBorders -> [(Window, (BorderType, Window, Rectangle))]+createBorderLookupTable wrsLastTime = concat $ map processSingleEntry $ M.toList wrsLastTime+    where+        processSingleEntry :: (Window, RectWithBorders) -> [(Window, (BorderType, Window, Rectangle))]+        processSingleEntry (w, (r, borderInfos)) = for borderInfos $ \bi -> (bWin bi, (bType bi, w, r))++prepareBorders :: Rectangle -> [BorderBlueprint]+prepareBorders (Rectangle x y wh ht) =+    [((Rectangle (x + fi wh - brBorderOffset) y brBorderSize ht), xC_right_side , RightSideBorder),+     ((Rectangle (x - brBorderOffset) y brBorderSize ht)        , xC_left_side  , LeftSideBorder),+     ((Rectangle x (y - brBorderOffset) wh brBorderSize)        , xC_top_side   , TopSideBorder),+     ((Rectangle x (y + fi ht - brBorderOffset) wh brBorderSize), xC_bottom_side, BottomSideBorder)+    ]++handleResize :: [(Window, (BorderType, Window, Rectangle))] -> Event -> X () handleResize borders ButtonEvent { ev_window = ew, ev_event_type = et }-    | et == buttonPress = do-        case (lookup ew borders) of-            Just (RightSideBorder hostWin (Rectangle hx hy _ hht)) -> do-                mouseDrag (\x _ -> do-                             let nwh = max 1 $ fi (x - hx)-                                 rect = Rectangle hx hy nwh hht-                             focus hostWin-                             when (x - hx > 0) $ sendMessage (SetGeometry rect)) (focus hostWin)-            Just (LeftSideBorder hostWin (Rectangle hx hy hwh hht)) -> do-                mouseDrag (\x _ -> do-                             let nx = max 0 $ min (hx + fi hwh) $ x-                                 nwh = max 1 $ hwh + fi (hx - x)-                                 rect = Rectangle nx hy nwh hht-                             focus hostWin-                             when (x < hx + fi hwh) $ sendMessage (SetGeometry rect)) (focus hostWin)-            Just (TopSideBorder hostWin (Rectangle hx hy hwh hht)) -> do-                mouseDrag (\_ y -> do-                             let ny = max 0 $ min (hy + fi hht) $ y-                                 nht = max 1 $ hht + fi (hy - y)-                                 rect = Rectangle hx ny hwh nht-                             focus hostWin-                             when (y < hy + fi hht) $ sendMessage (SetGeometry rect)) (focus hostWin)-            Just (BottomSideBorder hostWin (Rectangle hx hy hwh _)) -> do-                mouseDrag (\_ y -> do-                             let nht = max 1 $ fi (y - hy)-                                 rect = Rectangle hx hy hwh nht-                             focus hostWin-                             when (y - hy > 0) $ sendMessage (SetGeometry rect)) (focus hostWin)-            Nothing -> return ()+    | et == buttonPress, Just edge <- lookup ew borders =+    case edge of+        (RightSideBorder, hostWin, (Rectangle hx hy _ hht)) ->+            mouseDrag (\x _ -> do+                            let nwh = max 1 $ fi (x - hx)+                                rect = Rectangle hx hy nwh hht+                            focus hostWin+                            when (x - hx > 0) $ sendMessage (SetGeometry rect)) (focus hostWin)+        (LeftSideBorder, hostWin, (Rectangle hx hy hwh hht)) ->+            mouseDrag (\x _ -> do+                            let nx = max 0 $ min (hx + fi hwh) $ x+                                nwh = max 1 $ hwh + fi (hx - x)+                                rect = Rectangle nx hy nwh hht+                            focus hostWin+                            when (x < hx + fi hwh) $ sendMessage (SetGeometry rect)) (focus hostWin)+        (TopSideBorder, hostWin, (Rectangle hx hy hwh hht)) ->+            mouseDrag (\_ y -> do+                            let ny = max 0 $ min (hy + fi hht) $ y+                                nht = max 1 $ hht + fi (hy - y)+                                rect = Rectangle hx ny hwh nht+                            focus hostWin+                            when (y < hy + fi hht) $ sendMessage (SetGeometry rect)) (focus hostWin)+        (BottomSideBorder, hostWin, (Rectangle hx hy hwh _)) ->+            mouseDrag (\_ y -> do+                            let nht = max 1 $ fi (y - hy)+                                rect = Rectangle hx hy hwh nht+                            focus hostWin+                            when (y - hy > 0) $ sendMessage (SetGeometry rect)) (focus hostWin) handleResize _ _ = return () -createBorder :: BorderWithRect -> X (((Window, Rectangle), BorderWithWin))-createBorder (_, borderRect, borderCursor, borderInfo) = do+createBorder :: BorderBlueprint -> X (BorderInfo)+createBorder (borderRect, borderCursor, borderType) = do     borderWin <- createInputWindow borderCursor borderRect-    return ((borderWin, borderRect), (borderWin, borderInfo))--deleteBorder :: BorderWithWin -> X ()-deleteBorder (borderWin, _) = deleteWindow borderWin+    return BI { bWin = borderWin, bRect = borderRect, bType = borderType }  createInputWindow :: Glyph -> Rectangle -> X Window createInputWindow cursorGlyph r = withDisplay $ \d -> do@@ -151,3 +212,13 @@  for :: [a] -> (a -> b) -> [b] for = flip map++reorder :: (Eq a) => [(a, b)] -> [a] -> [(a, b)]+reorder wrs order =+    let ordered = concat $ map (pickElem wrs) order+        rest = filter (\(w, _) -> not (w `elem` order)) wrs+    in ordered ++ rest+    where+        pickElem list e = case (lookup e list) of+                                Just result -> [(e, result)]+                                Nothing -> []
XMonad/Layout/BoringWindows.hs view
@@ -6,7 +6,7 @@ -- Copyright   :  (c) 2008  David Roundy <droundy@darcs.net> -- License     :  BSD3-style (see LICENSE) ----- Maintainer  :  none+-- Maintainer  :  Adam Vogt <vogt.adam@gmail.com> -- Stability   :  unstable -- Portability :  unportable --@@ -31,10 +31,8 @@ import XMonad(Typeable, LayoutClass, Message, X, fromMessage,               sendMessage, windows, withFocused, Window) import Control.Applicative((<$>))-import Control.Monad(Monad(return, (>>))) import Data.List((\\), union)-import Data.Maybe(Maybe(..), maybe, fromMaybe, listToMaybe,-                  maybeToList)+import Data.Maybe(fromMaybe, listToMaybe, maybeToList) import qualified Data.Map as M import qualified XMonad.StackSet as W @@ -46,13 +44,14 @@ -- -- Then edit your @layoutHook@ by adding the layout modifier: ----- > myLayouts = boringWindows (Full ||| etc..)--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = boringWindows (Full ||| etc..)+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- Then to your keybindings, add: ----- > , ((modMask, xK_j), focusUp)--- > , ((modMask, xk_k), focusDown)+-- > , ((modm, xK_j), focusUp)+-- > , ((modm, xK_k), focusDown)+-- > , ((modm, xK_m), focusMaster) -- -- For more detailed instructions on editing the layoutHook see: --@@ -120,7 +119,7 @@                             do windows $ W.modify'                                             $ skipBoring W.focusDown' -- wiggle focus to make sure                                             . skipBoring W.focusUp'   -- no boring window gets the focus-                                            . W.focusMaster'+                                            . focusMaster'                                return Nothing         where skipBoring f st = fromMaybe st $ listToMaybe                                 $ filter ((`notElem` W.focus st:bs) . W.focus)@@ -129,3 +128,9 @@               bs = concat $ cbs:maybeToList lbs ++ M.elems nbs               rjl = return . Just . Left     handleMessOrMaybeModifyIt _ _ = return Nothing++-- | Variant of 'focusMaster' that works on a+-- 'Stack' rather than an entire 'StackSet'.+focusMaster' :: W.Stack a -> W.Stack a+focusMaster' c@(W.Stack _ [] _) = c+focusMaster' (W.Stack t ls rs) = W.Stack x [] (xs ++ t : rs) where (x:xs) = reverse ls
+ XMonad/Layout/ButtonDecoration.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}+----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.ButtonDecoration+-- Copyright   :  (c) Jan Vornberger 2009+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de+-- Stability   :  unstable+-- Portability :  not portable+--+-- A decoration that includes small buttons on both ends which invoke+-- various actions when clicked on: Show a window menu (see+-- "XMonad.Actions.WindowMenu"), minimize, maximize or close the window.+--+-- Note: For maximizing and minimizing to actually work, you will need+-- to integrate "XMonad.Layout.Maximize" and "XMonad.Layout.Minimize" into your+-- setup.  See the documentation of those modules for more information.+--+-----------------------------------------------------------------------------++module XMonad.Layout.ButtonDecoration+    ( -- * Usage:+      -- $usage+      buttonDeco+    ) where++import XMonad+import XMonad.Layout.Decoration+import XMonad.Layout.DecorationAddons++-- $usage+-- You can use this module with the following in your+-- @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.DecorationAddons+-- > import XMonad.Layout.ButtonDecoration+--+-- Then edit your @layoutHook@ by adding the ButtonDecoration to+-- your layout:+--+-- > myL = buttonDeco shrinkText defaultThemeWithButtons (layoutHook defaultConfig)+-- > main = xmonad defaultConfig { layoutHook = myL }+--++buttonDeco :: (Eq a, Shrinker s) => s -> Theme+           -> l a -> ModifiedLayout (Decoration ButtonDecoration s) l a+buttonDeco s c = decoration s c $ NFD True++data ButtonDecoration a = NFD Bool deriving (Show, Read)++instance Eq a => DecorationStyle ButtonDecoration a where+    describeDeco _ = "ButtonDeco"+    decorationCatchClicksHook _ mainw dFL dFR = titleBarButtonHandler mainw dFL dFR+    decorationAfterDraggingHook _ (mainw, _) decoWin = focus mainw >> handleScreenCrossing mainw decoWin >> return ()
XMonad/Layout/CenteredMaster.hs view
@@ -3,15 +3,15 @@ -- | -- Module      :  XMonad.Layout.CenteredMaster -- Copyright   :  (c) 2009 Ilya Portnov--- License     :  GNU GPL v3 or any later+-- License     :  BSD-style (see xmonad/LICENSE) -- -- Maintainer  :  Ilya Portnov <portnov84@rambler.ru> -- Stability   :  unstable -- Portability :  unportable ----- Two layout modifiers. centerMaster places master window at center, --- on top of all other windows, which are managed by base layout. --- topRightMaster is similar, but places master window in top right corner +-- Two layout modifiers. centerMaster places master window at center,+-- on top of all other windows, which are managed by base layout.+-- topRightMaster is similar, but places master window in top right corner -- instead of center. -- -----------------------------------------------------------------------------@@ -30,22 +30,22 @@  -- $usage -- This module defines two new layout modifiers: centerMaster and topRightMaster.--- centerMaster places master window at center of screen, on top of others. +-- centerMaster places master window at center of screen, on top of others. -- All other windows in background are managed by base layout. -- topRightMaster is like centerMaster, but places master window in top right corner instead of center.--- +-- -- Yo can use this module by adding folowing in your @xmonad.hs@: -- -- > import XMonad.Layout.CenteredMaster--- +-- -- Then add layouts to your layoutHook:--- +-- -- > myLayoutHook = centerMaster Grid ||| ...  -- | Function that decides where master window should be placed type Positioner = Rectangle -> Rectangle --- | Data type for LayoutModifier +-- | Data type for LayoutModifier data CenteredMaster a = CenteredMaster deriving (Read,Show)  instance LayoutModifier CenteredMaster Window where@@ -56,12 +56,12 @@ instance LayoutModifier TopRightMaster Window where   modifyLayout TopRightMaster = applyPosition (topRight (3/7) (1/2)) --- | Modifier that puts master window in center, other windows in background +-- | Modifier that puts master window in center, other windows in background -- are managed by given layout centerMaster :: LayoutClass l a => l a -> ModifiedLayout CenteredMaster l a centerMaster = ModifiedLayout CenteredMaster --- | Modifier that puts master window in top right corner, other windows in background +-- | Modifier that puts master window in top right corner, other windows in background -- are managed by given layout topRightMaster :: LayoutClass l a => l a -> ModifiedLayout TopRightMaster l a topRightMaster = ModifiedLayout TopRightMaster
XMonad/Layout/Circle.hs view
@@ -31,8 +31,8 @@ -- -- Then edit your @layoutHook@ by adding the Circle layout: ----- > myLayouts = Circle ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = Circle ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --
+ XMonad/Layout/Column.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.Column+-- Copyright   :  (c) 2009 Ilya Portnov+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Ilya Portnov <portnov84@rambler.ru>+-- Stability   :  unstable+-- Portability :  unportable+--+-- Provides Column layout that places all windows in one column. Windows+-- heights are calculated from equation: H1/H2 = H2/H3 = ... = q, where q is+-- given. With Shrink/Expand messages you can change the q value.+--+-----------------------------------------------------------------------------++module XMonad.Layout.Column (+                             -- * Usage+                             -- $usage+                             Column (..)+                            ) where+import XMonad+import qualified XMonad.StackSet as W++-- $usage+-- This module defines layot named Column. It places all windows in one+-- column. Windows heights are calculated from equation: H1/H2 = H2/H3 = ... =+-- q, where `q' is given (thus, windows heights are members of geometric+-- progression). With Shrink/Expand messages one can change the `q' value.+--+-- You can use this module by adding folowing in your @xmonad.hs@:+--+-- > import XMonad.Layout.Column+--+-- Then add layouts to your layoutHook:+--+-- > myLayoutHook = Column 1.6 ||| ...+--+-- In this example, each next window will have height 1.6 times less then+-- previous window.++data Column a = Column Float deriving (Read,Show)++instance LayoutClass Column a where+    pureLayout = columnLayout+    pureMessage = columnMessage++columnMessage :: Column a -> SomeMessage -> Maybe (Column a)+columnMessage (Column q) m = fmap resize (fromMessage m)+    where resize Shrink = Column (q-0.1)+          resize Expand = Column (q+0.1)++columnLayout :: Column a -> Rectangle -> W.Stack a -> [(a,Rectangle)]+columnLayout (Column q) rect stack = zip ws rects+    where ws = W.integrate stack+          n = length ws+          heights = map (xn n rect q) [1..n]+          ys = [fromIntegral $ sum $ take k heights | k <- [0..n-1]]+          rects = map (mkRect rect) $ zip heights ys++mkRect :: Rectangle -> (Dimension,Position) -> Rectangle+mkRect (Rectangle xs ys ws _) (h,y) = Rectangle xs (ys+fromIntegral y) ws h++xn :: Int -> Rectangle -> Float -> Int -> Dimension+xn n (Rectangle _ _ _ h) q k = if q==1 then+                                  h `div` (fromIntegral n)+                               else+                                  round ((fromIntegral h)*q^(n-k)*(1-q)/(1-q^n))++
XMonad/Layout/Combo.hs view
@@ -51,10 +51,10 @@ -- each sublayout. To do this, use "XMonad.Layout.WindowNavigation", -- and add the following key bindings (or something similar): ----- >    , ((modMask x .|. controlMask .|. shiftMask, xK_Right), sendMessage $ Move R)--- >    , ((modMask x .|. controlMask .|. shiftMask, xK_Left ), sendMessage $ Move L)--- >    , ((modMask x .|. controlMask .|. shiftMask, xK_Up   ), sendMessage $ Move U)--- >    , ((modMask x .|. controlMask .|. shiftMask, xK_Down ), sendMessage $ Move D)+-- >    , ((modm .|. controlMask .|. shiftMask, xK_Right), sendMessage $ Move R)+-- >    , ((modm .|. controlMask .|. shiftMask, xK_Left ), sendMessage $ Move L)+-- >    , ((modm .|. controlMask .|. shiftMask, xK_Up   ), sendMessage $ Move U)+-- >    , ((modm .|. controlMask .|. shiftMask, xK_Down ), sendMessage $ Move D) -- -- For detailed instruction on editing the key binding see -- "XMonad.Doc.Extending#Editing_key_bindings".
XMonad/Layout/ComboP.hs view
@@ -27,7 +27,7 @@ import Data.Maybe ( isJust ) import Control.Monad import XMonad hiding (focus)-import XMonad.StackSet ( integrate, Workspace (..), Stack(..) )+import XMonad.StackSet ( Workspace (..), Stack(..) ) import XMonad.Layout.WindowNavigation import XMonad.Util.WindowProperties import qualified XMonad.StackSet as W@@ -53,15 +53,15 @@ -- the property will go into the first part, all others will go into the second -- part. It supports @Move@ messages as 'combineTwo' does, but it also introduces -- 'SwapWindow' message which sends focused window to the other part. It is--- required becase @Move@ commands don't work when one of the parts is empty.+-- required because @Move@ commands don't work when one of the parts is empty. -- To use it, import \"XMonad.Layout.WindowNavigation\", and add the following key -- bindings (or something similar): ----- >    , ((modMask x .|. controlMask .|. shiftMask, xK_Right), sendMessage $ Move R)--- >    , ((modMask x .|. controlMask .|. shiftMask, xK_Left ), sendMessage $ Move L)--- >    , ((modMask x .|. controlMask .|. shiftMask, xK_Up   ), sendMessage $ Move U)--- >    , ((modMask x .|. controlMask .|. shiftMask, xK_Down ), sendMessage $ Move D)--- >    , ((modMask x .|. controlMask .|. shiftMask, xK_s    ), sendMessage $ SwapWindow)+-- >    , ((modm .|. controlMask .|. shiftMask, xK_Right), sendMessage $ Move R)+-- >    , ((modm .|. controlMask .|. shiftMask, xK_Left ), sendMessage $ Move L)+-- >    , ((modm .|. controlMask .|. shiftMask, xK_Up   ), sendMessage $ Move U)+-- >    , ((modm .|. controlMask .|. shiftMask, xK_Down ), sendMessage $ Move D)+-- >    , ((modm .|. controlMask .|. shiftMask, xK_s    ), sendMessage $ SwapWindow) -- -- For detailed instruction on editing the key binding see -- "XMonad.Doc.Extending#Editing_key_bindings".
XMonad/Layout/Cross.hs view
@@ -28,8 +28,8 @@ -- -- Then edit your @layoutHook@ by adding one of the Cross layouts: ----- > myLayouts =  simpleCross ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout =  simpleCross ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } --  -- apply a factor to a Rectangle Dimension
XMonad/Layout/Decoration.hs view
@@ -1,9 +1,8 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- for deriving Typeable-{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-} ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Layout.Decoration--- Copyright   :  (c) 2007 Andrea Rossato+-- Copyright   :  (c) 2007 Andrea Rossato, 2009 Jan Vornberger -- License     :  BSD-style (see xmonad/LICENSE) -- -- Maintainer  :  andrea.rossato@unibz.it@@ -22,33 +21,28 @@     , Decoration     , DecorationMsg (..)     , DecorationStyle (..)-    , DecorationState (..)     , DefaultDecoration (..)-    , isInStack, isVisible, isInvisible, isWithin, fi, lookFor+    , Shrinker (..), DefaultShrinker+    , shrinkText, CustomShrink ( CustomShrink ), shrinkWhile+    , isInStack, isVisible, isInvisible, isWithin, fi+    , findWindowByDecoration     , module XMonad.Layout.LayoutModifier-    , module XMonad.Layout.DecorationUtils     ) where +import Control.Monad (when) import Data.Maybe import Data.List+import Foreign.C.Types(CInt)  import XMonad import qualified XMonad.StackSet as W import XMonad.Hooks.UrgencyHook-import XMonad.Layout.DecorationUtils import XMonad.Layout.LayoutModifier import XMonad.Layout.WindowArranger (WindowArrangerMsg (..), diff, listFromList)-import XMonad.Layout.Minimize-import XMonad.Layout.Maximize import XMonad.Util.NamedWindows (getName) import XMonad.Util.Invisible import XMonad.Util.XUtils import XMonad.Util.Font-import XMonad.PositionStore-import XMonad.Hooks.ManageDocks-import XMonad.Actions.WindowMenu-import Control.Applicative((<$>))-import Foreign.C.Types(CInt)  -- $usage -- This module is intended for layout developers, who want to decorate@@ -84,6 +78,7 @@           , fontName            :: String    -- ^ Font name           , decoWidth           :: Dimension -- ^ Maximum width of the decorations (if supported by the 'DecorationStyle')           , decoHeight          :: Dimension -- ^ Height of the decorations+          , windowTitleAddons   :: [(String, Align)] -- ^ Extra text to appear in a window's title bar           } deriving (Show, Read)  -- | The default xmonad 'Theme'.@@ -101,23 +96,9 @@           , fontName            = "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"           , decoWidth           = 200           , decoHeight          = 20+          , windowTitleAddons   = []           } -minimizeButtonOffset :: Int-minimizeButtonOffset = 48--maximizeButtonOffset :: Int-maximizeButtonOffset = 25--closeButtonOffset :: Int-closeButtonOffset = 10--buttonSize :: Int-buttonSize = 10--data DecoClickAction = WindowMenu | MinimizeButton | MaximizeButton | CloseButton | Dragging-                        deriving (Show)- -- | A 'Decoration' layout modifier will handle 'SetTheme', a message -- to dynamically change the decoration 'Theme'. data DecorationMsg = SetTheme Theme deriving ( Typeable )@@ -130,7 +111,7 @@ -- 'Just'. data DecorationState =     DS { decos :: [(OrigWin,DecoWin)]-       , decoFont  :: XMonadFont+       , font  :: XMonadFont        } type DecoWin = (Maybe Window, Maybe Rectangle) type OrigWin = (Window,Rectangle)@@ -162,16 +143,25 @@     decorationEventHook :: ds a -> DecorationState -> Event -> X ()     decorationEventHook ds s e = handleMouseFocusDrag ds s e +    -- | A hook that can be used to catch the cases when the user+    -- clicks on the decoration. If you return True here, the click event+    -- will be considered as dealt with and no further processing will take place.+    decorationCatchClicksHook :: ds a+                              -> Window+                              -> Int    -- ^ distance from the left where the click happened on the decoration+                              -> Int    -- ^ distance from the right where the click happened on the decoration+                              -> X Bool+    decorationCatchClicksHook _ _ _ _ = return False++    -- | This hook is called while a window is dragged using the decoration.+    -- The hook can be overwritten if a different way of handling the dragging+    -- is required.     decorationWhileDraggingHook :: ds a -> CInt -> CInt -> (Window, Rectangle) -> Position -> Position -> X ()     decorationWhileDraggingHook _ ex ey (mainw, r) x y = handleDraggingInProgress ex ey (mainw, r) x y +    -- | This hoook is called after a window has been dragged using the decoration.     decorationAfterDraggingHook :: ds a -> (Window, Rectangle) -> Window -> X ()-    decorationAfterDraggingHook ds (mainw, r) decoWin = focus mainw-                                                        >> handleScreenCrossing mainw decoWin-                                                        >>= decorationAfterDraggingHookAddon ds (mainw, r)--    decorationAfterDraggingHookAddon :: ds a -> (Window, Rectangle) -> Bool -> X ()-    decorationAfterDraggingHookAddon _ _ _ = return ()+    decorationAfterDraggingHook _ds (mainw, _r) _decoWin = focus mainw      -- | The pure version of the main method, 'decorate'.     pureDecoration :: ds a -> Dimension -> Dimension -> Rectangle@@ -273,7 +263,7 @@            processState s = do let ndwrs = decos s                               showDecos (map snd ndwrs)-                              updateDecos sh t (decoFont s) ndwrs+                              updateDecos sh t (font s) ndwrs                               return (dwrs_to_wrs ndwrs, Just (Decoration (I (Just (s {decos = ndwrs}))) sh t ds))      handleMess (Decoration (I (Just s@(DS {decos = dwrs}))) sh t ds) m@@ -300,6 +290,8 @@     , Just i <- w `elemIndex` (catMaybes $ map (fst . snd) dwrs) = updateDeco sh t fs (dwrs !! i) handleEvent _ _ _ _ = return () +-- | Mouse focus and mouse drag are handled by the same function, this+-- way we can start dragging unfocused windows too. handleMouseFocusDrag :: (DecorationStyle ds a) => ds a -> DecorationState -> Event -> X () handleMouseFocusDrag ds (DS dwrs _) ButtonEvent { ev_window     = ew                                                 , ev_event_type = et@@ -308,28 +300,12 @@     | et == buttonPress     , Just ((mainw,r), (_, decoRectM)) <- lookFor ew dwrs = do         let Just (Rectangle dx _ dwh _) = decoRectM-            distFromRight = fi dwh - (ex - fi dx)             distFromLeft = ex - fi dx-            action = if (fi distFromLeft <= 3 * buttonSize)-                        then WindowMenu-                     else if (fi distFromRight >= closeButtonOffset &&-                              fi distFromRight <= closeButtonOffset + buttonSize)-                                 then CloseButton-                     else if (fi distFromRight >= maximizeButtonOffset &&-                              fi distFromRight <= maximizeButtonOffset + (2 * buttonSize))-                                then MaximizeButton-                     else if (fi distFromRight >= minimizeButtonOffset &&-                              fi distFromRight <= minimizeButtonOffset + buttonSize)-                                then MinimizeButton-                     else Dragging-        case action of-            WindowMenu -> focus mainw >> windowMenu-            CloseButton -> focus mainw >> kill-            MinimizeButton -> focus mainw >> sendMessage (MinimizeWin mainw)-            MaximizeButton -> focus mainw >> sendMessage (maximizeRestore mainw)-            Dragging -> mouseDrag (\x y -> focus mainw-                                           >> decorationWhileDraggingHook ds ex ey (mainw, r) x y)-                                    (decorationAfterDraggingHook ds (mainw, r) ew)+            distFromRight = fi dwh - (ex - fi dx)+        dealtWith <- decorationCatchClicksHook ds mainw (fi distFromLeft) (fi distFromRight)+        when (not dealtWith) $ do+            mouseDrag (\x y -> focus mainw >> decorationWhileDraggingHook ds ex ey (mainw, r) x y)+                        (decorationAfterDraggingHook ds (mainw, r) ew) handleMouseFocusDrag _ _ _ = return ()  handleDraggingInProgress :: CInt -> CInt -> (Window, Rectangle) -> Position -> Position -> X ()@@ -340,48 +316,6 @@                          (rect_height r)     sendMessage $ SetGeometry rect -handleScreenCrossing :: Window -> Window -> X Bool-handleScreenCrossing w decoWin = withDisplay $ \d -> do-    root <- asks theRoot-    (_, _, _, px, py, _, _, _) <- io $ queryPointer d root-    ws <- gets windowset-    sc <- fromMaybe (W.current ws) <$> pointScreen (fi px) (fi py)-    maybeWksp <- screenWorkspace $ W.screen sc-    let targetWksp = maybeWksp >>= \wksp -> -                        W.findTag w ws >>= \currentWksp ->-                        if (currentWksp /= wksp)-                            then Just wksp-                            else Nothing-    case targetWksp of-        Just wksp -> do-                        -- find out window under cursor on target workspace-                        -- apparently we have to switch to the workspace first-                        -- to make this work, which unforunately introduces some flicker-                        windows $ \ws' -> W.view wksp ws'-                        (_, _, selWin, _, _, _, _, _) <- io $ queryPointer d root--                        -- adjust PositionStore-                        let oldScreenRect = screenRect . W.screenDetail $ W.current ws-                            newScreenRect = screenRect . W.screenDetail $ sc-                        {-- somewhat ugly hack to get proper ScreenRect,-                            creates unwanted inter-dependencies-                            TODO: get ScreenRects in a proper way --}-                        oldScreenRect' <- fmap ($ oldScreenRect) (calcGap [U,D,L,R])-                        newScreenRect' <- fmap ($ newScreenRect) (calcGap [U,D,L,R])-                        wa <- io $ getWindowAttributes d decoWin-                        modifyPosStore (\ps ->-                            posStoreMove ps w (fi $ wa_x wa) (fi $ wa_y wa)-                                oldScreenRect' newScreenRect')--                        -- set focus correctly so the window will be inserted-                        -- at the correct position on the target workspace-                        -- and then shift the window-                        windows $ \ws' -> W.shiftWin wksp w . W.focusWindow selWin $ ws'--                        -- return True to signal that screen crossing has taken place-                        return True-        Nothing -> return False- -- | Given a window and the state, if a matching decoration is in the -- state return it with its ('Maybe') 'Rectangle'. lookFor :: Window -> [(OrigWin,DecoWin)] -> Maybe (OrigWin,(Window,Maybe Rectangle))@@ -390,6 +324,9 @@ lookFor w ((_, (Nothing, _)):dwrs) = lookFor w dwrs lookFor _ [] = Nothing +findWindowByDecoration :: Window -> DecorationState -> Maybe (OrigWin,(Window,Maybe Rectangle))+findWindowByDecoration w ds = lookFor w (decos ds)+ -- | Initialize the 'DecorationState' by initializing the font -- structure and by creating the needed decorations. initState :: DecorationStyle ds Window => Theme -> ds Window -> Rectangle@@ -403,7 +340,7 @@ releaseResources :: DecorationState -> X () releaseResources s = do   deleteDecos (map snd $ decos s)-  releaseXMF  (decoFont s)+  releaseXMF  (font s)  -- | Create the decoration windows of a list of windows and their -- rectangles, by calling the 'decorate' method of the@@ -425,7 +362,7 @@                        createNewWindow r mask (inactiveColor t) True  showDecos :: [DecoWin] -> X ()-showDecos = showWindows . catMaybes . map fst+showDecos = showWindows . catMaybes . map fst . filter (isJust . snd)  hideDecos :: [DecoWin] -> X () hideDecos = hideWindows . catMaybes . map fst@@ -454,10 +391,8 @@   let s = shrinkIt sh   name <- shrinkWhile s (\n -> do size <- io $ textWidthXMF dpy fs n                                   return $ size > fromIntegral wh - fromIntegral (ht `div` 2)) (show nw)-  let (als, strs) = ([AlignLeft, AlignCenter, AlignRightOffset minimizeButtonOffset,-                        AlignRightOffset maximizeButtonOffset, AlignRightOffset closeButtonOffset]-                    ,[" (M)"    , name      , "_"                                  ,-                        "[]"               , "X"])+  let als = AlignCenter : map snd (windowTitleAddons t)+      strs = name : map fst (windowTitleAddons t)   paintAndWrite dw fs wh ht 1 bc borderc tc bc als strs updateDeco _ _ _ (_,(Just w,Nothing)) = hideWindow w updateDeco _ _ _ _ = return ()@@ -488,3 +423,30 @@     , x + fi w <= rx + fi rw     , y + fi h <= ry + fi rh = True     | otherwise              = False++shrinkWhile :: (String -> [String]) -> (String -> X Bool) -> String -> X String+shrinkWhile sh p x = sw $ sh x+    where sw [n] = return n+          sw [] = return ""+          sw (n:ns) = do+                        cond <- p n+                        if cond+                          then sw ns+                          else return n++data CustomShrink = CustomShrink+instance Show CustomShrink where show _ = ""+instance Read CustomShrink where readsPrec _ s = [(CustomShrink,s)]++class (Read s, Show s) => Shrinker s where+    shrinkIt :: s -> String -> [String]++data DefaultShrinker = DefaultShrinker+instance Show DefaultShrinker where show _ = ""+instance Read DefaultShrinker where readsPrec _ s = [(DefaultShrinker,s)]+instance Shrinker DefaultShrinker where+    shrinkIt _ "" = [""]+    shrinkIt s cs = cs : shrinkIt s (init cs)++shrinkText :: DefaultShrinker+shrinkText = DefaultShrinker
+ XMonad/Layout/DecorationAddons.hs view
@@ -0,0 +1,123 @@+----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.DecorationAddons+-- Copyright   :  (c) Jan Vornberger 2009+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de+-- Stability   :  unstable+-- Portability :  not portable+--+-- Various stuff that can be added to the decoration. Most of it+-- is intended to be used by other modules. See+-- "XMonad.Layout.ButtonDecoration" for a module that makes use of this.+--+-----------------------------------------------------------------------------++module XMonad.Layout.DecorationAddons (+                                    titleBarButtonHandler+                                   ,defaultThemeWithButtons+                                   ,handleScreenCrossing+                                   ) where++import XMonad+import qualified XMonad.StackSet as W+import XMonad.Layout.Decoration+import XMonad.Actions.WindowMenu+import XMonad.Layout.Minimize+import XMonad.Layout.Maximize+import XMonad.Hooks.ManageDocks+import XMonad.Util.Font+import XMonad.Util.PositionStore++import Control.Applicative((<$>))+import Data.Maybe+import qualified Data.Set as S++minimizeButtonOffset :: Int+minimizeButtonOffset = 48++maximizeButtonOffset :: Int+maximizeButtonOffset = 25++closeButtonOffset :: Int+closeButtonOffset = 10++buttonSize :: Int+buttonSize = 10++-- | A function intended to be plugged into the 'decorationCatchClicksHook' of a decoration.+-- It will intercept clicks on the buttons of the decoration and invoke the associated action.+-- To actually see the buttons, you will need to use a theme that includes them.+-- See 'defaultThemeWithButtons' below.+titleBarButtonHandler :: Window -> Int -> Int -> X Bool+titleBarButtonHandler mainw distFromLeft distFromRight = do+    let action = if (fi distFromLeft <= 3 * buttonSize)+                        then focus mainw >> windowMenu >> return True+                  else if (fi distFromRight >= closeButtonOffset &&+                           fi distFromRight <= closeButtonOffset + buttonSize)+                              then focus mainw >> kill >> return True+                  else if (fi distFromRight >= maximizeButtonOffset &&+                           fi distFromRight <= maximizeButtonOffset + (2 * buttonSize))+                             then focus mainw >> sendMessage (maximizeRestore mainw) >> return True+                  else if (fi distFromRight >= minimizeButtonOffset &&+                           fi distFromRight <= minimizeButtonOffset + buttonSize)+                             then focus mainw >> sendMessage (MinimizeWin mainw) >> return True+                  else return False+    action++-- | Intended to be used together with 'titleBarButtonHandler'. See above.+defaultThemeWithButtons :: Theme+defaultThemeWithButtons = defaultTheme {+                            windowTitleAddons = [ (" (M)", AlignLeft)+                                                , ("_"   , AlignRightOffset minimizeButtonOffset)+                                                , ("[]"  , AlignRightOffset maximizeButtonOffset)+                                                , ("X"   , AlignRightOffset closeButtonOffset)+                                                ]+                            }++-- | A function intended to be plugged into the 'decorationAfterDraggingHook' of a decoration.+-- It will check if the window has been dragged onto another screen and shift it there.+-- The PositionStore is also updated accordingly, as this is designed to be used together+-- with "XMonad.Layout.PositionStoreFloat".+handleScreenCrossing :: Window -> Window -> X Bool+handleScreenCrossing w decoWin = withDisplay $ \d -> do+    root <- asks theRoot+    (_, _, _, px, py, _, _, _) <- io $ queryPointer d root+    ws <- gets windowset+    sc <- fromMaybe (W.current ws) <$> pointScreen (fi px) (fi py)+    maybeWksp <- screenWorkspace $ W.screen sc+    let targetWksp = maybeWksp >>= \wksp ->+                        W.findTag w ws >>= \currentWksp ->+                        if (currentWksp /= wksp)+                            then Just wksp+                            else Nothing+    case targetWksp of+        Just wksp -> do+                        -- find out window under cursor on target workspace+                        -- apparently we have to switch to the workspace first+                        -- to make this work, which unforunately introduces some flicker+                        windows $ \ws' -> W.view wksp ws'+                        (_, _, selWin, _, _, _, _, _) <- io $ queryPointer d root++                        -- adjust PositionStore+                        let oldScreenRect = screenRect . W.screenDetail $ W.current ws+                            newScreenRect = screenRect . W.screenDetail $ sc+                        {-- somewhat ugly hack to get proper ScreenRect,+                            creates unwanted inter-dependencies+                            TODO: get ScreenRects in a proper way --}+                        oldScreenRect' <- fmap ($ oldScreenRect) (calcGap $ S.fromList [minBound .. maxBound])+                        newScreenRect' <- fmap ($ newScreenRect) (calcGap $ S.fromList [minBound .. maxBound])+                        wa <- io $ getWindowAttributes d decoWin+                        modifyPosStore (\ps ->+                            posStoreMove ps w (fi $ wa_x wa) (fi $ wa_y wa)+                                oldScreenRect' newScreenRect')++                        -- set focus correctly so the window will be inserted+                        -- at the correct position on the target workspace+                        -- and then shift the window+                        windows $ \ws' -> W.shiftWin wksp w . W.focusWindow selWin $ ws'++                        -- return True to signal that screen crossing has taken place+                        return True+        Nothing -> return False
XMonad/Layout/DecorationMadness.hs view
@@ -94,7 +94,6 @@  import XMonad.Layout.Accordion import XMonad.Layout.Circle-import XMonad.Layout.ResizeScreen import XMonad.Layout.WindowArranger import XMonad.Layout.SimpleFloat @@ -127,8 +126,8 @@ -- up the key bindings, please read the documentation of -- "XMonad.Layout.WindowArranger" ----- The deafult theme can be dynamically change with the xmonad theme--- selector. See "XMonad.Prompt.Theme". For more themse, look at+-- The default theme can be dynamically change with the xmonad theme+-- selector. See "XMonad.Prompt.Theme". For more themes, look at -- "XMonad.Util.Themes"  -- $circle@@ -541,12 +540,12 @@ -- -- <http://code.haskell.org/~arossato/xmonadShots/floatSimpleSimple.png> floatSimpleSimple :: (Show a, Eq a) => ModifiedLayout (Decoration SimpleDecoration DefaultShrinker)-	             (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a+                 (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a floatSimpleSimple = simpleFloat  floatSimple :: (Show a, Eq a, Shrinker s) => s -> Theme ->                ModifiedLayout (Decoration SimpleDecoration s)-	      (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a+          (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a floatSimple = simpleFloat'  -- | This version is decorated with the 'DefaultDecoration' style.@@ -555,14 +554,14 @@ -- -- <http://code.haskell.org/~arossato/xmonadShots/floatSimpleDefault.png> floatSimpleDefault :: (Show a, Eq a) => ModifiedLayout (Decoration DefaultDecoration DefaultShrinker)-	              (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a+                  (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a floatSimpleDefault = decoration shrinkText defaultTheme DefaultDecoration (mouseResize $ windowArrangeAll $ SF 20)  -- | Same as 'floatSimpleDefault', but with the possibility of setting a -- custom shrinker and a custom theme. floatDefault :: (Show a, Eq a, Shrinker s) => s -> Theme ->                 ModifiedLayout (Decoration DefaultDecoration s)-	       (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a+           (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a floatDefault s t = decoration s t DefaultDecoration (mouseResize $ windowArrangeAll $ SF (decoHeight t))  -- | This version is decorated with the 'DwmStyle'. Note that this is@@ -572,14 +571,14 @@ -- -- <http://code.haskell.org/~arossato/xmonadShots/floatSimpleDwmStyle.png> floatSimpleDwmStyle :: (Show a, Eq a) => ModifiedLayout (Decoration DwmStyle DefaultShrinker)-	               (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a+                   (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a floatSimpleDwmStyle = decoration shrinkText defaultTheme Dwm (mouseResize $ windowArrangeAll $ SF 20)  -- | Same as 'floatSimpleDwmStyle', but with the possibility of setting a -- custom shrinker and a custom theme. floatDwmStyle :: (Show a, Eq a, Shrinker s) => s -> Theme ->                  ModifiedLayout (Decoration DwmStyle s)-	        (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a+            (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a floatDwmStyle s t = decoration s t Dwm (mouseResize $ windowArrangeAll $ SF (decoHeight t))  -- | This version is decorated with the 'TabbedDecoration' style.@@ -589,12 +588,12 @@ -- -- <http://code.haskell.org/~arossato/xmonadShots/floatSimpleTabbed.png> floatSimpleTabbed :: (Show a, Eq a) => ModifiedLayout (Decoration TabBarDecoration DefaultShrinker)-	             (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a+                 (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a floatSimpleTabbed = tabBar shrinkText defaultTheme Top (mouseResize $ windowArrangeAll $ SF 20)  -- | Same as 'floatSimpleTabbed', but with the possibility of setting a -- custom shrinker and a custom theme. floatTabbed :: (Show a, Eq a, Shrinker s) => s -> Theme ->                ModifiedLayout (Decoration TabBarDecoration s)-	      (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a+          (ModifiedLayout MouseResize (ModifiedLayout WindowArranger SimpleFloat)) a floatTabbed s t = tabBar s t Top (mouseResize $ windowArrangeAll $ SF (decoHeight t))
− XMonad/Layout/DecorationUtils.hs
@@ -1,45 +0,0 @@--------------------------------------------------------------------------------- |--- Module      :  XMonad.Layout.DecorationUtils--- Copyright   :  (c) 2007 Andrea Rossato--- License     :  BSD-style (see xmonad/LICENSE)------ Maintainer  :  andrea.rossato@unibz.it--- Stability   :  unstable--- Portability :  unportable-----------------------------------------------------------------------------------module XMonad.Layout.DecorationUtils-    ( Shrinker (..), DefaultShrinker-    , shrinkText, CustomShrink ( CustomShrink ), shrinkWhile-    ) where--import XMonad--shrinkWhile :: (String -> [String]) -> (String -> X Bool) -> String -> X String-shrinkWhile sh p x = sw $ sh x-    where sw [n] = return n-          sw [] = return ""-          sw (n:ns) = do-                        cond <- p n-                        if cond-                          then sw ns-                          else return n--data CustomShrink = CustomShrink-instance Show CustomShrink where show _ = ""-instance Read CustomShrink where readsPrec _ s = [(CustomShrink,s)]--class (Read s, Show s) => Shrinker s where-    shrinkIt :: s -> String -> [String]--data DefaultShrinker = DefaultShrinker-instance Show DefaultShrinker where show _ = ""-instance Read DefaultShrinker where readsPrec _ s = [(DefaultShrinker,s)]-instance Shrinker DefaultShrinker where-    shrinkIt _ "" = [""]-    shrinkIt s cs = cs : shrinkIt s (init cs)--shrinkText :: DefaultShrinker-shrinkText = DefaultShrinker
XMonad/Layout/Dishes.hs view
@@ -21,7 +21,6 @@                               Dishes (..)                             ) where -import Data.List import XMonad import XMonad.StackSet (integrate) import Control.Monad (ap)@@ -33,8 +32,8 @@ -- -- Then edit your @layoutHook@ by adding the Dishes layout: ----- > myLayouts = Dishes 2 (1/6) ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = Dishes 2 (1/6) ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --
XMonad/Layout/DragPane.hs view
@@ -1,5 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-}  ----------------------------------------------------------------------------- -- |@@ -8,7 +7,7 @@ --                    David Roundy <droundy@darcs.net>, --                    Andrea Rossato <andrea.rossato@unibz.it> -- License     :  BSD3-style (see LICENSE)--- +-- -- Maintainer  :  Andrea Rossato <andrea.rossato@unibz.it> -- Stability   :  unstable -- Portability :  unportable@@ -30,7 +29,7 @@ import XMonad import Data.Unique -import qualified XMonad.StackSet as W +import qualified XMonad.StackSet as W import XMonad.Util.Invisible import XMonad.Util.XUtils @@ -41,8 +40,8 @@ -- -- Then edit your @layoutHook@ by adding the DragPane layout: ----- > myLayouts = dragPane Horizontal 0.1 0.5 ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = dragPane Horizontal 0.1 0.5 ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -57,8 +56,8 @@ dragPane :: DragType -> Double -> Double -> DragPane a dragPane t x y = DragPane (I Nothing) t x y -data DragPane a = -    DragPane (Invisible Maybe (Window,Rectangle,Int)) DragType Double Double +data DragPane a =+    DragPane (Invisible Maybe (Window,Rectangle,Int)) DragType Double Double              deriving ( Show, Read )  data DragType = Horizontal | Vertical deriving ( Show, Read )@@ -87,7 +86,7 @@ handleMess _ _ = return Nothing  handleEvent :: DragPane a -> Event -> X ()-handleEvent (DragPane (I (Just (win,r,ident))) ty _ _) +handleEvent (DragPane (I (Just (win,r,ident))) ty _ _)             (ButtonEvent {ev_window = thisw, ev_subwindow = thisbw, ev_event_type = t })     | t == buttonPress && thisw == win || thisbw == win  = do   mouseDrag (\ex ey -> do@@ -115,12 +114,12 @@               [] -> case W.down s of                       (next:_) -> [(W.focus s,left),(next,right)]                       [] -> [(W.focus s, r)]-  if length wrs > 1 +  if length wrs > 1      then case mw of-            I (Just (w,_,ident)) -> do +            I (Just (w,_,ident)) -> do                     w' <- deleteWindow w >> newDragWin handr                     return (wrs, Just $ DragPane (I $ Just (w',r',ident)) ty delta split)-            I Nothing -> do +            I Nothing -> do                     w <- newDragWin handr                     i <- io $ newUnique                     return (wrs, Just $ DragPane (I $ Just (w,r',hashUnique i)) ty delta split)
XMonad/Layout/DraggingVisualizer.hs view
@@ -1,4 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- for deriving Typeable+{-# LANGUAGE DeriveDataTypeable, TypeSynonymInstances, MultiParamTypeClasses, FlexibleContexts #-} ---------------------------------------------------------------------------- -- | -- Module      :  XMonad.Layout.DraggingVisualizer@@ -8,6 +8,10 @@ -- Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de -- Stability   :  unstable -- Portability :  not portable+--+-- A helper module to visualize the process of dragging a window by+-- making it follow the mouse cursor. See "XMonad.Layout.WindowSwitcherDecoration"+-- for a module that makes use of this. -- ----------------------------------------------------------------------------- 
+ XMonad/Layout/Drawer.hs view
@@ -0,0 +1,129 @@+{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances, FlexibleContexts #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.Drawer+-- Copyright   :  (c) 2009 Max Rabkin+-- License     :  BSD-style (see xmonad/LICENSE)+--+-- Maintainer  :  max.rabkin@gmail.com+-- Stability   :  unstable+-- Portability :  unportable+--+-- A layout modifier that puts some windows in a "drawer" which retracts and+-- expands depending on whether any window in it has focus.+--+-- Useful for music players, tool palettes, etc.+--+-----------------------------------------------------------------------------++module XMonad.Layout.Drawer+    ( -- * Usage+      -- $usage++      -- * Drawers+      simpleDrawer+    , drawer++      -- * Placing drawers+      -- The drawer can be placed on any side of the screen with these functions+    , onLeft, onTop, onRight, onBottom++    , module XMonad.Util.WindowProperties+    ) where++import XMonad+import XMonad.Layout.LayoutModifier+import XMonad.Util.WindowProperties+import XMonad.StackSet as S+import XMonad.Layout.Reflect++-- $usage+-- To use this module, add the following import to @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.Drawer+--+-- > myLayout = drawer `onTop` (Tall 1 0.03 0.5) ||| Full ||| RandomOtherLayout...+-- >     where+-- >         drawer = simpleDrawer 0.01 0.3 (ClassName "Rhythmbox" `Or` ClassName "Xchat")+-- >+-- > main = xmonad defaultConfig { layoutHook = myLayout }+--+-- This will place the Rhythmbox and Xchat windows in at the top of the screen+-- only when using the 'Tall' layout.  See "XMonad.Util.WindowProperties" for+-- more information on selecting windows.++data Drawer l a = Drawer Rational Rational Property (l a)+    deriving (Read, Show)++-- | filter : filterM :: partition : partitionM+partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a], [a])+partitionM _ [] = return ([], [])+partitionM f (x:xs) = do+    b <- f x+    (ys, zs) <- partitionM f xs+    return $ if b+                then (x:ys, zs)+                else (ys, x:zs)++instance (LayoutClass l Window, Read (l Window)) => LayoutModifier (Drawer l) Window where+    modifyLayout (Drawer rs rb p l) ws rect =+        case stack ws of+            Nothing -> runLayout ws rect+            Just stk@(Stack { up=up_, down=down_, S.focus=w }) -> do+                    (upD, upM) <- partitionM (hasProperty p) up_+                    (downD, downM) <- partitionM (hasProperty p) down_+                    b <- hasProperty p w+                    focusedWindow <- gets (fmap S.focus . stack . workspace . current . windowset)++                    let rectD = if b && Just w == focusedWindow then rectB else rectS++                    let (stackD, stackM) = if b+                                            then ( Just $ stk { up=upD, down=downD }+                                                 , mkStack upM downM )+                                            else ( mkStack upD downD+                                                 , Just $ stk { up=upM, down=downM } )++                    (winsD, _) <- runLayout (ws { layout=l, stack=stackD }) rectD+                    (winsM, u') <- runLayout (ws { stack=stackM }) rectM+                    return (winsD ++ winsM, u')+      where+        mkStack [] [] = Nothing+        mkStack xs (y:ys) = Just (Stack { up=xs, S.focus=y, down=ys })+        mkStack (x:xs) ys = Just (Stack { up=xs, S.focus=x, down=ys })++        rectB = rect { rect_width=round $ fromIntegral (rect_width rect) * rb }+        rectS = rectB { rect_x=rect_x rectB - (round $ (rb - rs) * fromIntegral (rect_width rect)) }+        rectM = rect { rect_x=rect_x rect + round (fromIntegral (rect_width rect) * rs)+                     , rect_width=rect_width rect - round (fromIntegral (rect_width rect) * rs) }++type Reflected l = ModifiedLayout Reflect l++-- | Construct a drawer with a simple layout of the windows inside+simpleDrawer :: Rational -- ^ The portion of the screen taken up by the drawer when closed+              -> Rational   -- ^ The portion of the screen taken up by the drawer when open+              -> Property   -- ^ Which windows to put in the drawer+              -> Drawer Tall a+simpleDrawer rs rb p = Drawer rs rb p vertical+    where+        vertical = Tall 0 0 0++-- Export a synonym for the constructor as a Haddock workaround+-- | Construct a drawer with an arbitrary layout for windows inside+drawer ::    Rational   -- ^ The portion of the screen taken up by the drawer when closed+          -> Rational   -- ^ The portion of the screen taken up by the drawer when open+          -> Property   -- ^ Which windows to put in the drawer+          -> (l a)      -- ^ The layout of windows in the drawer+          -> Drawer l a+drawer = Drawer++onLeft :: Drawer l a -> l' a -> ModifiedLayout (Drawer l) l' a+onLeft = ModifiedLayout++onRight :: Drawer l a -> l' a -> Reflected (ModifiedLayout (Drawer l) (Reflected l')) a+onRight d = reflectHoriz . onLeft d . reflectHoriz++onTop :: Drawer l a -> l' a -> Mirror (ModifiedLayout (Drawer l) (Mirror l')) a+onTop d = Mirror . onLeft d . Mirror++onBottom :: Drawer l a -> l' a -> Reflected (Mirror (ModifiedLayout (Drawer l) (Mirror (Reflected l')))) a+onBottom d = reflectVert . onTop d . reflectVert
XMonad/Layout/FixedColumn.hs view
@@ -42,8 +42,8 @@ -- -- Then edit your @layoutHook@ by adding the FixedColumn layout: ----- > myLayouts = FixedColumn 1 20 80 10 ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = FixedColumn 1 20 80 10 ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --
XMonad/Layout/Gaps.hs view
@@ -1,8 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-}---- for now, use -fglasgow-exts for compatibility with ghc 6.6, which chokes--- on some of the LANGUAGE pragmas below-{- LANGUAGE FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances -}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances, PatternGuards #-}  ----------------------------------------------------------------------------- -- |@@ -32,7 +28,7 @@ module XMonad.Layout.Gaps (                                -- * Usage                                -- $usage-                          Direction(..),+                          Direction2D(..),                           GapSpec, gaps, GapMessage(..)                            ) where@@ -40,8 +36,8 @@ import XMonad.Core import Graphics.X11 (Rectangle(..)) -import XMonad.Hooks.ManageDocks (Direction(..)) import XMonad.Layout.LayoutModifier+import XMonad.Util.Types (Direction2D(..))  import Data.List (delete) @@ -58,10 +54,10 @@ -- You can additionally add some keybindings to toggle or modify the gaps, -- for example: ----- > , ((modMask x .|. controlMask, xK_g), sendMessage $ ToggleGaps)  -- toggle all gaps--- > , ((modMask x .|. controlMask, xK_t), sendMessage $ ToggleGap U) -- toggle the top gap--- > , ((modMask x .|. controlMask, xK_w), sendMessage $ IncGap R 5)  -- increment the right-hand gap--- > , ((modMask x .|. controlMask, xK_q), sendMessage $ DecGap R 5)  -- decrement the right-hand gap+-- > , ((modm .|. controlMask, xK_g), sendMessage $ ToggleGaps)  -- toggle all gaps+-- > , ((modm .|. controlMask, xK_t), sendMessage $ ToggleGap U) -- toggle the top gap+-- > , ((modm .|. controlMask, xK_w), sendMessage $ IncGap R 5)  -- increment the right-hand gap+-- > , ((modm .|. controlMask, xK_q), sendMessage $ DecGap R 5)  -- decrement the right-hand gap -- -- If you want complete control over all gaps, you could include -- something like this in your keybindings, assuming in this case you@@ -83,19 +79,19 @@  -- | A manual gap configuration.  Each side of the screen on which a --   gap is enabled is paired with a size in pixels.-type GapSpec = [(Direction,Int)]+type GapSpec = [(Direction2D,Int)]  -- | The gap state.  The first component is the configuration (which --   gaps are allowed, and their current size), the second is the gaps --   which are currently active.-data Gaps a = Gaps GapSpec [Direction]+data Gaps a = Gaps GapSpec [Direction2D]   deriving (Show, Read)  -- | Messages which can be sent to a gap modifier. data GapMessage = ToggleGaps              -- ^ Toggle all gaps.-                | ToggleGap  !Direction    -- ^ Toggle a single gap.-                | IncGap !Int !Direction    -- ^ Increase a gap by a certain number of pixels.-                | DecGap !Int !Direction    -- ^ Decrease a gap.+                | ToggleGap  !Direction2D    -- ^ Toggle a single gap.+                | IncGap !Int !Direction2D    -- ^ Increase a gap by a certain number of pixels.+                | DecGap !Int !Direction2D    -- ^ Decrease a gap.   deriving (Typeable)  instance Message GapMessage@@ -125,16 +121,16 @@ activeGaps :: Gaps a -> GapSpec activeGaps (Gaps conf cur) = filter ((`elem` cur) . fst) conf -toggleGaps :: GapSpec -> [Direction] -> [Direction]+toggleGaps :: GapSpec -> [Direction2D] -> [Direction2D] toggleGaps conf [] = map fst conf toggleGaps _    _  = [] -toggleGap :: GapSpec -> [Direction] -> Direction -> [Direction]+toggleGap :: GapSpec -> [Direction2D] -> Direction2D -> [Direction2D] toggleGap conf cur d | d `elem` cur            = delete d cur                      | d `elem` (map fst conf) = d:cur                      | otherwise               = cur -incGap :: GapSpec -> Direction -> Int -> GapSpec+incGap :: GapSpec -> Direction2D -> Int -> GapSpec incGap gs d i = map (\(dir,j) -> if dir == d then (dir,max (j+i) 0) else (dir,j)) gs  fi :: (Num b, Integral a) => a -> b
XMonad/Layout/Grid.hs view
@@ -30,14 +30,14 @@ -- -- Then edit your @layoutHook@ by adding the Grid layout: ----- > myLayouts = Grid ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = Grid ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- You can also specify an aspect ratio for Grid to strive for with the -- GridRatio constructor.  For example, if you want Grid to try to make a grid -- four windows wide and three windows tall, you could use ----- > myLayouts = GridRatio (4/3) ||| etc.+-- > myLayout = GridRatio (4/3) ||| etc. -- -- For more detailed instructions on editing the layoutHook see: --
XMonad/Layout/GridVariants.hs view
@@ -51,10 +51,10 @@ -- To be able to change the geometry of the master grid, add something -- like this to your keybindings: ----- > ((modMask .|. shiftMask, xK_equal), sendMessage $ IncMasterCols 1),--- > ((modMask .|. shiftMask, xK_minus), sendMessage $ IncMasterCols (-1)),--- > ((modMask .|. ctrlMask,  xK_equal), sendMessage $ IncMasterRows 1),--- > ((modMask .|. ctrlMask,  xK_minus), sendMessage $ IncMasterRows (-1))+-- > ((modm .|. shiftMask, xK_equal), sendMessage $ IncMasterCols 1),+-- > ((modm .|. shiftMask, xK_minus), sendMessage $ IncMasterCols (-1)),+-- > ((modm .|. controlMask,  xK_equal), sendMessage $ IncMasterRows 1),+-- > ((modm .|. controlMask,  xK_minus), sendMessage $ IncMasterRows (-1))  -- | Grid layout.  The parameter is the desired x:y aspect ratio of windows data Grid a = Grid !Rational
XMonad/Layout/HintedGrid.hs view
@@ -41,13 +41,13 @@ -- -- Then edit your @layoutHook@ by adding the 'Grid' layout: ----- > myLayouts = Grid False ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = Grid False ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- You can also specify an aspect ratio for Grid to strive for with the -- GridRatio constructor: ----- > myLayouts = GridRatio (4/3) False ||| etc.+-- > myLayout = GridRatio (4/3) False ||| etc. -- -- For more detailed instructions on editing the layoutHook see -- "XMonad.Doc.Extending#Editing_the_layout_hook".
XMonad/Layout/IM.hs view
@@ -10,7 +10,7 @@ -- Stability   :  unstable -- Portability :  unportable ----- Layout modfier suitable for workspace with multi-windowed instant messanger+-- Layout modfier suitable for workspace with multi-windowed instant messenger -- (like Psi or Tkabber). -- -----------------------------------------------------------------------------@@ -29,8 +29,6 @@  import XMonad import qualified XMonad.StackSet as S-import Data.List-import XMonad.Layout (splitHorizontallyBy) import XMonad.Layout.Grid import XMonad.Layout.LayoutModifier import XMonad.Util.WindowProperties@@ -45,8 +43,8 @@ -- for managing your chat windows (Grid in this example, another useful choice -- to consider is Tabbed layout). ----- > myLayouts = withIM (1%7) (ClassName "Tkabber") Grid ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = withIM (1%7) (ClassName "Tkabber") Grid ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- Here @1%7@ is the part of the screen which your roster will occupy, -- @ClassName \"Tkabber\"@ tells xmonad which window is actually your roster.
XMonad/Layout/IndependentScreens.hs view
@@ -19,18 +19,22 @@     VirtualWorkspace, PhysicalWorkspace,     workspaces',     withScreens, onCurrentScreen,+    marshallPP,     countScreens,-    marshall, unmarshall+    -- * Converting between virtual and physical workspaces+    -- $converting+    marshall, unmarshall, unmarshallS, unmarshallW,+    marshallWindowSpace, unmarshallWindowSpace ) where  -- for the screen stuff import Control.Arrow hiding ((|||)) import Control.Monad-import Control.Monad.Instances import Data.List import Graphics.X11.Xinerama import XMonad-import XMonad.StackSet hiding (workspaces)+import XMonad.StackSet hiding (filter, workspaces)+import XMonad.Hooks.DynamicLog  -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:@@ -48,13 +52,13 @@ -- to specific workspace names.  In the default configuration, only -- the keybindings for changing workspace do this: ----- > [((m .|. modMask, k), windows $ f i)+-- > [((m .|. modm, k), windows $ f i) -- >     | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9] -- >     , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]] -- -- This should change to ----- > [((m .|. modMask, k), windows $ onCurrentScreen f i)+-- > [((m .|. modm, k), windows $ onCurrentScreen f i) -- >     | (i, k) <- zip (workspaces' conf) [xK_1 .. xK_9] -- >     , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]] --@@ -67,17 +71,24 @@ type VirtualWorkspace  = WorkspaceId type PhysicalWorkspace = WorkspaceId +-- $converting+-- You shouldn't need to use the functions below very much. They are used+-- internally. However, in some cases, they may be useful, and so are exported+-- just in case. In general, the \"marshall\" functions convert the convenient+-- form (like \"web\") you would like to use in your configuration file to the+-- inconvenient form (like \"2_web\") that xmonad uses internally. Similarly,+-- the \"unmarshall\" functions convert in the other direction.+ marshall :: ScreenId -> VirtualWorkspace -> PhysicalWorkspace marshall (S sc) vws = show sc ++ '_':vws -unmarshall :: PhysicalWorkspace -> (ScreenId, VirtualWorkspace)-unmarshall = ((S . read) *** drop 1) . break (=='_')+unmarshall  :: PhysicalWorkspace -> (ScreenId, VirtualWorkspace)+unmarshallS :: PhysicalWorkspace -> ScreenId+unmarshallW :: PhysicalWorkspace -> VirtualWorkspace --- ^ You shouldn't need to use @marshall@ and @unmarshall@ very much.--- They simply convert between the physical and virtual worlds.  For--- example, you might want to use them as part of a status bar--- configuration.  The function @snd . unmarshall@ would discard the--- screen information from an otherwise unsightly workspace name.+unmarshall  = ((S . read) *** drop 1) . break (=='_')+unmarshallS = fst . unmarshall+unmarshallW = snd . unmarshall  workspaces' :: XConfig l -> [VirtualWorkspace] workspaces' = nub . map (snd . unmarshall) . workspaces@@ -102,3 +113,38 @@ -- countScreens :: (MonadIO m, Integral i) => m i countScreens = liftM genericLength . liftIO $ openDisplay "" >>= getScreenInfo++-- | This turns a naive pretty-printer into one that is aware of the+-- independent screens. That is, you can write your pretty printer to behave+-- the way you want on virtual workspaces; this function will convert that+-- pretty-printer into one that first filters out physical workspaces on other+-- screens, then converts all the physical workspaces on this screen to their+-- virtual names.+--+-- For example, if you have handles @hLeft@ and @hRight@ for bars on the left and right screens, respectively, and @pp@ is a pretty-printer function that takes a handle, you could write+--+-- > logHook = let log screen handle = dynamicLogWithPP . marshallPP screen . pp $ handle+-- >           in log 0 hLeft >> log 1 hRight+marshallPP :: ScreenId -> PP -> PP+marshallPP s pp = pp {+    ppCurrent           = ppCurrent         pp . snd . unmarshall,+    ppVisible           = ppVisible         pp . snd . unmarshall,+    ppHidden            = ppHidden          pp . snd . unmarshall,+    ppHiddenNoWindows   = ppHiddenNoWindows pp . snd . unmarshall,+    ppUrgent            = ppUrgent          pp . snd . unmarshall,+    ppSort              = fmap (marshallSort s) (ppSort pp)+    }++marshallSort :: ScreenId -> ([WindowSpace] -> [WindowSpace]) -> ([WindowSpace] -> [WindowSpace])+marshallSort s vSort = pScreens . vSort . vScreens where+    onScreen ws = unmarshallS (tag ws) == s+    vScreens    = map unmarshallWindowSpace . filter onScreen+    pScreens    = map (marshallWindowSpace s)++-- | Convert the tag of the 'WindowSpace' from a 'VirtualWorkspace' to a 'PhysicalWorkspace'.+marshallWindowSpace   :: ScreenId -> WindowSpace -> WindowSpace+-- | Convert the tag of the 'WindowSpace' from a 'PhysicalWorkspace' to a 'VirtualWorkspace'.+unmarshallWindowSpace :: WindowSpace -> WindowSpace++marshallWindowSpace s ws = ws { tag = marshall s  (tag ws) }+unmarshallWindowSpace ws = ws { tag = unmarshallW (tag ws) }
XMonad/Layout/LayoutBuilder.hs view
@@ -5,7 +5,7 @@ -- Copyright   :  (c) 2009 Anders Engstrom <ankaan@gmail.com> -- License     :  BSD3-style (see LICENSE) ----- Maintainer  :  none+-- Maintainer  :  Anders Engstrom <ankaan@gmail.com> -- Stability   :  unstable -- Portability :  unportable --@@ -28,11 +28,8 @@ ) where  import XMonad-import XMonad.Layout import qualified XMonad.StackSet as W-import Graphics.X11.Xlib import Data.Maybe (isJust)-import Control.Monad  -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:@@ -41,18 +38,18 @@ -- -- Then edit your @layoutHook@ by adding something like: ----- > myLayouts = ( (layoutN 1 (relBox 0 0 0.5 1) (Just $ relBox 0 0 1 1) $ simpleTabbed)+-- > myLayout = ( (layoutN 1 (relBox 0 0 0.5 1) (Just $ relBox 0 0 1 1) $ simpleTabbed) -- >             $ (layoutAll (relBox 0.5 0 1 1)                         $ simpleTabbed) -- >             ) |||--- >             ( (layoutN 1       (relBox (1/3) 0 (1/2) 1) (Just $ relBox 0 0 1 1) $ Tall 0 0 0)--- >             $ (layoutR 0.1 0.5 (relBox (2/3) 0 1     1) Nothing                 $ Tall 0 0 0)--- >             $ (layoutAll       (relBox 0     0 (1/3) 1)                         $ Tall 0 0 0)+-- >             ( (layoutN 1       (relBox (1/3) 0 (1/2) 1) (Just $ relBox 0 0 1 1) $ Tall 0 0.01 0.5)+-- >             $ (layoutR 0.1 0.5 (relBox (2/3) 0 1     1) Nothing                 $ Tall 0 0.01 0.5)+-- >             $ (layoutAll       (relBox 0     0 (1/3) 1)                         $ Tall 0 0.01 0.5) -- >             ) ||| -- >             ( (layoutN 1 (absBox (-512-200) 0 512        0) (Just $ relBox 0 0 1 1) $ simpleTabbed) -- >             $ (layoutN 1 (absBox (-200)     0 0          0) Nothing                 $ simpleTabbed) -- >             $ (layoutAll (absBox 0          0 (-512-200) 0)                         $ simpleTabbed)--- >             ) ||| Full ||| etc... --- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- >             ) ||| Full ||| etc...+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- This will produce a layout similar to DragPane, but with the possibility to have multiple windows in the left half -- and tabs that show the available windows. It will also produce a layout similar to ThreeColMid and a special layout@@ -70,8 +67,8 @@ -- -- You may wish to add the following keybindings: ----- >    , ((modMask x .|. shiftMask, xK_h ), sendMessage $ IncLayoutN (-1))--- >    , ((modMask x .|. shiftMask, xK_l ), sendMessage $ IncLayoutN 1)+-- >    , ((modm .|. shiftMask, xK_h ), sendMessage $ IncLayoutN (-1))+-- >    , ((modm .|. shiftMask, xK_l ), sendMessage $ IncLayoutN 1) -- -- For detailed instruction on editing the key binding see: --
XMonad/Layout/LayoutCombinators.hs view
@@ -1,5 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, PatternGuards #-} ----------------------------------------------------------------------------- -- | -- Module       : XMonad.Layout.LayoutCombinators@@ -47,7 +46,7 @@       -- * New layout choice combinator and 'JumpToLayout'       -- $jtl     , (|||)-    , JumpToLayout(JumpToLayout)+    , JumpToLayout(..)     ) where  import Data.Maybe ( isJust, isNothing )@@ -65,8 +64,8 @@ -- Then edit your @layoutHook@ to use the new layout combinators. For -- example: ----- > myLayouts = (Tall 1 (3/100) (1/2) *//* Full)  ||| (Tall 1 (3/100) (1/2) ***||** Full) ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = (Tall 1 (3/100) (1/2) *//* Full)  ||| (Tall 1 (3/100) (1/2) ***||** Full) ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the @layoutHook@ see: --@@ -79,7 +78,7 @@ -- -- Then bind some keys to a 'JumpToLayout' message: ----- >   , ((modMask x .|. controlMask, xK_f), sendMessage $ JumpToLayout "Full")  -- jump directly to the Full layout+-- >   , ((modm .|. controlMask, xK_f), sendMessage $ JumpToLayout "Full")  -- jump directly to the Full layout -- -- See below for more detailed documentation. @@ -214,12 +213,12 @@  data NewSelect l1 l2 a = NewSelect Bool (l1 a) (l2 a) deriving ( Read, Show ) -data NoWrap = NextLayoutNoWrap | Wrap deriving ( Read, Show, Typeable )-instance Message NoWrap---- | A message to jump to a particular layout, specified by its---   description string.-data JumpToLayout = JumpToLayout String deriving ( Read, Show, Typeable )+-- |+data JumpToLayout = JumpToLayout String -- ^ A message to jump to a particular layout+                                        -- , specified by its description string..+                  | NextLayoutNoWrap+                  | Wrap+                    deriving ( Read, Show, Typeable ) instance Message JumpToLayout  instance (LayoutClass l1 a, LayoutClass l2 a) => LayoutClass (NewSelect l1 l2) a where
XMonad/Layout/LayoutHints.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}-+{-# LANGUAGE ParallelListComp, PatternGuards #-} ----------------------------------------------------------------------------- -- | -- Module       : XMonad.Layout.LayoutHints@@ -8,7 +8,7 @@ -- -- Maintainer   : none -- Stability    : unstable--- Portability  : portable+-- Portability  : unportable -- -- Make layouts respect size hints. -----------------------------------------------------------------------------@@ -18,17 +18,27 @@       -- $usage       layoutHints     , layoutHintsWithPlacement+    , layoutHintsToCenter     , LayoutHints-    , placeRectangle-    ) where+    )  where -import XMonad hiding ( trace )-import XMonad.Layout.LayoutModifier-import XMonad.Layout.Decoration ( isInStack )+import XMonad(LayoutClass(runLayout), mkAdjust, Window,+              Dimension, Position, Rectangle(Rectangle),D)+import qualified XMonad.StackSet as W -import Control.Applicative ( (<$>) )-import Control.Arrow ( second )+import XMonad.Layout.Decoration(isInStack)+import XMonad.Layout.LayoutModifier(ModifiedLayout(..),+                                    LayoutModifier(modifyLayout, redoLayout, modifierDescription))+import XMonad.Util.Types(Direction2D(..))+import Control.Applicative((<$>))+import Control.Arrow(Arrow((***), first, second))+import Control.Monad(join)+import Data.Function(on)+import Data.List(sortBy) +import Data.Set (Set)+import qualified Data.Set as Set+ -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: --@@ -37,14 +47,18 @@ -- Then edit your @layoutHook@ by adding the 'layoutHints' layout modifier -- to some layout: ----- > myLayouts = layoutHints (Tall 1 (3/100) (1/2))  ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = layoutHints (Tall 1 (3/100) (1/2))  ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- Or, to center the adapted window in its available area: ----- > myLayouts = layoutHintsWithPlacement (0.5, 0.5) (Tall 1 (3/100) (1/2))  +-- > myLayout = layoutHintsWithPlacement (0.5, 0.5) (Tall 1 (3/100) (1/2)) -- >                   ||| Full ||| etc.. --+-- Or, to make a reasonable attempt to eliminate gaps between windows:+--+-- > myLayout = layoutHintsToCenter (Tall 1 (3/100) (1/2))+-- -- For more detailed instructions on editing the layoutHook see: -- -- "XMonad.Doc.Extending#Editing_the_layout_hook"@@ -57,17 +71,28 @@ -- originally assigned area according to the @rx@ and @ry@ parameters. -- (0, 0) places the window at the top left, (1, 0) at the top right, (0.5, 0.5) -- at the center, etc.-layoutHintsWithPlacement :: (LayoutClass l a) => (Double, Double) +layoutHintsWithPlacement :: (LayoutClass l a) => (Double, Double)                          -> l a -> ModifiedLayout LayoutHints l a layoutHintsWithPlacement rs = ModifiedLayout (LayoutHints rs) -data LayoutHints a = LayoutHints (Double, Double) +-- | @layoutHintsToCenter layout@ applies hints, sliding the window to the+-- center of the screen and expanding its neighbors to fill the gaps. Windows+-- are never expanded in a way that increases overlap.+--+-- @layoutHintsToCenter@ only makes one pass at resizing the neighbors of+-- hinted windows, so with some layouts (ex. the arrangement with two 'Mirror'+-- 'Tall' stacked vertically), @layoutHintsToCenter@ may leave some gaps.+-- Simple layouts like 'Tall' are unaffected.+layoutHintsToCenter :: (LayoutClass l a) => l a -> ModifiedLayout LayoutHintsToCenter l a+layoutHintsToCenter = ModifiedLayout LayoutHintsToCenter++data LayoutHints a = LayoutHints (Double, Double)                      deriving (Read, Show)  instance LayoutModifier LayoutHints Window where     modifierDescription _ = "Hinted"     redoLayout _ _ Nothing  xs = return (xs, Nothing)-    redoLayout (LayoutHints al) _ (Just s) xs +    redoLayout (LayoutHints al) _ (Just s) xs         = do xs' <- mapM (\x@(_, r) -> second (placeRectangle al r) <$> applyHint x) xs              return (xs', Nothing)      where@@ -77,10 +102,136 @@             return (w, if isInStack s w then Rectangle a b c' d' else r)  -- | @placeRectangle (rx, ry) r0 r@ will return a new rectangle with the same dimensions--- as @r@, but positioned inside of @r0@ as specified by the (rx, ry) parameters (see +-- as @r@, but positioned inside of @r0@ as specified by the (rx, ry) parameters (see -- 'layoutHintsWithPlacement'). placeRectangle :: RealFrac r => (r, r) -> Rectangle -> Rectangle -> Rectangle placeRectangle (rx, ry) (Rectangle x0 y0 w h) (Rectangle _ _ dx dy)     = Rectangle (align x0 dx w rx) (align y0 dy h ry) dx dy     where align :: RealFrac r => Position -> Dimension -> Dimension -> r -> Position           align z0 dz d r = z0 + truncate (fromIntegral (d - dz) * r)++fitting :: [Rectangle] -> Int+fitting rects = sum $ do+    r <- rects+    return $ length $ filter (touching r) rects++applyOrder :: Rectangle -> [((Window, Rectangle),t)] -> [[((Window, Rectangle),t)]]+applyOrder root wrs = do+    -- perhaps it would just be better to take all permutations, or apply the+    -- resizing multiple times+    f <- [maximum, minimum, sum, sum . map sq]+    return $ sortBy (compare `on` (f . distance)) wrs+    where distFC = uncurry ((+) `on` sq) . pairWise (-) (center root)+          distance = map distFC . corners . snd . fst+          pairWise f (a,b) (c,d) = (f a c, f b d)+          sq = join (*)++data LayoutHintsToCenter a = LayoutHintsToCenter deriving (Read, Show)++instance LayoutModifier LayoutHintsToCenter Window where+    modifyLayout _ ws@(W.Workspace _ _ Nothing) r = runLayout ws r+    modifyLayout _ ws@(W.Workspace _ _ (Just st)) r = do+        (arrs,ol) <- runLayout ws r+        flip (,) ol+            . head . reverse . sortBy (compare `on` (fitting . map snd))+            . map (applyHints st r) . applyOrder r+            <$> mapM (\x -> fmap ((,) x) $ mkAdjust (fst x)) arrs++-- apply hints to first, grow adjacent windows+applyHints :: W.Stack Window -> Rectangle -> [((Window, Rectangle),(D -> D))] -> [(Window, Rectangle)]+applyHints _ _ [] = []+applyHints s root (((w,lrect@(Rectangle a b c d)),adj):xs) =+        let (c',d') = adj (c,d)+            redr = placeRectangle (centerPlacement root lrect :: (Double,Double)) lrect+                    $ if isInStack s w then Rectangle a b c' d' else lrect++            ds = (fromIntegral c - fromIntegral c',fromIntegral d - fromIntegral d')+            growOther' r = growOther ds lrect (freeDirs root lrect) r+            mapSnd f = map (first $ second f)+            next = applyHints s root $ mapSnd growOther' xs+        in (w,redr):next++growOther :: (Position, Position) -> Rectangle -> Set Direction2D -> Rectangle -> Rectangle+growOther ds lrect fds r+    | dirs <- flipDir <$> Set.toList (Set.intersection adj fds)+    , not $ any (uncurry opposite) $ cross dirs =+        foldr (flip grow ds) r dirs+    | otherwise = r+    where+        adj = adjacent lrect  r+        cross xs = [ (a,b) | a <- xs, b <- xs ]++        flipDir :: Direction2D -> Direction2D+        flipDir d = case d of { L -> R; U -> D; R -> L; D -> U }++        opposite :: Direction2D -> Direction2D -> Bool+        opposite x y = flipDir x == y++-- | Leave the opposite edges where they were+grow :: Direction2D -> (Position,Position) -> Rectangle -> Rectangle+grow L (px,_ ) (Rectangle x y w h) = Rectangle (x-px) y (w+fromIntegral px) h+grow U (_ ,py) (Rectangle x y w h) = Rectangle x (y-py) w (h+fromIntegral py)+grow R (px,_ ) (Rectangle x y w h) = Rectangle x y (w+fromIntegral px) h+grow D (_ ,py) (Rectangle x y w h) = Rectangle x y w (h+fromIntegral py)++comparingEdges :: ([Position] -> [Position] -> Bool) -> Rectangle -> Rectangle -> Set Direction2D+comparingEdges surrounds r1 r2 = Set.fromList $ map fst $ filter snd [ (\k -> (dir,k)) $+            any and [[dir `elem` [R,L], allEq [a,c,w,y], [b,d] `surrounds` [x,z]]+                    ,[dir `elem` [U,D], allEq [b,d,x,z], [a,c] `surrounds` [w,y]]]+    | ((a,b),(c,d)) <- edge $ corners r1+    | ((w,x),(y,z)) <- edge $ delay 2 $ corners r2+    | dir <- [U,R,D,L]]+        where edge (x:xs) = zip (x:xs) (xs ++ [x])+              edge [] = []+              delay n xs = drop n xs ++ take n xs+              allEq = all (uncurry (==)) . edge++-- | in what direction is the second window from the first that can expand if the+-- first is shrunk, assuming that the root window is fully covered:+--  one direction for a common edge+--  two directions for a common corner+adjacent :: Rectangle -> Rectangle -> Set Direction2D+adjacent = comparingEdges (all . onClosedInterval)++-- | True whenever two edges touch. not (Set.null $ adjacent x y) ==> touching x y+touching :: Rectangle -> Rectangle -> Bool+touching a b = not . Set.null $ comparingEdges c a b+    where c x y = any (onClosedInterval x) y || any (onClosedInterval y) x++onClosedInterval :: Ord a => [a] -> a -> Bool+onClosedInterval bds x = minimum bds <= x && maximum bds >= x++-- | starting top left going clockwise+corners :: Rectangle -> [(Position, Position)]+corners (Rectangle x y w h) = [(x,y)+                              ,(x+fromIntegral w, y)+                              ,(x+fromIntegral w, y+fromIntegral h)+                              ,(x, y+fromIntegral h)]++center :: Rectangle -> (Position, Position)+center (Rectangle x y w h) = (avg x w, avg y h)+    where avg a b = a + fromIntegral b `div` 2++centerPlacement :: RealFrac r => Rectangle -> Rectangle -> (r, r)+centerPlacement = centerPlacement' clamp+    where clamp n = case signum n of+                            0 -> 0.5+                            1 -> 1+                            _ -> 0++freeDirs :: Rectangle -> Rectangle -> Set Direction2D+freeDirs root = Set.fromList . uncurry (++) . (lr *** ud)+              . centerPlacement' signum root+    where+        lr 1 = [L]+        lr (-1) = [R]+        lr _ = [L,R]+        ud 1 = [U]+        ud (-1) = [D]+        ud _ = [U,D]++centerPlacement' :: (Position -> r) -> Rectangle -> Rectangle -> (r, r)+centerPlacement' cf root assigned+    = (cf $ cx - cwx, cf $ cy - cwy)+    where (cx,cy) = center root+          (cwx,cwy) = center assigned
XMonad/Layout/LayoutModifier.hs view
@@ -1,5 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}  ----------------------------------------------------------------------------- -- |
XMonad/Layout/LayoutScreens.hs view
@@ -10,12 +10,13 @@ -- Stability   :  unstable -- Portability :  unportable --+-- Divide a single screen into multiple screens. -----------------------------------------------------------------------------  module XMonad.Layout.LayoutScreens (                                     -- * Usage                                     -- $usage-                                    layoutScreens, fixedLayout+                                    layoutScreens, layoutSplitScreen, fixedLayout                                    ) where  import XMonad@@ -38,8 +39,8 @@ -- -- Then add some keybindings; for example: ----- >   , ((modMask x .|. shiftMask,                 xK_space), layoutScreens 2 (TwoPane 0.5 0.5))--- >   , ((modMask x .|. controlMask .|. shiftMask, xK_space), rescreen)+-- >   , ((modm .|. shiftMask,                 xK_space), layoutScreens 2 (TwoPane 0.5 0.5))+-- >   , ((modm .|. controlMask .|. shiftMask, xK_space), rescreen) -- -- Another example use would be to handle a scenario where xrandr didn't -- work properly (e.g. a VNC X server in my case) and you want to be able@@ -47,13 +48,14 @@ -- -- > import XMonad.Layout.LayoutScreens ----- >   , ((modMask x .|. shiftMask, xK_space),+-- >   , ((modm .|. shiftMask, xK_space), -- >        layoutScreens 1 (fixedLayout [Rectangle 0 0 1024 768]))--- >   , ((modMask x .|. controlMask .|. shiftMask, xK_space), rescreen)+-- >   , ((modm .|. controlMask .|. shiftMask, xK_space), rescreen) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings". +-- | Modify all screens. layoutScreens :: LayoutClass l Int => Int -> l Int -> X () layoutScreens nscr _ | nscr < 1 = trace $ "Can't layoutScreens with only " ++ show nscr ++ " screens." layoutScreens nscr l =@@ -64,6 +66,20 @@                s:ss = map snd wss            in  ws { W.current = W.Screen x 0 (SD s)                   , W.visible = zipWith3 W.Screen xs [1 ..] $ map SD ss+                  , W.hidden  = ys }++-- | Modify current screen.+layoutSplitScreen :: LayoutClass l Int => Int -> l Int -> X ()+layoutSplitScreen nscr _ | nscr < 1 = trace $ "Can't layoutSplitScreen with only " ++ show nscr ++ " screens."+layoutSplitScreen nscr l =+    do rect <- gets $ screenRect . W.screenDetail . W.current . windowset+       (wss, _) <- runLayout (W.Workspace "" l (Just $ W.Stack { W.focus=1, W.up=[],W.down=[1..nscr-1] })) rect+       windows $ \ws@(W.StackSet { W.current = c, W.visible = vs, W.hidden = hs }) ->+           let (x:xs, ys) = splitAt nscr $ W.workspace c : hs+               s:ss = map snd wss+           in  ws { W.current = W.Screen x (W.screen c) (SD s)+                  , W.visible = (zipWith3 W.Screen xs [(W.screen c+1) ..] $ map SD ss) +++                                map (\v -> if W.screen v>W.screen c then v{W.screen = W.screen v + fromIntegral (nscr-1)} else v) vs                   , W.hidden  = ys }  getWindowRectangle :: Window -> X Rectangle
+ XMonad/Layout/LimitWindows.hs view
@@ -0,0 +1,159 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable, PatternGuards #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.LimitWindows+-- Copyright   :  (c) 2009 Adam Vogt+--                (c) 2009 Max Rabkin -- wrote limitSelect+-- License     :  BSD-style (see xmonad/LICENSE)+--+-- Maintainer  :  vogt.adam@gmail.com+-- Stability   :  unstable+-- Portability :  unportable+--+-- A layout modifier that limits the number of windows that can be shown.+-- See "XMonad.Layout.Minimize" for manually setting hidden windows.+--+-----------------------------------------------------------------------------++module XMonad.Layout.LimitWindows (+    -- * Usage+    -- $usage++    -- * Layout Modifiers+    limitWindows,limitSlice,limitSelect,++    -- * Change the number of windows+    increaseLimit,decreaseLimit,setLimit+    ) where++import XMonad.Layout.LayoutModifier+import XMonad+import qualified XMonad.StackSet as W+import Control.Monad((<=<),guard)+import Control.Applicative((<$>))+import Data.Maybe(fromJust)++-- $usage+-- To use this module, add the following import to @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.LimitWindows+--+-- > myLayout = limitWindows 6 $ Tall 1 0.03 0.5 ||| Full ||| RandomOtherLayout...+-- > main = xmonad defaultConfig { layoutHook = myLayout }+--+-- You may also be interested in dynamically changing the number dynamically,+-- by binding keys to the 'increaseLimit', 'decreaseLimit', or 'setLimit'+-- actions.+--+-- For detailed instructions on editing your key bindings, see+-- "XMonad.Doc.Extending#Editing_key_bindings".+--+-- See also 'XMonad.Layout.BoringWindows.boringAuto' for keybindings that skip+-- the hidden windows.++increaseLimit :: X ()+increaseLimit = sendMessage $ LimitChange succ++decreaseLimit :: X ()+decreaseLimit = sendMessage . LimitChange $ max 1 . pred++setLimit :: Int -> X ()+setLimit tgt = sendMessage . LimitChange $ const tgt++-- | Only display the first @n@ windows.+limitWindows :: Int -> l a -> ModifiedLayout LimitWindows l a+limitWindows n = ModifiedLayout (LimitWindows FirstN n)++-- | Only display @n@ windows around the focused window. This makes sense with+-- layouts that arrange windows linearily, like 'XMonad.Layout.Layout.Accordion'.+limitSlice :: Int -> l a -> ModifiedLayout LimitWindows l a+limitSlice n = ModifiedLayout (LimitWindows Slice n)++-- | Only display the first @m@ windows and @r@ others.+-- The @IncMasterN@ message will change @m@, as well as passing it onto the+-- underlying layout.+limitSelect :: Int -> Int -> l a -> ModifiedLayout Selection l a+limitSelect m r = ModifiedLayout Sel{ nMaster=m, start=m, nRest=r }++data LimitWindows a = LimitWindows SliceStyle Int deriving (Read,Show)++data SliceStyle = FirstN | Slice deriving (Read,Show)++data LimitChange = LimitChange { unLC :: (Int -> Int) } deriving (Typeable)++instance Message LimitChange++instance LayoutModifier LimitWindows a where+     pureMess (LimitWindows s n) =+        fmap (LimitWindows s) . pos <=< (`app` n) . unLC <=< fromMessage+      where pos x   = guard (x>=1)     >> return x+            app f x = guard (f x /= x) >>  return (f x)++     modifyLayout (LimitWindows style n) ws r =+        runLayout ws { W.stack = f n <$> W.stack ws } r+      where f = case style of+                    FirstN -> firstN+                    Slice -> slice++firstN ::  Int -> W.Stack a -> W.Stack a+firstN n st = upfocus $ fromJust $ W.differentiate $ take (max 1 n) $ W.integrate st+    where upfocus = foldr (.) id $ replicate (length (W.up st)) W.focusDown'++-- | A non-wrapping, fixed-size slice of a stack around the focused element+slice ::  Int -> W.Stack t -> W.Stack t+slice n (W.Stack f u d) =+        W.Stack f (take (nu + unusedD) u)+                  (take (nd + unusedU) d)+    where unusedD = max 0 $ nd - length d+          unusedU = max 0 $ nu - length u+          nd = div (n - 1) 2+          nu = uncurry (+) $ divMod (n - 1) 2++data Selection a = Sel { nMaster :: Int, start :: Int, nRest :: Int }+    deriving (Read, Show, Eq)++instance LayoutModifier Selection a where+    modifyLayout s w r =+        runLayout (w { W.stack = updateAndSelect s <$> W.stack w }) r++    pureModifier sel _ stk wins = (wins, update sel <$> stk)++    pureMess sel m+        | Just f <- unLC <$> fromMessage m =+            Just $ sel { nRest = max 0 (f (nMaster sel + nRest sel) - nMaster sel) }+        | Just (IncMasterN n) <- fromMessage m =+            Just $ sel { nMaster = max 0 (nMaster sel + n) }+        | otherwise =+            Nothing++select :: Selection l -> W.Stack a -> W.Stack a+select s stk+    | lups < nMaster s+        = stk { W.down=take (nMaster s - lups - 1) downs +++                    (take (nRest s) . drop (start s - lups - 1) $ downs) }+    | otherwise+        = stk { W.up=reverse (take (nMaster s) ups ++ drop (start s) ups),+                W.down=take ((nRest s) - (lups - start s) - 1) downs }+    where+        downs = W.down stk+        ups = reverse $ W.up stk+        lups = length ups++updateStart :: Selection l -> W.Stack a -> Int+updateStart s stk+    | lups < nMaster s  -- the focussed window is in the master pane+        = start s `min` (lups + ldown - (nRest s) + 1) `max` nMaster s+    | otherwise+        = start s `min` lups+                  `max` (lups - (nRest s) + 1)+                  `min` (lups + ldown - (nRest s) + 1)+                  `max` nMaster s+    where+        lups = length $ W.up stk+        ldown = length $ W.down stk++update :: Selection l -> W.Stack a -> Selection a+update sel stk = sel { start=updateStart sel stk }++updateAndSelect :: Selection l -> W.Stack a -> W.Stack a+updateAndSelect sel stk = select (update sel stk) stk
XMonad/Layout/MagicFocus.hs view
@@ -18,7 +18,9 @@      -- $usage      magicFocus,      promoteWarp,-     promoteWarp'+     promoteWarp',+     followOnlyIf,+     disableFollowOnWS     ) where  import XMonad@@ -37,8 +39,8 @@ -- Then edit your @layoutHook@ by adding the magicFocus layout -- modifier: ----- > myLayouts = magicFocus (Tall 1 (3/100) (1/2)) ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts,+-- > myLayout = magicFocus (Tall 1 (3/100) (1/2)) ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout, -- >                               handleEventHook = promoteWarp } -- -- For more detailed instructions on editing the layoutHook see:@@ -89,3 +91,17 @@             return $ All False           else return $ All True promoteWarp' _ _ = return $ All True++-- | Another event hook to override the focusFollowsMouse and make the pointer+-- only follow if a given condition is satisfied. This could be used to disable+-- focusFollowsMouse only for given workspaces or layouts.+-- Beware that your focusFollowsMouse setting is ignored if you use this event hook.+followOnlyIf :: X Bool -> Event -> X All+followOnlyIf cond e@(CrossingEvent {ev_window = w, ev_event_type = t})+    | t == enterNotify && ev_mode e == notifyNormal+    = whenX cond (focus w) >> return (All False)+followOnlyIf _ _ = return $ All True++-- | Disables focusFollow on the given workspaces:+disableFollowOnWS :: [WorkspaceId] -> X Bool+disableFollowOnWS wses = (`notElem` wses) `fmap` gets (W.currentTag . windowset)
XMonad/Layout/Magnifier.hs view
@@ -1,4 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-}+{-# LANGUAGE DeriveDataTypeable, MultiParamTypeClasses, TypeSynonymInstances, PatternGuards #-} ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Layout.Magnifier@@ -41,8 +41,8 @@ -- Then edit your @layoutHook@ by adding the 'magnifier' layout modifier -- to some layout: ----- > myLayouts = magnifier (Tall 1 (3/100) (1/2))  ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = magnifier (Tall 1 (3/100) (1/2))  ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- By default magnifier increases the focused window's size by 1.5. -- You can also use:@@ -59,11 +59,11 @@ -- Magnifier supports some commands. To use them add something like -- this to your key bindings: ----- >    , ((modMask x .|. controlMask              , xK_plus ), sendMessage MagnifyMore)--- >    , ((modMask x .|. controlMask              , xK_minus), sendMessage MagnifyLess)--- >    , ((modMask x .|. controlMask              , xK_o    ), sendMessage ToggleOff  )--- >    , ((modMask x .|. controlMask .|. shiftMask, xK_o    ), sendMessage ToggleOn   )--- >    , ((modMask x .|. controlMask              , xK_m    ), sendMessage Toggle     )+-- >    , ((modm .|. controlMask              , xK_plus ), sendMessage MagnifyMore)+-- >    , ((modm .|. controlMask              , xK_minus), sendMessage MagnifyLess)+-- >    , ((modm .|. controlMask              , xK_o    ), sendMessage ToggleOff  )+-- >    , ((modm .|. controlMask .|. shiftMask, xK_o    ), sendMessage ToggleOn   )+-- >    , ((modm .|. controlMask              , xK_m    ), sendMessage Toggle     ) -- -- Note that a few other extension modules, such as -- "XMonad.Layout.MultiToggle" and "XMonad.Layout.ToggleLayouts", also
XMonad/Layout/Master.hs view
@@ -47,7 +47,7 @@ -- layout data AddMaster a = AddMaster Rational Rational deriving (Show, Read) --- | Modifier wich converts given layout to a mastered one+-- | Modifier which converts given layout to a mastered one mastered :: (LayoutClass l a) =>        Rational -- ^ @delta@, the ratio of the screen to resize by     -> Rational -- ^ @frac@, what portion of the screen to use for the master window
XMonad/Layout/Maximize.hs view
@@ -1,5 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}  ----------------------------------------------------------------------------- -- |@@ -35,8 +34,8 @@ -- -- Then edit your @layoutHook@ by adding the Maximize layout modifier: ----- > myLayouts = maximize (Tall 1 (3/100) (1/2)) ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = maximize (Tall 1 (3/100) (1/2)) ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -44,7 +43,7 @@ -- -- In the key-bindings, do something like: ----- >        , ((modMask x, xK_backslash), withFocused (sendMessage . maximizeRestore))+-- >        , ((modm, xK_backslash), withFocused (sendMessage . maximizeRestore)) -- >        ... -- -- For detailed instruction on editing the key binding see:
+ XMonad/Layout/MessageControl.hs view
@@ -0,0 +1,126 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.MessageControl+-- Copyright   :  (c) 2008 Quentin Moser+-- License     :  BSD3+--+-- Maintainer  :  <quentin.moser@unifr.ch>+-- Stability   :  unstable+-- Portability :  unportable+--+-- Provides message \"escaping\" and filtering facilities which+-- help control complex nested layouts.+-----------------------------------------------------------------------------++module XMonad.Layout.MessageControl (+                               -- * Usage+                               -- $usage+                            Ignore()+                          , ignore+                          , UnEscape()+                          , unEscape+                          , EscapedMessage(Escape)+                          , escape+                          ) where++import XMonad.Core (Message, SomeMessage(..)+                   , fromMessage, LayoutClass(..))+import XMonad.StackSet (Workspace(..))++import XMonad.Layout.LayoutModifier (LayoutModifier(..), ModifiedLayout(..))++import Data.Typeable (Typeable)+import Control.Applicative ((<$>))+import Control.Arrow (second)++-- $usage+-- You can use this module by importing it into your @~\/.xmonad\/xmonad.hs@ file:+--+-- > import XMonad.Layout.MessageEscape+--+-- Then, if you use a modified layout where the modifier would intercept+-- a message, but you'd want to be able to send it to the inner layout+-- only, add the 'unEscape' modifier to the inner layout like so:+--+-- > import XMonad.Layout.Master (mastered)+-- > import XMonad.Layout.Tabbed (simpleTabbed)+-- > import XMonad.Layout.LayoutCombinators ((|||))+-- >+-- > myLayout = Tall ||| unEscape (mastered 0.01 0.5 $ Full ||| simpleTabbed)+--+-- you can now send a message to the inner layout with+--  @sendMessage $ escape message@, e.g.+--+-- > -- Change the inner layout+-- > ((modm .|. controlMask, xK_space), sendMessage $ escape NextLayout)+--+-- If you want unescaped messages to be handled /only/ by the enclosing+-- layout, use the 'ignore' modifier:+--+-- > myLayout = Tall ||| (ignore NextLayout $ ignore (JumpToLayout "") $+-- >                       unEscape $ mastered 0.01 0.5+-- >                         $ Full ||| simpleTabbed)+--+-- /IMPORTANT NOTE:/ The standard '(|||)' operator from "XMonad.Layout"+-- does not behave correctly with 'ignore'. Make sure you use the one+-- from "XMonad.Layout.LayoutCombinators".++-- | the Ignore layout modifier. Prevents its inner layout from receiving+-- messages of a certain type.++data Ignore m l w = I (l w)+                    deriving (Show, Read)++instance (Message m, LayoutClass l w) => LayoutClass (Ignore m l) w where+    runLayout ws r = second (I <$>) <$> runLayout (unILayout ws) r+        where  unILayout :: Workspace i (Ignore m l w) w -> Workspace i (l w) w+               unILayout w@(Workspace { layout = (I l) }) = w { layout = l }+    handleMessage l@(I l') sm+        = case fromMessageAs sm l of+            Just _ -> return Nothing+            Nothing -> (I <$>) <$> handleMessage l' sm+        where fromMessageAs :: Message m' => SomeMessage -> Ignore m' l w -> Maybe m'+              fromMessageAs a _ = fromMessage a+    description (I l) = "Ignore "++description l++-- | the UnEscape layout modifier. Listens to 'EscapedMessage's and sends+-- their nested message to the inner layout.++data UnEscape w = UE+                deriving (Show, Read)++instance LayoutModifier UnEscape a where+    handleMessOrMaybeModifyIt _ mess+        = return $ case fromMessage mess of+                     Just (Escape mess') -> Just $ Right mess'+                     Nothing -> Nothing+++-- | Data type for an escaped message. Send with 'escape'.++newtype EscapedMessage = Escape SomeMessage+    deriving Typeable++instance Message EscapedMessage+++-- | Creates an 'EscapedMessage'.++escape :: Message m => m -> EscapedMessage+escape = Escape . SomeMessage+++-- | Applies the UnEscape layout modifier to a layout.++unEscape :: LayoutClass l w => l w -> ModifiedLayout UnEscape l w+unEscape l = ModifiedLayout UE l+++-- | Applies the Ignore layout modifier to a layout, blocking+-- all messages of the same type as the one passed as its first argument.++ignore :: (Message m, LayoutClass l w)+          => m -> l w -> (Ignore m l w)+ignore _ l = I l
XMonad/Layout/Minimize.hs view
@@ -1,4 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable+{-# LANGUAGE MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances, FlexibleContexts, PatternGuards #-} ---------------------------------------------------------------------------- -- | -- Module      :  XMonad.Layout.Minimize@@ -9,9 +9,14 @@ -- Stability   :  unstable -- Portability :  not portable --+-- Makes it possible to minimize windows, temporarily removing them+-- from the layout until they are restored.+-- -----------------------------------------------------------------------------  module XMonad.Layout.Minimize (+        -- * Usage+        -- $usage         minimize,         MinimizeMsg(..)     ) where@@ -21,10 +26,45 @@ import XMonad.Layout.LayoutModifier import XMonad.Layout.BoringWindows as BW import Data.List+import qualified Data.Map as M -data Minimize a = Minimize [Window] deriving ( Read, Show )+-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.Minimize+--+-- Then edit your @layoutHook@ by adding the Minimize layout modifier:+--+-- > myLayout = minimize (Tall 1 (3/100) (1/2)) ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout }+--+-- For more detailed instructions on editing the layoutHook see:+--+-- "XMonad.Doc.Extending#Editing_the_layout_hook"+--+-- In the key-bindings, do something like:+--+-- >        , ((modm,               xK_m     ), withFocused (\f -> sendMessage (MinimizeWin f)))+-- >        , ((modm .|. shiftMask, xK_m     ), sendMessage RestoreNextMinimizedWin)+--+-- The first action will minimize the focused window, while the second one will restore+-- the next minimized window.+--+-- For detailed instruction on editing the key binding see:+--+-- "XMonad.Doc.Extending#Editing_key_bindings".+--+-- The module is designed to work together with "XMonad.Layout.BoringWindows" so+-- that minimized windows will be skipped over when switching the focused window with+-- the keyboard. Include 'BW.boringWindows' in your layout hook and see the+-- documentation of "XMonad.Layout.BoringWindows" on how to modify your keybindings.+--+-- Also see "XMonad.Hooks.RestoreMinimized" if you want to be able to restore+-- minimized windows from your taskbar.++data Minimize a = Minimize [Window] (M.Map Window W.RationalRect) deriving ( Read, Show ) minimize :: LayoutClass l Window => l Window -> ModifiedLayout Minimize l Window-minimize = ModifiedLayout $ Minimize []+minimize = ModifiedLayout $ Minimize [] M.empty  data MinimizeMsg = MinimizeWin Window                     | RestoreMinimizedWin Window@@ -33,24 +73,42 @@ instance Message MinimizeMsg  instance LayoutModifier Minimize Window where-    modifierDescription (Minimize _) = "Minimize"+    modifierDescription _ = "Minimize" -    modifyLayout (Minimize minimized) wksp rect = do+    modifyLayout (Minimize minimized _) wksp rect = do         let stack = W.stack wksp             filtStack = stack >>=W.filter (\w -> not (w `elem` minimized))         runLayout (wksp {W.stack = filtStack}) rect -    handleMess (Minimize minimized) m = case fromMessage m of-        Just (MinimizeWin w)-          | not (w `elem` minimized) -> do+    handleMess (Minimize minimized unfloated) m+        | Just (MinimizeWin w) <- fromMessage m, not (w `elem` minimized) = do                 BW.focusDown-                return $ Just $ Minimize (w:minimized)-          | otherwise               -> return Nothing-        Just (RestoreMinimizedWin w) ->-            return $ Just $ Minimize (minimized \\ [w])-        Just (RestoreNextMinimizedWin)-          | not (null minimized)    -> do+                ws <- gets windowset+                case M.lookup w (W.floating ws) of+                  Nothing -> return $ Just $ Minimize (w:minimized) unfloated+                  Just r -> do+                    (windows . W.sink) w+                    return $ Just $ Minimize (w:minimized) (M.insert w r unfloated)+        | Just (RestoreMinimizedWin w) <- fromMessage m =+            case M.lookup w unfloated of+              Nothing -> return $ Just $ Minimize (minimized \\ [w]) unfloated+              Just r -> do+                (windows . (W.float w)) r+                return $ Just $ Minimize (minimized \\ [w]) (M.delete w unfloated)+        | Just RestoreNextMinimizedWin <- fromMessage m =+          if not (null minimized)+            then case M.lookup (head minimized) unfloated of+              Nothing -> do                 focus (head minimized)-                return $ Just $ Minimize (tail minimized)-          | otherwise               -> return Nothing-        _ -> return Nothing+                return $ Just $ Minimize (tail minimized) unfloated+              Just r -> do+                let w = head minimized+                (windows . (W.float w)) r+                focus w+                return $ Just $ Minimize (tail minimized) (M.delete w unfloated)+            else return Nothing+        | Just BW.UpdateBoring <- fromMessage m = do+            ws <- gets (W.workspace . W.current . windowset)+            flip sendMessageWithNoRefresh ws $ BW.Replace "Minimize" minimized+            return Nothing+        | otherwise = return Nothing
XMonad/Layout/Monitor.hs view
@@ -47,14 +47,14 @@ -- and 'rect' should be set here. Also consider setting 'persistent' to True. -- -- Minimal example:---    +-- -- > myMonitor = monitor -- >     { prop = ClassName "SomeClass" -- >     , rect = Rectangle 0 0 40 20 -- rectangle 40x20 in upper left corner--- >     } +-- >     } -- -- More interesting example:---         +-- -- > clock = monitor { -- >      -- Cairo-clock creates 2 windows with the same classname, thus also using title -- >      prop = ClassName "Cairo-clock" `And` Title "MacSlow's Cairo-Clock"@@ -63,7 +63,7 @@ -- >      -- avoid flickering -- >    , persistent = True -- >      -- make the window transparent--- >    , opacity = 0xAAAAAAAA+-- >    , opacity = 0.6 -- >      -- hide on start -- >    , visible = False -- >      -- assign it a name to be able to toggle it independently of others@@ -71,30 +71,30 @@ -- >    } -- -- Add ManageHook to de-manage monitor windows and apply opacity settings.--- +-- -- > manageHook = myManageHook <+> manageMonitor clock--- +-- -- Apply layout modifier.--- --- > myLayouts = ModifiedLayout clock $ tall ||| Full ||| ...--- +--+-- > myLayout = ModifiedLayout clock $ tall ||| Full ||| ...+-- -- After that, if there exists a window with specified properties, it will be -- displayed on top of all /tiled/ (not floated) windows on specified -- position. -- -- It's also useful to add some keybinding to toggle monitor visibility:--- +-- -- > , ((mod1Mask, xK_u     ), broadcastMessage ToggleMonitor >> refresh) -- -- Screenshot: <http://www.haskell.org/haskellwiki/Image:Xmonad-clock.png>  data Monitor a = Monitor-    { prop :: Property   -- ^ property which uniquely identifies monitor window-    , rect :: Rectangle  -- ^ specifies where to put monitor-    , visible :: Bool    -- ^ is it visible by default?-    , name :: String     -- ^ name of monitor (useful when we have many of them)-    , persistent :: Bool -- ^ is it shown on all layouts?-    , opacity :: Integer -- ^ opacity level+    { prop :: Property    -- ^ property which uniquely identifies monitor window+    , rect :: Rectangle   -- ^ specifies where to put monitor+    , visible :: Bool     -- ^ is it visible by default?+    , name :: String      -- ^ name of monitor (useful when we have many of them)+    , persistent :: Bool  -- ^ is it shown on all layouts?+    , opacity :: Rational -- ^ opacity level     } deriving (Read, Show)  -- | Template for 'Monitor' record. At least 'prop' and 'rect' should be@@ -106,7 +106,7 @@     , visible = True     , name = ""     , persistent = False-    , opacity = 0xFFFFFFFF+    , opacity = 1     }  -- | Messages without names affect all monitors. Messages with names affect only@@ -145,7 +145,7 @@             if name mon == n then Just $ mon { visible = False } else Nothing         | Just Hide <- fromMessage mess = do unless (persistent mon) $ withMonitor (prop mon) () hide; return Nothing         | otherwise = return Nothing-        + -- | ManageHook which demanages monitor window and applies opacity settings. manageMonitor :: Monitor a -> ManageHook manageMonitor mon = propertyToQuery (prop mon) --> do
XMonad/Layout/Mosaic.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable #-}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable, PatternGuards #-} ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Layout.Mosaic@@ -17,25 +17,28 @@ module XMonad.Layout.Mosaic (     -- * Usage     -- $usage-    Mosaic(Mosaic)-    ,Aspect(..)-    ,shallower-    ,steeper-    ,growMaster-    ,shrinkMaster+     Aspect(..)+    ,mosaic     ,changeMaster+    ,changeFocused     )     where  import Prelude hiding (sum)  import XMonad(Typeable,-              LayoutClass(doLayout , pureMessage, description), Message,-              fromMessage, splitHorizontallyBy, splitVerticallyBy, Rectangle)-import XMonad.StackSet(integrate)-import Data.Foldable(Foldable(foldMap), sum)-import Data.Monoid(Monoid(mappend, mempty))+              LayoutClass(doLayout, handleMessage, pureMessage, description),+              Message, X, fromMessage, withWindowSet, Resize(..),+              splitHorizontallyBy, splitVerticallyBy, sendMessage, Rectangle)+import qualified XMonad.StackSet as W+import Control.Arrow(second, first)+import Control.Monad(mplus)+import Data.Foldable(Foldable,foldMap, sum)+import Data.Function(on)+import Data.List(sortBy)+import Data.Monoid(Monoid,mempty, mappend) + -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: --@@ -43,20 +46,20 @@ -- -- Then edit your @layoutHook@ by adding the Mosaic layout: ----- > myLayouts = Mosaic (take 5 $ iterate (*0.7) 1) ||| Mosaic [3,1,1,1,1,1] ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = mosaic 2 [3,2] ||| Full ||| etc..+-- > main = xmonad $ defaultConfig { layoutHook = myLayout } ----- Unfortunately, infinite lists break serialization, so don't use them.+-- Unfortunately, infinite lists break serialization, so don't use them. And if+-- the list is too short, it is extended with @++ repeat 1@, which covers the+-- main use case. -- -- To change the choice in aspect ratio and the relative sizes of windows, add -- to your keybindings: -----  > , ((modMask, xK_a), sendMessage Taller)---  > , ((modMask, xK_z), sendMessage Wider)---  > , ((modMask, xK_h), sendMessage Shrink >> sendMessage (SlopeMod shallower))---  > , ((modMask, xK_l), sendMessage Expand >> sendMessage (SlopeMod steeper))+--  > , ((modm, xK_a), sendMessage Taller)+--  > , ((modm, xK_z), sendMessage Wider) -----  > , ((modMask, xK_r), sendMessage Reset)+--  > , ((modm, xK_r), sendMessage Reset) -- -- For more detailed instructions on editing the layoutHook see: --@@ -71,90 +74,93 @@  instance Message Aspect -data Mosaic a-    {- | The relative magnitudes (the sign is ignored) of the rational numbers-     - provided determine the relative areas that the windows receive. The-     - first number represents the size of the master window, the second is for-     - the next window in the stack, and so on. Windows without a list element-     - are hidden.-    -}-    = Mosaic [Rational]-    -- override the aspect? current index, maximum index-    | MosaicSt Bool Rational Int [Rational]-    deriving (Read, Show)+-- | The relative magnitudes (the sign is ignored) of the rational numbers in+-- the second argument determine the relative areas that the windows receive.+-- The first number represents the size of the master window, the second is for+-- the next window in the stack, and so on.+--+-- The list is extended with @++ repeat 1@, so @mosaic 1.5 []@ is like a+-- resizable grid.+--+-- The first parameter is the multiplicative factor to use when responding to+-- the 'Expand' message.+mosaic :: Rational -> [Rational] -> Mosaic a+mosaic = Mosaic Nothing +data Mosaic a = -- | True to override the aspect, current index, maximum index+                Mosaic (Maybe(Bool,Rational,Int)) Rational [Rational] deriving (Read,Show)+ instance LayoutClass Mosaic a where     description = const "Mosaic" -    pureMessage (Mosaic _ss) _ms = Nothing-    pureMessage (MosaicSt _ ix mix ss) ms = fromMessage ms >>= ixMod-        where ixMod Taller | rix >= mix = Nothing-                           | otherwise = Just $ MosaicSt False (succ ix) mix ss-              ixMod Wider  | rix <= 0   = Nothing-                           | otherwise = Just $ MosaicSt False (pred ix) mix ss-              ixMod Reset              = Just $ Mosaic ss-              ixMod (SlopeMod f)       = Just $ MosaicSt False ix mix (f ss)-              rix = round ix+    pureMessage (Mosaic Nothing _ _) _ = Nothing+    pureMessage (Mosaic (Just(_,ix,mix)) delta ss) ms = fromMessage ms >>= ixMod+        where ixMod Taller | round ix >= mix = Nothing+                           | otherwise = Just $ Mosaic (Just(False,succ ix,mix)) delta ss+              ixMod Wider  | round ix <= (0::Integer) = Nothing+                           | otherwise = Just $ Mosaic (Just(False,pred ix,mix)) delta ss+              ixMod Reset              = Just $ Mosaic Nothing delta ss+              ixMod (SlopeMod f)       = Just $ Mosaic (Just(False,ix,mix)) delta (f ss) -    doLayout (Mosaic ss) r st = return (zip (integrate st) rect, newLayout)-        where rects = splits (length $ integrate st) r ss-              lrects = length rects-              rect = rects !! (lrects `div` 2)-              newLayout = Just $ MosaicSt True (fromIntegral lrects / 2) (pred lrects) ss+    handleMessage l@(Mosaic _ delta _) ms+        | Just Expand <- fromMessage ms = changeFocused (*delta) >> return Nothing+        | Just Shrink <- fromMessage ms = changeFocused (/delta) >> return Nothing+        | otherwise = return $ pureMessage l ms -    doLayout (MosaicSt override ix mix ss) r st-                                = return (zip (integrate st) rect, newLayout)-        where rects = splits (length $ integrate st) r ss-              lrects = length rects-              nix = if mix == 0 || override then fromIntegral $ lrects `div` 2-                        else max 0 $ min (fromIntegral $ pred lrects)-                            $ fromIntegral (pred lrects) * ix / fromIntegral mix-              rect = rects !! round nix-              newLayout = Just $ MosaicSt override nix (pred lrects) ss+    doLayout (Mosaic state delta ss) r st = let+        ssExt = zipWith const (ss ++ repeat 1) $ W.integrate st+        rects = splits r ssExt+        nls = length rects+        fi = fromIntegral+        nextIx (ov,ix,mix)+                | mix <= 0 || ov = fromIntegral $ nls `div` 2+                | otherwise = max 0 $ (*fi (pred nls)) $ min 1 $ ix / fi mix+        rect = rects !! maybe (nls `div` 2) round (nextIx `fmap` state)+        state' = fmap (\x@(ov,_,_) -> (ov,nextIx x,pred nls)) state+                    `mplus` Just (True,fromIntegral nls / 2,pred nls)+        ss' = maybe ss (const ss `either` const ssExt) $ zipRemain ss ssExt+        in return (zip (W.integrate st) rect, Just $ Mosaic state' delta ss') +zipRemain :: [a] -> [b] -> Maybe (Either [a] [b])+zipRemain (_:xs) (_:ys) = zipRemain xs ys+zipRemain [] [] = Nothing+zipRemain [] y = Just (Right y)+zipRemain x [] = Just (Left x)+ -- | These sample functions are meant to be applied to the list of window sizes -- through the 'SlopeMod' message.------ Steeper and shallower scale the ratios of successive windows.+changeMaster :: (Rational -> Rational) -> X ()+changeMaster = sendMessage . SlopeMod . onHead++-- | Apply a function to the Rational that represents the currently focused+-- window. ----- growMaster and shrinkMaster just increase and decrease the size of the first--- element, and thus they change the layout very similarily to the standard--- 'Expand' or 'Shrink' for the 'Tall' layout.+-- 'Expand' and 'Shrink' messages are responded to with @changeFocused+-- (*delta)@ or @changeFocused (delta/)@ where @delta@ is the first argument to+-- 'mosaic'. ----- It may be possible to resize the specific focused window; however the same--- result could probably be achieved by promoting it, or moving it to a higher--- place in the list of windows; when you have a decreasing list of window--- sizes, the change in position will also result in a change in size.--steeper :: [Rational] -> [Rational]-steeper [] = []-steeper xs = map (subtract (minimum xs*0.8)) xs--shallower :: [Rational] -> [Rational]-shallower [] = []-shallower xs = map (+(minimum xs*2)) xs--growMaster :: [Rational] -> [Rational]-growMaster = changeMaster 2--shrinkMaster :: [Rational] -> [Rational]-shrinkMaster = changeMaster 0.5+-- This is exported because other functions (ex. @const 1@, @(+1)@) may be+-- useful to apply to the current area.+changeFocused :: (Rational -> Rational) -> X ()+changeFocused f = withWindowSet $ sendMessage . SlopeMod+                    . maybe id (mulIx . length . W.up)+                    . W.stack . W.workspace . W.current+    where mulIx i = uncurry (++) . second (onHead f) . splitAt i --- | Multiply the area of the current master by a specified ratio-changeMaster :: Rational -> [Rational] -> [Rational]-changeMaster _ [] = []-changeMaster f (x:xs) = f*x:xs+onHead :: (a -> a) -> [a] -> [a]+onHead f = uncurry (++) . first (fmap f) . splitAt 1 -splits :: Int -> Rectangle -> [Rational] -> [[Rectangle]]-splits num rect = splitsL rect . makeTree . normalize-                            . map abs . reverse . take num+splits :: Rectangle -> [Rational] -> [[Rectangle]]+splits rect = map (reverse . map snd . sortBy (compare `on` fst))+                . splitsL rect . makeTree snd . zip [1..]+                . normalize . reverse . map abs --- recursively enumerate splits-splitsL :: Rectangle -> Tree Rational -> [[Rectangle]]+splitsL :: Rectangle -> Tree (Int,Rational) -> [[(Int,Rectangle)]] splitsL _rect Empty = []-splitsL rect (Leaf _) = [[rect]]+splitsL rect (Leaf (x,_)) = [[(x,rect)]] splitsL rect (Branch l r) = do-    let mkSplit f = f (sum l / (sum l + sum r)) rect+    let mkSplit f = f ((sumSnd l /) $ sumSnd l + sumSnd r) rect+        sumSnd = sum . fmap snd     (rl,rr) <- map mkSplit [splitVerticallyBy,splitHorizontallyBy]     splitsL rl l `interleave` splitsL rr r @@ -163,38 +169,42 @@ interleave :: [[a]] -> [[a]] -> [[a]] interleave xs ys | lx > ly = zc xs (extend lx ys)                  | otherwise = zc (extend ly xs) ys-    where lx = length xs-          ly = length ys-          zc = zipWith (++)+  where lx = length xs+        ly = length ys+        zc = zipWith (++) -extend :: Int -> [a] -> [a]-extend n pat = do-    (p,e) <- zip pat $ replicate m True ++ repeat False-    [p | e] ++ replicate d p-    where (d,m) = n `divMod` length pat+        extend :: Int -> [a] -> [a]+        extend n pat = do+            (p,e) <- zip pat $ replicate m True ++ repeat False+            [p | e] ++ replicate d p+            where (d,m) = n `divMod` length pat  normalize :: Fractional a => [a] -> [a]-normalize x = let s = sum x-    in map (/s) x+normalize x = let s = sum x in map (/s) x  data Tree a = Branch (Tree a) (Tree a) | Leaf a | Empty-    deriving (Show)  instance Foldable Tree where    foldMap _f Empty = mempty    foldMap f (Leaf x) = f x    foldMap f (Branch l r) = foldMap f l `mappend` foldMap f r +instance Functor Tree where+   fmap f (Leaf x) = Leaf $ f x+   fmap f (Branch l r) = Branch (fmap f l) (fmap f r)+   fmap _ Empty = Empty+ instance Monoid (Tree a) where     mempty = Empty     mappend Empty x = x     mappend x Empty = x     mappend x y = Branch x y -makeTree :: [Rational] -> Tree Rational-makeTree [] = Empty-makeTree [x] = Leaf x-makeTree xs = Branch (makeTree a) (makeTree b)-    where ((a,b),_) = foldr w (([],[]),(0,0)) xs-          w n ((ls,rs),(l,r)) = if l > r then ((ls,n:rs),(l,n+r))-                                        else ((n:ls,rs),(n+l,r))+makeTree ::  (Num a1, Ord a1) => (a -> a1) -> [a] -> Tree a+makeTree _ [] = Empty+makeTree _ [x] = Leaf x+makeTree f xs = Branch (makeTree f a) (makeTree f b)+    where ((a,b),_) = foldr go (([],[]),(0,0)) xs+          go n ((ls,rs),(l,r))+            | l > r     = ((ls,n:rs),(l,f n+r))+            | otherwise = ((n:ls,rs),(f n+l,r))
XMonad/Layout/MosaicAlt.hs view
@@ -1,17 +1,16 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeSynonymInstances #-}+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeSynonymInstances #-}  ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Layout.MosaicAlt -- Copyright   :  (c) 2007 James Webb -- License     :  BSD-style (see xmonad/LICENSE)--- +-- -- Maintainer  :  xmonad#jwebb,sygneca,com -- Stability   :  unstable -- Portability :  unportable ----- A layout which gives each window a specified amount of screen space +-- A layout which gives each window a specified amount of screen space -- relative to the others. Compared to the 'Mosaic' layout, this one -- divides the space in a more balanced way. --@@ -42,8 +41,8 @@ -- -- Then edit your @layoutHook@ by adding the MosaicAlt layout: ----- > myLayouts = MosaicAlt M.empty ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = MosaicAlt M.empty ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -51,11 +50,11 @@ -- -- In the key-bindings, do something like: ----- >     , ((modMask x .|. shiftMask  , xK_a    ), withFocused (sendMessage . expandWindowAlt))--- >     , ((modMask x .|. shiftMask  , xK_z    ), withFocused (sendMessage . shrinkWindowAlt))--- >     , ((modMask x .|. shiftMask  , xK_s    ), withFocused (sendMessage . tallWindowAlt))--- >     , ((modMask x .|. shiftMask  , xK_d    ), withFocused (sendMessage . wideWindowAlt))--- >     , ((modMask x .|. controlMask, xK_space), sendMessage resetAlt)+-- >     , ((modm .|. shiftMask  , xK_a    ), withFocused (sendMessage . expandWindowAlt))+-- >     , ((modm .|. shiftMask  , xK_z    ), withFocused (sendMessage . shrinkWindowAlt))+-- >     , ((modm .|. shiftMask  , xK_s    ), withFocused (sendMessage . tallWindowAlt))+-- >     , ((modm .|. shiftMask  , xK_d    ), withFocused (sendMessage . wideWindowAlt))+-- >     , ((modm .|. controlMask, xK_space), sendMessage resetAlt) -- >     ... -- -- For detailed instruction on editing the key binding see:
XMonad/Layout/MouseResizableTile.hs view
@@ -1,4 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-} ---------------------------------------------------------------------------- -- | -- Module      :  XMonad.Layout.MouseResizableTile@@ -9,9 +9,14 @@ -- Stability   :  unstable -- Portability :  not portable --+-- A layout in the spirit of "XMonad.Layout.ResizableTile", but with the option+-- to use the mouse to adjust the layout.+-- -----------------------------------------------------------------------------  module XMonad.Layout.MouseResizableTile (+                                    -- * Usage+                                    -- $usage                                     mouseResizableTile,                                     mouseResizableTileMirrored,                                     MRTMessage (ShrinkSlave, ExpandSlave)@@ -20,7 +25,38 @@ import XMonad hiding (tile, splitVertically, splitHorizontallyBy) import qualified XMonad.StackSet as W import XMonad.Util.XUtils+import Control.Applicative((<$>)) +-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.MouseResizableTile+--+-- Then edit your @layoutHook@ by adding the MouseResizableTile layout.+-- Either in its normal form or the mirrored version. (The mirror layout modifier+-- will not work correctly here because of the use of the mouse.)+--+-- > myLayout = mouseResizableTile ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout }+--+-- or+--+-- > myLayout = mouseResizableTileMirrored ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout }+--+-- For more detailed instructions on editing the layoutHook see:+--+-- "XMonad.Doc.Extending#Editing_the_layout_hook"+--+-- You may also want to add the following key bindings:+--+-- > , ((modm,               xK_u), sendMessage ShrinkSlave) -- %! Shrink a slave area+-- > , ((modm,               xK_i), sendMessage ExpandSlave) -- %! Expand a slave area+--+-- For detailed instruction on editing the key binding see:+--+-- "XMonad.Doc.Extending#Editing_key_bindings".+ data MRTMessage = SetMasterFraction Rational                     | SetLeftSlaveFraction Int Rational                     | SetRightSlaveFraction Int Rational@@ -54,10 +90,6 @@ mrtDraggerOffset = 3 mrtDraggerSize :: Dimension mrtDraggerSize = 6-mrtHDoubleArrow :: Glyph-mrtHDoubleArrow = 108-mrtVDoubleArrow :: Glyph-mrtVDoubleArrow = 116  mouseResizableTile :: MouseResizableTile a mouseResizableTile = MRT 1 mrtFraction [] [] [] 0 0 False@@ -65,21 +97,23 @@ mouseResizableTileMirrored :: MouseResizableTile a mouseResizableTileMirrored= MRT 1 mrtFraction [] [] [] 0 0 True -instance LayoutClass MouseResizableTile a where+instance LayoutClass MouseResizableTile Window where     doLayout state sr (W.Stack w l r) =         let wins = reverse l ++ w : r             num = length wins             sr' = mirrorAdjust sr (mirrorRect sr)             (rects, preparedDraggers) = tile (nmaster state) (masterFrac state)-                                            ((leftFracs state) ++ repeat mrtFraction)-                                            ((rightFracs state) ++ repeat mrtFraction) sr' num+                                            (leftFracs state ++ repeat mrtFraction)+                                            (rightFracs state ++ repeat mrtFraction) sr' num             rects' = map (mirrorAdjust id mirrorRect . sanitizeRectangle sr') rects         in do             mapM_ deleteDragger $ draggers state-            newDraggers <- mapM (createDragger sr . adjustForMirror (isMirrored state)) preparedDraggers-            return (zip wins rects', Just $ state { draggers = newDraggers,-                                                    focusPos = length l,-                                                    numWindows = length wins })+            (draggerWrs, newDraggers) <- unzip <$> mapM+                                            (createDragger sr . adjustForMirror (isMirrored state))+                                            preparedDraggers+            return (zip wins rects' ++ draggerWrs, Just $ state { draggers = newDraggers,+                                                                  focusPos = length l,+                                                                  numWindows = length wins })         where             mirrorAdjust a b = if (isMirrored state)                                 then b@@ -88,9 +122,9 @@     handleMessage state m         | Just (IncMasterN d) <- fromMessage m =             return $ Just $ state { nmaster = max 0 (nmaster state + d) }-        | Just (Shrink) <- fromMessage m =+        | Just Shrink <- fromMessage m =             return $ Just $ state { masterFrac = max 0 (masterFrac state - mrtDelta) }-        | Just (Expand) <- fromMessage m =+        | Just Expand <- fromMessage m =             return $ Just $ state { masterFrac = min 1 (masterFrac state + mrtDelta) }         | Just ShrinkSlave <- fromMessage m =             return $ Just $ modifySlave state (-mrtDelta)@@ -109,16 +143,17 @@         where releaseResources = mapM_ deleteDragger $ draggers state     handleMessage _ _ = return Nothing -    description _ = "MouseResizableTile"+    description state = mirror "MouseResizableTile"+        where mirror = if isMirrored state then ("Mirror " ++) else id  adjustForMirror :: Bool -> DraggerWithRect -> DraggerWithRect adjustForMirror False dragger = dragger adjustForMirror True (draggerRect, draggerCursor, draggerInfo) =         (mirrorRect draggerRect, draggerCursor', draggerInfo)     where-        draggerCursor' = if (draggerCursor == mrtHDoubleArrow)-                            then mrtVDoubleArrow-                            else mrtHDoubleArrow+        draggerCursor' = if (draggerCursor == xC_sb_h_double_arrow)+                            then xC_sb_v_double_arrow+                            else xC_sb_h_double_arrow  modifySlave :: MouseResizableTile a -> Rational-> MouseResizableTile a modifySlave state delta =@@ -161,7 +196,7 @@ tile nmaster' masterFrac' leftFracs' rightFracs' sr num     | num <= nmaster'       = splitVertically (take (num - 1) leftFracs') sr True 0     | nmaster' == 0         = splitVertically (take (num - 1) rightFracs') sr False 0-    | otherwise             = (leftRects ++ rightRects, [masterDragger] ++ leftDraggers ++ rightDraggers)+    | otherwise             = (leftRects ++ rightRects, masterDragger : leftDraggers ++ rightDraggers)     where ((sr1, sr2), masterDragger) = splitHorizontallyBy masterFrac' sr           (leftRects, leftDraggers) = splitVertically (take (nmaster' - 1) leftFracs') sr1 True 0           (rightRects, rightDraggers) = splitVertically (take (num - nmaster' - 1) rightFracs') sr2 False 0@@ -169,59 +204,50 @@ splitVertically :: RealFrac r => [r] -> Rectangle -> Bool -> Int -> ([Rectangle], [DraggerWithRect]) splitVertically [] r _ _ = ([r], []) splitVertically (f:fx) (Rectangle sx sy sw sh) isLeft num =-    let nextRect = Rectangle sx sy sw (smallh - (div mrtDraggerSize 2))+    let nextRect = Rectangle sx sy sw $ smallh - div mrtDraggerSize 2         (otherRects, otherDragger) = splitVertically fx                                         (Rectangle sx (sy + fromIntegral smallh + mrtDraggerOffset)-                                                    sw (sh - smallh - (div mrtDraggerSize 2)))+                                                    sw (sh - smallh - div mrtDraggerSize 2))                                         isLeft (num + 1)         draggerRect = Rectangle sx (sy + fromIntegral smallh - mrtDraggerOffset) sw mrtDraggerSize         draggerInfo = if isLeft                         then LeftSlaveDragger sy (fromIntegral sh) num                         else RightSlaveDragger sy (fromIntegral sh) num-        nextDragger = (draggerRect, mrtVDoubleArrow, draggerInfo)+        nextDragger = (draggerRect, xC_sb_v_double_arrow, draggerInfo)     in (nextRect : otherRects, nextDragger : otherDragger)   where smallh = floor $ fromIntegral sh * f  splitHorizontallyBy :: RealFrac r => r -> Rectangle -> ((Rectangle, Rectangle), DraggerWithRect)-splitHorizontallyBy f (Rectangle sx sy sw sh) = ((leftHalf, rightHalf), (draggerRect, mrtHDoubleArrow, draggerInfo))+splitHorizontallyBy f (Rectangle sx sy sw sh) = ((leftHalf, rightHalf), (draggerRect, xC_sb_h_double_arrow, draggerInfo))   where leftw = floor $ fromIntegral sw * f-        leftHalf = Rectangle sx sy (leftw - (div mrtDraggerSize 2)) sh+        leftHalf = Rectangle sx sy (leftw - mrtDraggerSize `div` 2) sh         rightHalf = Rectangle (sx + fromIntegral leftw + mrtDraggerOffset) sy-                                (sw - fromIntegral leftw - (div mrtDraggerSize 2)) sh+                                (sw - fromIntegral leftw - mrtDraggerSize `div` 2) sh         draggerRect = Rectangle (sx + fromIntegral leftw - mrtDraggerOffset) sy mrtDraggerSize sh         draggerInfo = MasterDragger sx (fromIntegral sw) -createDragger :: Rectangle -> DraggerWithRect -> X DraggerWithWin+createDragger :: Rectangle -> DraggerWithRect -> X ((Window, Rectangle), DraggerWithWin) createDragger sr (draggerRect, draggerCursor, draggerInfo) = do-        draggerWin <- createInputWindow draggerCursor $ sanitizeRectangle sr draggerRect-        return (draggerWin, draggerInfo)+        let draggerRect' = sanitizeRectangle sr draggerRect+        draggerWin <- createInputWindow draggerCursor draggerRect'+        return ((draggerWin, draggerRect'), (draggerWin, draggerInfo))  deleteDragger :: DraggerWithWin -> X () deleteDragger (draggerWin, _) = deleteWindow draggerWin - handleResize :: [DraggerWithWin] -> Bool -> Event -> X () handleResize draggers' isM ButtonEvent { ev_window = ew, ev_event_type = et }-    | et == buttonPress = do-        case (lookup ew draggers') of-            Just (MasterDragger lowerBound range) -> do-                mouseDrag (\x y -> do-                             let axis = chooseAxis isM x y-                                 fraction = fromIntegral (axis - lowerBound) / range-                             sendMessage (SetMasterFraction fraction)) (return ())-            Just (LeftSlaveDragger lowerBound range num) -> do-                mouseDrag (\x y -> do-                             let axis = chooseAxis isM y x-                                 fraction = fromIntegral (axis - lowerBound) / range-                             sendMessage (SetLeftSlaveFraction num fraction)) (return ())-            Just (RightSlaveDragger lowerBound range num) -> do-                mouseDrag (\x y -> do-                             let axis = chooseAxis isM y x-                                 fraction = fromIntegral (axis - lowerBound) / range-                             sendMessage (SetRightSlaveFraction num fraction)) (return ())-            Nothing -> return ()+    | et == buttonPress, Just x <- lookup ew draggers' = case x of+        MasterDragger     lb r     -> mouseDrag' id   lb r  SetMasterFraction+        LeftSlaveDragger  lb r num -> mouseDrag' flip lb r (SetLeftSlaveFraction num)+        RightSlaveDragger lb r num -> mouseDrag' flip lb r (SetRightSlaveFraction num)     where         chooseAxis isM' axis1 axis2 = if isM' then axis2 else axis1+        mouseDrag' flp lowerBound range msg = flip mouseDrag (return ()) $ \x y -> do+                let axis = flp (chooseAxis isM) x y+                    fraction = fromIntegral (axis - lowerBound) / range+                sendMessage (msg fraction)+ handleResize _ _ _ = return ()  createInputWindow :: Glyph -> Rectangle -> X Window
+ XMonad/Layout/MultiColumns.hs view
@@ -0,0 +1,145 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.MultiColumns+-- Copyright   :  (c) Anders Engstrom <ankaan@gmail.com>+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Anders Engstrom <ankaan@gmail.com>+-- Stability   :  unstable+-- Portability :  unportable+--+-- This layout tiles windows in a growing number of columns. The number of+-- windows in each column can be controlled by messages.+-----------------------------------------------------------------------------++module XMonad.Layout.MultiColumns (+                              -- * Usage+                              -- $usage++                              multiCol+                             ) where++import XMonad+import qualified XMonad.StackSet as W++import Control.Monad++-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.MultiColumns+--+-- Then edit your @layoutHook@ by adding the multiCol layout:+--+-- > myLayouts = multiCol [1] 4 0.01 0.5 ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayouts }+--+-- Or alternatively:+--+-- > myLayouts = Mirror (multiCol [1] 2 0.01 (-0.25)) ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayouts }+--+-- The maximum number of windows in a column can be controlled using the+-- IncMasterN messages and the column containing the focused window will be+-- modified. If the value is 0, all remaining windows will be placed in that+-- column when all columns before that has been filled.+--+-- The size can be set to between 1 and -0.5. If the value is positive, the+-- master column will be of that size. The rest of the screen is split among+-- the other columns. But if the size is negative, it instead indicates the+-- size of all non-master columns and the master column will cover the rest of+-- the screen. If the master column would become smaller than the other+-- columns, the screen is instead split equally among all columns. Therefore,+-- if equal size among all columns are desired, set the size to -0.5.+--+-- For more detailed instructions on editing the layoutHook see:+--+-- "XMonad.Doc.Extending#Editing_the_layout_hook"++-- | Layout constructor.+multiCol+  :: [Int]    -- ^ Windows in each column, starting with master. Set to 0 to catch the rest.+  -> Int      -- ^ Default value for all following columns.+  -> Rational -- ^ How much to change size each time.+  -> Rational -- ^ Initial size of master area, or column area if the size is negative.+  -> MultiCol a+multiCol n defn ds s = MultiCol (map (max 0) n) (max 0 defn) ds s 0++data MultiCol a = MultiCol+  { multiColNWin      :: ![Int]+  , multiColDefWin    :: !Int+  , multiColDeltaSize :: !Rational+  , multiColSize      :: !Rational+  , multiColActive    :: !Int+  } deriving (Show,Read,Eq)++instance LayoutClass MultiCol a where+    doLayout l r s = return (zip w rlist, resl)+        where rlist = doL (multiColNWin l') (multiColSize l') r wlen+              w = W.integrate s+              wlen = length w+              -- Make sure the list of columns is big enough and update active column+              nw = multiColNWin l ++ repeat (multiColDefWin l)+              l' = l { multiColNWin = take (max (length $ multiColNWin l) $ getCol (wlen-1) nw + 1) nw+                     , multiColActive = getCol (length $ W.up s) nw+                     }+              -- Only return new layout if it has been modified+              resl = if l'==l+                     then Nothing+                     else Just l'+    handleMessage l m =+        return $ msum [fmap resize     (fromMessage m)+                      ,fmap incmastern (fromMessage m)]+            where resize Shrink = l { multiColSize = max (-0.5) $ s-ds }+                  resize Expand = l { multiColSize = min 1 $ s+ds }+                  incmastern (IncMasterN x) = l { multiColNWin = take a n ++ [newval] ++ tail r }+                      where newval =  max 0 $ head r + x+                            r = drop a n+                  n = multiColNWin l+                  ds = multiColDeltaSize l+                  s = multiColSize l+                  a = multiColActive l+    description _ = "MultiCol"+++-- | Get which column a window is in, starting at 0.+getCol :: Int -> [Int] -> Int+getCol w (n:ns) = if n<1 || w < n+                  then 0+                  else 1 + getCol (w-n) ns+-- Should never occur...+getCol _ _ = -1++doL :: [Int] -> Rational -> Rectangle -> Int -> [Rectangle]+doL nwin s r n = rlist+    where -- Number of columns to tile+          ncol = getCol (n-1) nwin + 1+          -- Compute the actual size+          size = floor $ abs s * fromIntegral (rect_width r)+          -- Extract all but last column to tile+          c = take (ncol-1) nwin+          -- Compute number of windows in last column and add it to the others+          col = c ++ [n-sum c]+          -- Compute width of columns+          width = if s>0+                  then if ncol==1+                       -- Only one window+                       then [fromIntegral $ rect_width r]+                       -- Give the master it's space and split the rest equally for the other columns+                       else size:replicate (ncol-1) ((fromIntegral (rect_width r) - size) `div` (ncol-1))+                  else if fromIntegral ncol * abs s >= 1+                       -- Split equally+                       then replicate ncol $ fromIntegral (rect_width r) `div` ncol+                       -- Let the master cover what is left...+                       else (fromIntegral (rect_width r) - (ncol-1)*size):replicate (ncol-1) size+          -- Compute the horizontal position of columns+          xpos = accumEx (fromIntegral $ rect_x r) width+          -- Exclusive accumulation+          accumEx a (x:xs) = a:accumEx (a+x) xs+          accumEx _ _ = []+          -- Create a rectangle for each column+          cr = zipWith (\x w -> r { rect_x=fromIntegral x, rect_width=fromIntegral w }) xpos width+          -- Split the columns into the windows+          rlist = concat $ zipWith (\num rect -> splitVertically num rect) col cr
XMonad/Layout/MultiToggle.hs view
@@ -1,4 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-}+{-# LANGUAGE DeriveDataTypeable, ExistentialQuantification, Rank2Types, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts, PatternGuards #-}  ----------------------------------------------------------------------------- -- |@@ -41,11 +41,6 @@ -- first disables any currently active transformer; i.e. it works like a -- group of radio buttons. ----- A side effect of this meta-layout is that layout transformers no longer--- receive any messages; any message not handled by MultiToggle itself will--- undo the current layout transformer, pass the message on to the base--- layout, then reapply the transformer.--- -- To use this module, you need some data types which represent -- transformers; for some commonly used transformers (including -- MIRROR, NOBORDERS, and FULL used in the examples below) you can@@ -63,7 +58,7 @@ -- you can now dynamically apply the 'XMonad.Layout.Mirror' transformation: -- -- > ...--- >   , ((modMask,               xK_x     ), sendMessage $ Toggle MIRROR)+-- >   , ((modm,               xK_x     ), sendMessage $ Toggle MIRROR) -- > ... -- -- (That should be part of your key bindings.) When you press @mod-x@, the@@ -89,27 +84,28 @@ -- -- > data MIRROR = MIRROR deriving (Read, Show, Eq, Typeable) -- > instance Transformer MIRROR Window where--- >     transform _ x k = k (Mirror x)+-- >     transform _ x k = k (Mirror x) (\(Mirror x') -> x') -- -- Note, you need to put @{-\# LANGUAGE DeriveDataTypeable \#-}@ at the--- beginning of your file (ghc 6.8 only; with ghc 6.6 you can use--- @{-\# OPTIONS_GHC -fglasgow-exts \#-}@ instead) to be able to--- derive "Data.Typeable".---+-- beginning of your file.  -- | A class to identify custom transformers (and look up transforming -- functions by type). class (Eq t, Typeable t) => Transformer t a | t -> a where-    transform :: (LayoutClass l a) => t -> l a -> (forall l'. (LayoutClass l' a) => l' a -> b) -> b+    transform :: (LayoutClass l a) => t -> l a ->+        (forall l'. (LayoutClass l' a) => l' a -> (l' a -> l a) -> b) -> b -data EL a = forall l. (LayoutClass l a) => EL (l a)+data (LayoutClass l a) => EL l a = forall l'. (LayoutClass l' a) => EL (l' a) (l' a -> l a) -unEL :: EL a -> (forall l. (LayoutClass l a) => l a -> b) -> b-unEL (EL x) k = k x+unEL :: (LayoutClass l a) => EL l a -> (forall l'. (LayoutClass l' a) => l' a -> b) -> b+unEL (EL x _) k = k x -transform' :: (Transformer t a) => t -> EL a -> EL a-transform' t el = el `unEL` \l -> transform t l EL+deEL :: (LayoutClass l a) => EL l a -> l a+deEL (EL x det) = det x +transform' :: (Transformer t a, LayoutClass l a) => t -> EL l a -> EL l a+transform' t (EL l det) = transform t l (\l' det' -> EL l' (det . det'))+ -- | Toggle the specified layout transformer. data Toggle a = forall t. (Transformer t a) => Toggle t     deriving (Typeable)@@ -120,10 +116,8 @@     deriving (Read, Show)  data MultiToggle ts l a = MultiToggle{-    baseLayout :: l a,-    currLayout :: EL a,+    currLayout :: EL l a,     currIndex :: Maybe Int,-    currTrans :: EL a -> EL a,     transformers :: ts } @@ -131,27 +125,23 @@ expand (MultiToggleS b i ts) =     resolve ts (fromMaybe (-1) i) id         (\x mt ->-            let g = transform' x in-            mt{-                currLayout = g . EL $ baseLayout mt,-                currTrans = g-            }+            let g = transform' x in mt{ currLayout = g $ currLayout mt }         )-        (MultiToggle b (EL b) i id ts)+        (MultiToggle (EL b id) i ts) -collapse :: MultiToggle ts l a -> MultiToggleS ts l a-collapse mt = MultiToggleS (baseLayout mt) (currIndex mt) (transformers mt)+collapse :: (LayoutClass l a) => MultiToggle ts l a -> MultiToggleS ts l a+collapse mt = MultiToggleS (deEL (currLayout mt)) (currIndex mt) (transformers mt)  instance (LayoutClass l a, Read (l a), HList ts a, Read ts) => Read (MultiToggle ts l a) where     readsPrec p s = map (first expand) $ readsPrec p s -instance (Show ts, Show (l a)) => Show (MultiToggle ts l a) where+instance (Show ts, Show (l a), LayoutClass l a) => Show (MultiToggle ts l a) where     showsPrec p = showsPrec p . collapse  -- | Construct a @MultiToggle@ layout from a transformer table and a base -- layout. mkToggle :: (LayoutClass l a) => ts -> l a -> MultiToggle ts l a-mkToggle ts l = MultiToggle l (EL l) Nothing id ts+mkToggle ts l = MultiToggle (EL l id) Nothing ts  -- | Construct a @MultiToggle@ layout from a single transformer and a base -- layout.@@ -193,48 +183,26 @@ geq :: (Typeable a, Eq a, Typeable b) => a -> b -> Bool geq a b = Just a == cast b -acceptChange :: (LayoutClass l' a) => MultiToggle ts l a -> ((l' a -> MultiToggle ts l a) -> b -> c) -> X b -> X c-acceptChange mt f = fmap (f (\x -> mt{ currLayout = EL x }))- instance (Typeable a, Show ts, HList ts a, LayoutClass l a) => LayoutClass (MultiToggle ts l) a where     description mt = currLayout mt `unEL` \l -> description l -    runLayout (Workspace i mt s) r-        | isNothing (currIndex mt) =-            acceptChange mt (fmap . fmap . \f x -> (f x){ baseLayout = x }) $ runLayout (Workspace i (baseLayout mt) s) r-        | otherwise = currLayout mt `unEL` \l ->-            acceptChange mt (fmap . fmap) $ runLayout (Workspace i l s) r+    runLayout (Workspace i mt s) r = case currLayout mt of+        EL l det -> fmap (fmap . fmap $ (\x -> mt { currLayout = EL x det })) $+            runLayout (Workspace i l s) r      handleMessage mt m         | Just (Toggle t) <- fromMessage m         , i@(Just _) <- find (transformers mt) t-            = currLayout mt `unEL` \l ->-            if i == currIndex mt-                then do-                    handleMessage l (SomeMessage ReleaseResources)-                    return . Just $-                        mt{-                            currLayout = EL $ baseLayout mt,-                            currIndex = Nothing,-                            currTrans = id-                        }-                else do-                    handleMessage l (SomeMessage ReleaseResources)-                    let f = transform' t+            = case currLayout mt of+                EL l det -> do+                    l' <- fromMaybe l `fmap` handleMessage l (SomeMessage ReleaseResources)                     return . Just $-                        mt{-                            currLayout = f . EL $ baseLayout mt,-                            currIndex = i,-                            currTrans = f+                        mt {+                            currLayout = (if cur then id else transform' t) (EL (det l') id),+                            currIndex = if cur then Nothing else i                         }-        | fromMessage m == Just ReleaseResources ||-          fromMessage m == Just Hide-            = currLayout mt `unEL` \l -> acceptChange mt fmap (handleMessage l m)-        | otherwise = do-            ml <- handleMessage (baseLayout mt) m-            case ml of-                Nothing -> return Nothing-                Just b' -> currLayout mt `unEL` \l -> do-                    handleMessage l (SomeMessage ReleaseResources)-                    return . Just $-                        mt{ baseLayout = b', currLayout = currTrans mt . EL $ b' }+                    where cur = (i == currIndex mt)+        | otherwise+            = case currLayout mt of+                EL l det -> fmap (fmap (\x -> mt { currLayout = EL x det })) $+                    handleMessage l m
XMonad/Layout/MultiToggle/Instances.hs view
@@ -1,6 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-}--- above is for compatibility with GHC 6.6.-{- LANGUAGE TypeSynonymInstances, DeriveDataTypeable -}+{-# LANGUAGE TypeSynonymInstances, DeriveDataTypeable, MultiParamTypeClasses #-}  ----------------------------------------------------------------------------- -- |@@ -24,6 +22,7 @@  import XMonad import XMonad.Layout.NoBorders+import XMonad.Layout.LayoutModifier  data StdTransformers = FULL          -- ^ switch to Full layout                      | NBFULL        -- ^ switch to Full with no borders@@ -33,8 +32,8 @@   deriving (Read, Show, Eq, Typeable)  instance Transformer StdTransformers Window where-    transform FULL         _ k = k Full-    transform NBFULL       _ k = k (noBorders Full)-    transform MIRROR       x k = k (Mirror x)-    transform NOBORDERS    x k = k (noBorders x)-    transform SMARTBORDERS x k = k (smartBorders x)+    transform FULL         x k = k Full (const x)+    transform NBFULL       x k = k (noBorders Full) (const x)+    transform MIRROR       x k = k (Mirror x) (\(Mirror x') -> x')+    transform NOBORDERS    x k = k (noBorders x) (\(ModifiedLayout _ x') -> x')+    transform SMARTBORDERS x k = k (smartBorders x) (\(ModifiedLayout _ x') -> x')
XMonad/Layout/Named.hs view
@@ -32,8 +32,8 @@ -- Then edit your @layoutHook@ by adding the Named layout modifier -- to some layout: ----- > myLayouts = named "real big" Full ||| (nameTail $ named "real big" $ Full) ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = named "real big" Full ||| (nameTail $ named "real big" $ Full) ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --
XMonad/Layout/NoBorders.hs view
@@ -33,7 +33,6 @@ import XMonad import XMonad.Layout.LayoutModifier import qualified XMonad.StackSet as W-import Control.Monad import Data.List import qualified Data.Map as M import Data.Function (on)
XMonad/Layout/NoFrillsDecoration.hs view
@@ -9,13 +9,33 @@ -- Stability   :  unstable -- Portability :  not portable --+-- Most basic version of decoration for windows without any additional+-- modifications. In contrast to "XMonad.Layout.SimpleDecoration" this will+-- result in title bars that span the entire window instead of being only the+-- length of the window title.+-- -----------------------------------------------------------------------------  module XMonad.Layout.NoFrillsDecoration-    ( noFrillsDeco+    ( -- * Usage:+      -- $usage+      noFrillsDeco     ) where  import XMonad.Layout.Decoration++-- $usage+-- You can use this module with the following in your+-- @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.NoFrillsDecoration+--+-- Then edit your @layoutHook@ by adding the NoFrillsDecoration to+-- your layout:+--+-- > myL = noFrillsDeco shrinkText defaultTheme (layoutHook defaultConfig)+-- > main = xmonad defaultConfig { layoutHook = myL }+--  -- | Add very simple decorations to windows of a layout. noFrillsDeco :: (Eq a, Shrinker s) => s -> Theme
XMonad/Layout/OneBig.hs view
@@ -27,7 +27,7 @@ -- bottom of master. It tries to give equal space for each slave -- window. ----- You can use this module by adding folowing in your @xmonad.hs@:+-- You can use this module by adding following in your @xmonad.hs@: -- -- > import XMonad.Layout.OneBig --@@ -54,7 +54,7 @@  -- | Main layout function oneBigLayout :: OneBig a -> Rectangle -> W.Stack a -> [(a, Rectangle)]-oneBigLayout (OneBig cx cy) rect stack = [(master,masterRect)] +oneBigLayout (OneBig cx cy) rect stack = [(master,masterRect)]                                       ++ (divideBottom bottomRect bottomWs)                                       ++ (divideRight rightRect rightWs)       where ws = W.integrate stack@@ -106,7 +106,7 @@           x = round (fromIntegral sw*cx+(fromIntegral sx))           h = round (fromIntegral sh*cy) --- | Divide bottom rectangle between windows +-- | Divide bottom rectangle between windows divideBottom :: Rectangle -> [a] -> [(a, Rectangle)] divideBottom (Rectangle x y w h) ws = zip ws rects     where n = length ws@@ -122,7 +122,7 @@           oneRect = Rectangle x y w (fromIntegral oneH)           rects = take n $ iterate (shiftB (fromIntegral oneH)) oneRect --- | Shift rectangle right +-- | Shift rectangle right shiftR :: Position -> Rectangle -> Rectangle shiftR s (Rectangle x y w h) = Rectangle (x+s) y w h 
XMonad/Layout/PositionStoreFloat.hs view
@@ -9,20 +9,48 @@ -- Stability   :  unstable -- Portability :  not portable --+-- A floating layout which has been designed with a dual-head setup+-- in mind. It makes use of "XMonad.Util.PositionStore" as well as+-- "XMonad.Hooks.PositionStoreHooks" . Since there is currently no way+-- to move or resize windows with the keyboard alone in this layout,+-- it is adviced to use it in combination with a decoration such as+-- "XMonad.Layout.NoFrillsDecoration" (to move windows) and the+-- layout modifier "XMonad.Layout.BorderResize" (to resize windows).+-- -----------------------------------------------------------------------------  module XMonad.Layout.PositionStoreFloat-    ( positionStoreFloat+    ( -- * Usage+      -- $usage+      positionStoreFloat     ) where  import XMonad-import XMonad.PositionStore+import XMonad.Util.PositionStore import qualified XMonad.StackSet as S import XMonad.Layout.WindowArranger import Control.Monad(when) import Data.Maybe(isJust) import Data.List(nub) +-- $usage+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.PositionStoreFloat+-- > import XMonad.Layout.NoFrillsDecoration+-- > import XMonad.Layout.BorderResize+--+-- Then edit your @layoutHook@ by adding the PositionStoreFloat layout.+-- Below is a suggestion which uses the mentioned NoFrillsDecoration and+-- BorderResize:+--+-- > myLayouts = floatingDeco $ borderResize $ positionStoreFloat ||| etc..+-- >               where floatingDeco l = noFrillsDeco shrinkText defaultTheme l+-- > main = xmonad defaultConfig { layoutHook = myLayouts }+--+-- See the documentation of "XMonad.Hooks.PositionStoreHooks" on how+-- to add the support hooks.+ positionStoreFloat :: PositionStoreFloat a positionStoreFloat = PSF (Nothing, []) @@ -30,7 +58,7 @@ instance LayoutClass PositionStoreFloat Window where     description _ = "PSF"     doLayout (PSF (maybeChange, paintOrder)) sr (S.Stack w l r) = do-            XState { positionStore = posStore } <- get+            posStore <- getPosStore             let wrs = map (\w' -> (w', pSQ posStore w' sr)) (reverse l ++ r)             let focused = case maybeChange of                             Nothing -> (w, pSQ posStore w sr)
XMonad/Layout/Reflect.hs view
@@ -1,8 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-}---- for now, use -fglasgow-exts for compatibility with ghc 6.6, which chokes--- on some of the LANGUAGE pragmas below-{- LANGUAGE FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances -}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances #-}  ----------------------------------------------------------------------------- -- |@@ -22,7 +18,8 @@                                -- $usage                                 reflectHoriz, reflectVert,-                               REFLECTX(..), REFLECTY(..)+                               REFLECTX(..), REFLECTY(..),+                               Reflect                               ) where @@ -62,8 +59,8 @@ -- -- Finally, add some keybindings to do the toggling, for example: ----- > , ((modMask x .|. controlMask, xK_x), sendMessage $ Toggle REFLECTX)--- > , ((modMask x .|. controlMask, xK_y), sendMessage $ Toggle REFLECTY)+-- > , ((modm .|. controlMask, xK_x), sendMessage $ Toggle REFLECTX)+-- > , ((modm .|. controlMask, xK_y), sendMessage $ Toggle REFLECTY) --  -- | Apply a horizontal reflection (left \<--\> right) to a@@ -109,7 +106,7 @@ data REFLECTY = REFLECTY deriving (Read, Show, Eq, Typeable)  instance Transformer REFLECTX Window where-    transform REFLECTX x k = k (reflectHoriz x)+    transform REFLECTX x k = k (reflectHoriz x) (\(ModifiedLayout _ x') -> x')  instance Transformer REFLECTY Window where-    transform REFLECTY x k = k (reflectVert x)+    transform REFLECTY x k = k (reflectVert x) (\(ModifiedLayout _ x') -> x')
XMonad/Layout/ResizableTile.hs view
@@ -1,5 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}  ----------------------------------------------------------------------------- -- |@@ -34,8 +33,8 @@ -- -- Then edit your @layoutHook@ by adding the ResizableTile layout: ----- > myLayouts =  ResizableTall 1 (3/100) (1/2) [] ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout =  ResizableTall 1 (3/100) (1/2) [] ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -43,8 +42,8 @@ -- -- You may also want to add the following key bindings: ----- > , ((modMask x,               xK_a), sendMessage MirrorShrink)--- > , ((modMask x,               xK_z), sendMessage MirrorExpand)+-- > , ((modm,               xK_a), sendMessage MirrorShrink)+-- > , ((modm,               xK_z), sendMessage MirrorExpand) -- -- For detailed instruction on editing the key binding see: --@@ -53,7 +52,20 @@ data MirrorResize = MirrorShrink | MirrorExpand deriving Typeable instance Message MirrorResize -data ResizableTall a = ResizableTall Int Rational Rational [Rational] deriving (Show, Read)+data ResizableTall a = ResizableTall+    { _nmaster :: Int       -- ^ number of master windows+    , _delta  :: Rational   -- ^ change when resizing by 'Shrink', 'Expand',+                            -- 'MirrorShrink', 'MirrorExpand'+    , _frac   :: Rational   -- ^ width of master+    , _slaves :: [Rational] -- ^ fraction to multiply the window+                            -- height that would be given when divided equally.+                            --+                            -- slave windows are assigned their modified+                            -- heights in order, from top to bottom+                            --+                            -- unspecified values are replaced by 1+    } deriving (Show, Read)+ instance LayoutClass ResizableTall a where     doLayout (ResizableTall nmaster _ frac mfrac) r =         return . (\x->(x,Nothing)) .@@ -95,7 +107,7 @@ splitVertically _ n r | n < 2 = [r] splitVertically (f:fx) n (Rectangle sx sy sw sh) = Rectangle sx sy sw smallh :     splitVertically fx (n-1) (Rectangle sx (sy+fromIntegral smallh) sw (sh-smallh))-  where smallh = floor $ fromIntegral (sh `div` fromIntegral n) * f --hmm, this is a fold or map.+  where smallh = min sh (floor $ fromIntegral (sh `div` fromIntegral n) * f) --hmm, this is a fold or map.  splitHorizontallyBy :: RealFrac r => r -> Rectangle -> (Rectangle, Rectangle) splitHorizontallyBy f (Rectangle sx sy sw sh) =
XMonad/Layout/Roledex.hs view
@@ -10,14 +10,15 @@ -- Stability   :  unstable -- Portability :  unportable ----- Screenshot  :  <http://www.timthelion.com/rolodex.png>--- -- This is a completely pointless layout which acts like Microsoft's Flip 3D -----------------------------------------------------------------------------  module XMonad.Layout.Roledex (     -- * Usage     -- $usage++    -- * Screenshots+    -- $screenshot     Roledex(Roledex)) where  import XMonad@@ -27,17 +28,20 @@ -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: ----- > import XMonad.Layout.Roledex +-- > import XMonad.Layout.Roledex -- -- Then edit your @layoutHook@ by adding the Roledex layout: ----- > myLayouts =  Roledex ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout =  Roledex ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: -- -- "XMonad.Doc.Extending#Editing_the_layout_hook" +-- $screenshot+-- <<http://www.timthelion.com/rolodex.png>>+ data Roledex a = Roledex deriving ( Show, Read )  instance LayoutClass Roledex Window where@@ -51,8 +55,8 @@  where ups    = W.up ws        dns    = W.down ws        c = length ups + length dns-       rect = fst $ splitHorizontallyBy (2%3 :: Ratio Int) $ fst (splitVerticallyBy (2%3 :: Ratio Int) sc) -       gw = div' (w - rw) (fromIntegral c) +       rect = fst $ splitHorizontallyBy (2%3 :: Ratio Int) $ fst (splitVerticallyBy (2%3 :: Ratio Int) sc)+       gw = div' (w - rw) (fromIntegral c)             where             (Rectangle _ _ w _) = sc             (Rectangle _ _ rw _) = rect@@ -60,12 +64,12 @@             where             (Rectangle _ _ _ h) = sc             (Rectangle _ _ _ rh) = rect-       mainPane = mrect (gw * fromIntegral c) (gh * fromIntegral c) rect +       mainPane = mrect (gw * fromIntegral c) (gh * fromIntegral c) rect        mrect  mx my (Rectangle x y w h) = Rectangle (x + (fromIntegral mx)) (y + (fromIntegral my)) w h        tops    = map f $ cd c (length dns)        bottoms = map f $ [0..(length dns)]        f n = mrect (gw * (fromIntegral n)) (gh * (fromIntegral n)) rect-       cd n m = if n > m +       cd n m = if n > m                 then (n - 1) : (cd (n-1) m)                 else [] 
XMonad/Layout/ShowWName.hs view
@@ -45,7 +45,7 @@ showWName = ModifiedLayout (SWN True defaultSWNConfig Nothing)  -- | A layout modifier to show the workspace name when switching. It--- is possible to provide a costum configuration.+-- is possible to provide a custom configuration. showWName' :: SWNConfig -> l a -> ModifiedLayout ShowWName l a showWName' c = ModifiedLayout (SWN True c Nothing) 
XMonad/Layout/SimpleFloat.hs view
@@ -38,8 +38,8 @@ -- -- Then edit your @layoutHook@ by adding the SimpleFloat layout: ----- > myLayouts = simpleFloat ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = simpleFloat ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --
XMonad/Layout/Simplest.hs view
@@ -29,8 +29,8 @@ -- -- Then edit your @layoutHook@ by adding the Simplest layout: ----- > myLayouts = Simplest ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = Simplest ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --
XMonad/Layout/SimplestFloat.hs view
@@ -23,6 +23,7 @@ import qualified XMonad.StackSet as S import XMonad.Layout.WindowArranger import XMonad.Layout.LayoutModifier+import XMonad.Util.XUtils (fi)  -- $usage -- You can use this module with the following in your@@ -32,8 +33,8 @@ -- -- Then edit your @layoutHook@ by adding the SimplestFloat layout: ----- > myLayouts = simplestFloat ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = simplestFloat ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -42,12 +43,12 @@ -- | A simple floating layout where every window is placed according -- to the window's initial attributes. simplestFloat :: Eq a => (ModifiedLayout WindowArranger SimplestFloat) a-simplestFloat = (windowArrangeAll $ SF)+simplestFloat = windowArrangeAll SF  data SimplestFloat a = SF deriving (Show, Read) instance LayoutClass SimplestFloat Window where-    doLayout SF sc (S.Stack w l r) = do wrs <- mapM (getSize sc) (w : reverse l ++ r)-                                        return (wrs, Nothing)+    doLayout SF sc (S.Stack w l r) = fmap (flip (,) Nothing)+                                   $ mapM (getSize sc) (w : reverse l ++ r)     description _ = "SimplestFloat"  getSize :: Rectangle -> Window -> X (Window,Rectangle)@@ -60,5 +61,3 @@       wh = (fi $ wa_width  wa) + (bw * 2)       ht = (fi $ wa_height wa) + (bw * 2)   return (w, Rectangle x y wh ht)-  where-    fi x = fromIntegral x
+ XMonad/Layout/Spacing.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Layout.Spacing+-- Copyright   :  (c) Brent Yorgey+-- License     :  BSD-style (see LICENSE)+--+-- Maintainer  :  <byorgey@gmail.com>+-- Stability   :  unstable+-- Portability :  portable+--+-- Add a configurable amount of space around windows.+-----------------------------------------------------------------------------++module XMonad.Layout.Spacing (+                               -- * Usage+                               -- $usage++                               spacing++                             ) where++import Graphics.X11 (Rectangle(..))+import Control.Arrow (second)++import XMonad.Layout.LayoutModifier++-- $usage+-- You can use this module by importing it into your @~\/.xmonad\/xmonad.hs@ file:+--+-- > import XMonad.Layout.Spacing+--+-- and modifying your layoutHook as follows (for example):+--+-- > layoutHook = spacing 2 $ Tall 1 (3/100) (1/2)+-- >                      -- put a 2px space around every window+--++-- | Surround all windows by a certain number of pixels of blank space.+spacing :: Int -> l a -> ModifiedLayout Spacing l a+spacing p = ModifiedLayout (Spacing p)++data Spacing a = Spacing Int deriving (Show, Read)++instance LayoutModifier Spacing a where++    pureModifier (Spacing p) _ _ wrs = (map (second $ shrinkRect p) wrs, Nothing)++    modifierDescription (Spacing p) = "Spacing " ++ show p++shrinkRect :: Int -> Rectangle -> Rectangle+shrinkRect p (Rectangle x y w h) = Rectangle (x+fi p) (y+fi p) (w-2*fi p) (h-2*fi p)+  where fi n = fromIntegral n   -- avoid the DMR
XMonad/Layout/Spiral.hs view
@@ -34,8 +34,8 @@ -- -- Then edit your @layoutHook@ by adding the Spiral layout: ----- > myLayouts =  spiral (6/7) ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout =  spiral (6/7) ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --
XMonad/Layout/StackTile.hs view
@@ -1,5 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}  ----------------------------------------------------------------------------- -- |@@ -12,7 +11,7 @@ -- Portability :  unportable -- -- A stacking layout, like dishes but with the ability to resize master pane.--- Moastly usefull on small screens.+-- Mostly useful on small screens. -- ----------------------------------------------------------------------------- @@ -33,8 +32,8 @@ -- -- Then edit your @layoutHook@ by adding the StackTile layout: ----- > myLayouts =  StackTile 1 (3/100) (1/2) ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout =  StackTile 1 (3/100) (1/2) ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --
XMonad/Layout/SubLayouts.hs view
@@ -28,11 +28,16 @@      defaultSublMap, +    -- * Screenshots+    -- $screenshots+     -- * Todo     -- $todo     )     where +import XMonad.Layout.Circle () -- so haddock can find the link+ import XMonad.Layout.Decoration(Decoration, DefaultShrinker) import XMonad.Layout.LayoutModifier(LayoutModifier(handleMess, modifyLayout,                                     redoLayout),@@ -40,18 +45,16 @@ import XMonad.Layout.Simplest(Simplest(..)) import XMonad.Layout.Tabbed(defaultTheme, shrinkText,                             TabbedDecoration, addTabs)-import XMonad.Layout.WindowNavigation(Direction, Navigate(Apply))+import XMonad.Layout.WindowNavigation(Navigate(Apply)) import XMonad.Util.Invisible(Invisible(..))+import XMonad.Util.Types(Direction2D(..)) import XMonad-import Control.Applicative((<$>))+import Control.Applicative((<$>),(<*)) import Control.Arrow(Arrow(second, (&&&)))-import Control.Monad(Monad(return), Functor(..),-                     MonadPlus(mplus), (=<<), sequence, foldM, guard, when, join)-import Data.Function((.), ($), flip, id, on)-import Data.List((++), foldr, filter, map, concatMap, elem,-                 notElem, null, nubBy, (\\), find)-import Data.Maybe(Maybe(..), maybe, fromMaybe, listToMaybe,-                  mapMaybe)+import Control.Monad(MonadPlus(mplus), foldM, guard, when, join)+import Data.Function(on)+import Data.List(nubBy, (\\), find)+import Data.Maybe(isNothing, fromMaybe, listToMaybe, mapMaybe) import Data.Traversable(sequenceA)  import qualified XMonad.Layout.BoringWindows as B@@ -59,7 +62,31 @@ import qualified Data.Map as M import Data.Map(Map) +-- $screenshots+--+-- <<http://haskell.org/sitewiki/images/thumb/8/8b/Xmonad-SubLayouts-xinerama.png/480px-Xmonad-SubLayouts-xinerama.png>>+--+-- Larger version: <http://haskell.org/sitewiki/images/8/8b/Xmonad-SubLayouts-xinerama.png>+ -- $todo+--  /Issue 288/+--+--  "XMonad.Layout.ResizableTile" assumes that its environment+--  contains only the windows it is running: sublayouts are currently run with+--  the stack containing only the windows passed to it in its environment, but+--  any changes that the layout makes are not merged back.+--+--  Should the behavior be made optional?+--+--  /Features/+--+--   * suggested managehooks for merging specific windows, or the apropriate+--     layout based hack to find out the number of groups currently showed, but+--     the size of current window groups is not available (outside of this+--     growing module)+--+--  /SimpleTabbed as a SubLayout/+-- --  'subTabbed' works well, but it would be more uniform to avoid the use of --  addTabs, with the sublayout being Simplest (but --  'XMonad.Layout.Tabbed.simpleTabbed' is this...).  The only thing to be@@ -67,7 +94,7 @@ --  styles. Better compatibility with some other layouts of which I am not --  aware could be another benefit. -----  'simpleTabbed' (and other decorated layouts) fail horibly when used as+--  'simpleTabbed' (and other decorated layouts) fail horribly when used as --  subLayouts: -- --    * decorations stick around: layout is run after being told to Hide@@ -78,9 +105,6 @@ --    * sending ReleaseResources before running it makes xmonad very slow, and --      still leaves borders sticking around -----  Issue 288: "XMonad.Layout.ResizableTile" assumes that its environment---  contains only the windows it is running: should sublayouts be run in a---  restricted environment that is then merged back?  -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:@@ -88,16 +112,16 @@ -- > import XMonad.Layout.SubLayouts -- > import XMonad.Layout.WindowNavigation ----- Using BoringWindows is optional and it allows you to add a keybinding to--- skip over the non-visible windows.+-- Using "XMonad.Layout.BoringWindows" is optional and it allows you to add a+-- keybinding to skip over the non-visible windows. -- -- > import XMonad.Layout.BoringWindows ----- Then edit your @layoutHook@ by adding the subTabbed layout modifier:+-- Then edit your @layoutHook@ by adding the 'subTabbed' layout modifier: ----- > myLayouts = windowNavigation $ subTabbed $ boringWindows $+-- > myLayout = windowNavigation $ subTabbed $ boringWindows $ -- >                        Tall 1 (3/100) (1/2) ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- "XMonad.Layout.WindowNavigation" is used to specify which windows to merge, -- and it is not integrated into the modifier because it can be configured, and@@ -105,23 +129,23 @@ -- -- Then to your keybindings add: -----  > , ((modMask .|. controlMask, xK_h), sendMessage $ pullGroup L)---  > , ((modMask .|. controlMask, xK_l), sendMessage $ pullGroup R)---  > , ((modMask .|. controlMask, xK_k), sendMessage $ pullGroup U)---  > , ((modMask .|. controlMask, xK_j), sendMessage $ pullGroup D)+--  > , ((modm .|. controlMask, xK_h), sendMessage $ pullGroup L)+--  > , ((modm .|. controlMask, xK_l), sendMessage $ pullGroup R)+--  > , ((modm .|. controlMask, xK_k), sendMessage $ pullGroup U)+--  > , ((modm .|. controlMask, xK_j), sendMessage $ pullGroup D) --  >---  > , ((modMask .|. controlMask, xK_m), withFocused (sendMessage . MergeAll))---  > , ((modMask .|. controlMask, xK_u), withFocused (sendMessage . UnMerge))+--  > , ((modm .|. controlMask, xK_m), withFocused (sendMessage . MergeAll))+--  > , ((modm .|. controlMask, xK_u), withFocused (sendMessage . UnMerge)) --  >---  > , ((modMask .|. controlMask, xK_period), onGroup W.focusUp')---  > , ((modMask .|. controlMask, xK_comma), onGroup W.focusDown')+--  > , ((modm .|. controlMask, xK_period), onGroup W.focusUp')+--  > , ((modm .|. controlMask, xK_comma), onGroup W.focusDown') -- --  These additional keybindings require the optional --  "XMonad.Layout.BoringWindows" layoutModifier. The focus will skip over the --  windows that are not focused in each sublayout. -----  > , ((modMask, xK_j), focusDown)---  > , ((modMask, xK_k), focusUp)+--  > , ((modm, xK_j), focusDown)+--  > , ((modm, xK_k), focusUp) -- --  A 'submap' can be used to make modifying the sublayouts using 'onGroup' and --  'toSubl' simpler:@@ -139,15 +163,21 @@  -- | The main layout modifier arguments: -----  [@nextLayout@] When a new group is formed, use the layout @sl@ after---  skipping that number of layouts. Specify a finite list and groups that do---  not have a corresponding index get the first choice in @sls@+-- @subLayout advanceInnerLayouts innerLayout outerLayout@ -----  [@sl@] The single layout given to be run as a sublayout.+--  [@advanceInnerLayouts@] When a new group at index @n@ in the outer layout+--  is created (even with one element), the @innerLayout@ is used as the+--  layout within that group after being advanced with @advanceInnerLayouts !!+--  n@ 'NextLayout' messages. If there is no corresponding element in the+--  @advanceInnerLayouts@ list, then @innerLayout@ is not given any 'NextLayout'+--  messages. -----  [@x@] The layout that determines the rectangles that the groups get.+--  [@innerLayout@] The single layout given to be run as a sublayout. -----  Ex. The second group is Tall, the third is Circle, all others are tabbed+--  [@outerLayout@] The layout that determines the rectangles given to each+--  group.+--+--  Ex. The second group is 'Tall', the third is 'Circle', all others are tabbed --  with: -- --  > myLayout = addTabs shrinkText defaultTheme@@ -156,7 +186,7 @@ subLayout :: [Int] -> subl a -> l a -> ModifiedLayout (Sublayout subl) l a subLayout nextLayout sl x = ModifiedLayout (Sublayout (I []) (nextLayout,sl) []) x --- | 'subLayout' but use 'XMonad.Layout.Tabbed.addTabs' to add decorations.+-- | @subTabbed@ is a use of 'subLayout' with 'addTabs' to show decorations. subTabbed :: (Eq a, LayoutModifier (Sublayout Simplest) a, LayoutClass l a) =>     l a -> ModifiedLayout (Decoration TabbedDecoration DefaultShrinker)                           (ModifiedLayout (Sublayout Simplest) l) a@@ -215,7 +245,11 @@                 -- ^ separate the focused group into singleton groups     | Merge a a -- ^ merge the first group into the second group     | MergeAll a-                -- ^ make one large group, keeping a focused+                -- ^ make one large group, keeping the parameter focused+    | Migrate a a+                -- ^ used to the window named in the first argument to the+                -- second argument's group, this may be replaced by a+                -- combination of 'UnMerge' and 'Merge'     | WithGroup (W.Stack a -> X (W.Stack a)) a     | SubMessage SomeMessage  a                 -- ^ the sublayout with the given window will get the message@@ -239,22 +273,18 @@ instance Message Broadcast instance Typeable a => Message (GroupMsg a) --- | pullGroup, pushGroup allow you to merge windows or groups inheriting the--- position of the current window (pull) or the other window (push).-pullGroup :: Direction -> Navigate+-- | @pullGroup@, @pushGroup@ allow you to merge windows or groups inheriting+-- the position of the current window (pull) or the other window (push).+--+-- @pushWindow@ and @pullWindow@ move individual windows between groups. They+-- are less effective at preserving window positions.+pullGroup,pushGroup,pullWindow,pushWindow :: Direction2D -> Navigate pullGroup = mergeNav (\o c -> sendMessage $ Merge o c)---pullWindow :: Direction -> Navigate-pullWindow = mergeNav (\o c -> sendMessage (UnMerge o) >> sendMessage (Merge o c))--pushGroup :: Direction -> Navigate pushGroup = mergeNav (\o c -> sendMessage $ Merge c o)--pushWindow :: Direction -> Navigate-pushWindow = mergeNav (\o c -> sendMessage (UnMerge c) >> sendMessage (Merge c o))+pullWindow = mergeNav (\o c -> sendMessage $ Migrate o c)+pushWindow = mergeNav (\o c -> sendMessage $ Migrate c o) -mergeNav :: (Window -> Window -> X ()) -> Direction -> Navigate+mergeNav :: (Window -> Window -> X ()) -> Direction2D -> Navigate mergeNav f = Apply (\o -> withFocused (f o))  -- | Apply a function on the stack belonging to the currently focused group. It@@ -271,29 +301,36 @@             let gs' = updateGroup st $ toGroups osls                 st' = W.filter (`elem` M.keys gs') =<< st             updateWs gs'-            runLayout (W.Workspace i la st') r+            oldStack <- gets $ W.stack . W.workspace . W.current . windowset+            setStack st'+            runLayout (W.Workspace i la st') r <* setStack oldStack+            -- FIXME: merge back reordering, deletions?      redoLayout (Sublayout { delayMess = I ms, def = defl, subls = osls }) _r st arrs = do         let gs' = updateGroup st $ toGroups osls         sls <- fromGroups defl st gs' osls -        let newL :: LayoutClass l Window => Rectangle -> WorkspaceId -> (l Window,Bool)+        let newL :: LayoutClass l Window => Rectangle -> WorkspaceId -> (l Window) -> Bool                     -> (Maybe (W.Stack Window)) -> X ([(Window, Rectangle)], l Window)-            newL rect n (ol, mess) sst = do+            newL rect n ol isNew sst = do+                orgStack <- currentStack                 let handle l (y,_)-                        | mess = fromMaybe l <$> handleMessage l y+                        | not isNew = fromMaybe l <$> handleMessage l y                         | otherwise = return l                     kms = filter ((`elem` M.keys gs') . snd) ms+                setStack sst                 nl <- foldM handle ol $ filter ((`elem` W.integrate' sst) . snd) kms-                fmap (fromMaybe nl) <$> runLayout (W.Workspace n nl sst) rect+                result <- runLayout (W.Workspace n nl sst) rect+                setStack orgStack -- FIXME: merge back reordering, deletions?+                return $ fromMaybe nl `second` result -            (urls,ssts) = unzip [ (newL gr i l sst, sst)-                    | l <- map (second $ const True) sls+            (urls,ssts) = unzip [ (newL gr i l isNew sst, sst)+                    | (isNew,(l,_st)) <- sls                     | i <- map show [ 0 :: Int .. ]                     | (k,gr) <- arrs, let sst = M.lookup k gs' ]          arrs' <- sequence urls-        sls' <- return . Sublayout (I []) defl <$> fromGroups defl st gs'+        sls' <- return . Sublayout (I []) defl . map snd <$> fromGroups defl st gs'                         [ (l,s) | (_,l) <- arrs' | (Just s) <- ssts ]         return (concatMap fst arrs', sls') @@ -333,23 +370,32 @@             in fgs $ M.unions $ map mkSingleton ws          | Just (Merge x y) <- fromMessage m-        , let findGrp z = mplus (M.lookup z gs) $ listToMaybe-                $ M.elems $ M.filter ((z `elem`) . W.integrate) gs-        , Just (W.Stack _ xb xn) <- findGrp x-        , Just yst <- findGrp y =+        , Just (W.Stack _ xb xn) <- findGroup x+        , Just yst <- findGroup y =             let zs = W.Stack x xb (xn ++ W.integrate yst)-            in fgs $ M.update (\_ -> Just zs) x $ M.delete y gs+            in fgs $ M.insert x zs $ M.delete (W.focus yst) gs          | Just (UnMerge x) <- fromMessage m =             fgs . M.fromList . map (W.focus &&& id) . M.elems                     $ M.mapMaybe (W.filter (x/=)) gs +        -- XXX sometimes this migrates an incorrect window, why?+        | Just (Migrate x y) <- fromMessage m+        , Just xst <- findGroup x+        , Just (W.Stack yf yu yd) <- findGroup y =+            let zs = W.Stack x (yf:yu) yd+                nxsAdd = maybe id (\e -> M.insert (W.focus e) e) $ W.filter (x/=) xst+            in fgs $ nxsAdd $ M.insert x zs $ M.delete yf gs++         | otherwise = fmap join $ sequenceA $ catchLayoutMess <$> fromMessage m      where gs = toGroups sls            fgs gs' = do                 st <- currentStack-                Just . Sublayout (I ms) defl <$> fromGroups defl st gs' sls+                Just . Sublayout (I ms) defl . map snd <$> fromGroups defl st gs' sls +           findGroup z = mplus (M.lookup z gs) $ listToMaybe+                    $ M.elems $ M.filter ((z `elem`) . W.integrate) gs            -- catchLayoutMess :: LayoutMessages -> X (Maybe (Sublayout l Window))            --  This l must be the same as from the instance head,            --  -XScopedTypeVariables should bring it into scope, but we are@@ -431,7 +477,7 @@               -> Maybe (W.Stack k)               -> Groups k               -> [(layout a, b)]-              -> X [(layout a, W.Stack k)]+              -> X [(Bool,(layout a, W.Stack k))] fromGroups (skips,defl) st gs sls = do     defls <- mapM (iterateM nextL defl !!) skips     return $ fromGroups' defl defls st gs (map fst sls)@@ -439,12 +485,19 @@               iterateM f = iterate (>>= f) . return  fromGroups' :: (Ord k) => a -> [a] -> Maybe (W.Stack k) -> Groups k -> [a]-                    -> [(a, W.Stack k)]+                    -> [(Bool,(a, W.Stack k))] fromGroups' defl defls st gs sls =-    [ fromMaybe2 (dl, single w) (l, M.lookup w gs)-        | l <- map Just sls ++ repeat Nothing+    [ (isNew,fromMaybe2 (dl, single w) (l, M.lookup w gs))+        | l <- map Just sls ++ repeat Nothing, let isNew = isNothing l         | dl <- defls ++ repeat defl         | w <- W.integrate' $ W.filter (`notElem` unfocs) =<< st ]     where unfocs = unfocused =<< M.elems gs           single w = W.Stack w [] []           fromMaybe2 (a,b) (x,y) = (fromMaybe a x, fromMaybe b y)+++-- this would be much cleaner with some kind of data-accessor+setStack :: Maybe (W.Stack Window) -> X ()+setStack x = modify (\s -> s { windowset = (windowset s)+                { W.current = (W.current $ windowset s)+                { W.workspace = (W.workspace $ W.current $ windowset s) { W.stack = x }}}})
XMonad/Layout/TabBarDecoration.hs view
@@ -66,6 +66,7 @@ instance Eq a => DecorationStyle TabBarDecoration a where     describeDeco  _ = "TabBar"     shrink    _ _ r = r+    decorationCatchClicksHook _ mainw _ _ = focus mainw >> return True     pureDecoration (TabBar p) _ dht (Rectangle x y wh ht) s _ (w,_) =         if isInStack s w then Just $ Rectangle nx ny wid (fi dht) else Nothing         where wrs = S.integrate s
XMonad/Layout/Tabbed.hs view
@@ -6,7 +6,7 @@ -- Copyright   :  (c) 2007 David Roundy, Andrea Rossato -- License     :  BSD-style (see xmonad/LICENSE) ----- Maintainer  :  droundy@darcs.net, andrea.rossato@unibz.it+-- Maintainer  :  andrea.rossato@unibz.it -- Stability   :  unstable -- Portability :  unportable --@@ -28,7 +28,6 @@     , Shrinker(..)     ) where -import Data.Maybe import Data.List  import XMonad@@ -43,19 +42,23 @@ -- -- Then edit your @layoutHook@ by adding the Tabbed layout: ----- > myLayouts = simpleTabbed ||| Full ||| etc..+-- > myLayout = simpleTabbed ||| Full ||| etc.. -- -- or, if you want a specific theme for you tabbed layout: ----- > myLayouts = tabbed shrinkText defaultTheme ||| Full ||| etc..+-- > myLayout = tabbed shrinkText defaultTheme ||| Full ||| etc.. -- -- and then: ----- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > main = xmonad defaultConfig { layoutHook = myLayout } --+-- This layout has hardcoded behaviour for mouse clicks on tab decorations:+-- Left click on the tab switches focus to that window.+-- Middle click on the tab closes the window.+-- -- The default Tabbar behaviour is to hide it when only one window is open -- on the workspace.  To have it always shown, use one of the layouts or--- modifiers ending in "Always".+-- modifiers ending in @Always@. -- -- For more detailed instructions on editing the layoutHook see: --@@ -77,7 +80,7 @@ -- This is a minimal working configuration: -- -- > import XMonad--- > import XMonad.Layout.DecorationMadness+-- > import XMonad.Layout.Tabbed -- > main = xmonad defaultConfig { layoutHook = simpleTabbed } simpleTabbed :: ModifiedLayout (Decoration TabbedDecoration DefaultShrinker) Simplest Window simpleTabbed = tabbed shrinkText defaultTheme@@ -95,21 +98,21 @@  -- | A layout decorated with tabs and the possibility to set a custom -- shrinker and theme.-tabbed     :: (Eq a, Shrinker s) => s -> Theme +tabbed     :: (Eq a, Shrinker s) => s -> Theme            -> ModifiedLayout (Decoration TabbedDecoration s) Simplest a tabbed s c = addTabs s c Simplest -tabbedAlways     :: (Eq a, Shrinker s) => s -> Theme +tabbedAlways     :: (Eq a, Shrinker s) => s -> Theme                  -> ModifiedLayout (Decoration TabbedDecoration s) Simplest a tabbedAlways s c = addTabsAlways s c Simplest  -- | A layout decorated with tabs at the bottom and the possibility to set a custom -- shrinker and theme.-tabbedBottom     :: (Eq a, Shrinker s) => s -> Theme +tabbedBottom     :: (Eq a, Shrinker s) => s -> Theme                  -> ModifiedLayout (Decoration TabbedDecoration s) Simplest a tabbedBottom s c = addTabsBottom s c Simplest -tabbedBottomAlways     :: (Eq a, Shrinker s) => s -> Theme +tabbedBottomAlways     :: (Eq a, Shrinker s) => s -> Theme                        -> ModifiedLayout (Decoration TabbedDecoration s) Simplest a tabbedBottomAlways s c = addTabsBottomAlways s c Simplest @@ -151,7 +154,17 @@ instance Eq a => DecorationStyle TabbedDecoration a where     describeDeco (Tabbed Top _ ) = "Tabbed"     describeDeco (Tabbed Bottom _ ) = "Tabbed Bottom"-    pureDecoration (Tabbed lc sh) _ ht _ s wrs (w,r@(Rectangle x y wh hh)) +    decorationEventHook _ ds ButtonEvent { ev_window     = ew+                                         , ev_event_type = et+                                         , ev_button     = eb }+        | et == buttonPress+        , Just ((w,_),_) <-findWindowByDecoration ew ds =+           if eb == button2+               then killWindow w+               else focus w+    decorationEventHook _ _ _ = return ()++    pureDecoration (Tabbed lc sh) _ ht _ s wrs (w,r@(Rectangle x y wh hh))         = if ((sh == Always && numWindows > 0) || numWindows > 1)           then Just $ case lc of                         Top -> upperTab@@ -164,7 +177,7 @@               upperTab = Rectangle nx y wid (fi ht)               lowerTab = Rectangle nx (y+fi(hh-ht)) wid (fi ht)               numWindows = length ws-    shrink (Tabbed loc _ ) (Rectangle _ _ _ dh) (Rectangle x y w h) +    shrink (Tabbed loc _ ) (Rectangle _ _ _ dh) (Rectangle x y w h)         = case loc of             Top -> Rectangle x (y + fi dh) w (h - dh)             Bottom -> Rectangle x y w (h - dh)
XMonad/Layout/ThreeColumns.hs view
@@ -13,14 +13,14 @@ -- A layout similar to tall but with three columns. With 2560x1600 pixels this -- layout can be used for a huge main window and up to six reasonable sized -- slave windows.------ Screenshot: <http://server.c-otto.de/xmonad/ThreeColumnsMiddle.png>--- -----------------------------------------------------------------------------  module XMonad.Layout.ThreeColumns (                               -- * Usage                               -- $usage++                              -- * Screenshots+                              -- $screenshot                               ThreeCol(..)                              ) where @@ -38,10 +38,10 @@ -- -- Then edit your @layoutHook@ by adding the ThreeCol layout: ----- > myLayouts = ThreeCol 1 (3/100) (1/2) ||| ThreeColMid 1 (3/100) (1/2) ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = ThreeCol 1 (3/100) (1/2) ||| ThreeColMid 1 (3/100) (1/2) ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } ----- The first argument specifies hom many windows initially appear in the main+-- The first argument specifies how many windows initially appear in the main -- window. The second argument argument specifies the amount to resize while -- resizing and the third argument specifies the initial size of the columns. -- A positive size designates the fraction of the screen that the main window@@ -55,6 +55,10 @@ -- -- "XMonad.Doc.Extending#Editing_the_layout_hook" ++-- $screenshot+-- <<http://server.c-otto.de/xmonad/ThreeColumnsMiddle.png>>+ -- | Arguments are nmaster, delta, fraction data ThreeCol a = ThreeColMid { threeColNMaster :: !Int, threeColDelta :: !Rational, threeColFrac :: !Rational}                 | ThreeCol    { threeColNMaster :: !Int, threeColDelta :: !Rational, threeColFrac :: !Rational}@@ -92,9 +96,9 @@ split3HorizontallyBy :: Bool -> Rational -> Rectangle -> (Rectangle, Rectangle, Rectangle) split3HorizontallyBy middle f (Rectangle sx sy sw sh) =     if middle-    then ( Rectangle (sx + fromIntegral r2w) sy r1w sh-         , Rectangle sx sy r2w sh-         , Rectangle (sx + fromIntegral r2w + fromIntegral r1w) sy r3w sh )+    then ( Rectangle (sx + fromIntegral r3w) sy r1w sh+         , Rectangle (sx + fromIntegral r3w + fromIntegral r1w) sy r2w sh+         , Rectangle sx sy r3w sh )     else ( Rectangle sx sy r1w sh          , Rectangle (sx + fromIntegral r1w) sy r2w sh          , Rectangle (sx + fromIntegral r1w + fromIntegral r2w) sy r3w sh )
− XMonad/Layout/ThreeColumnsMiddle.hs
@@ -1,4 +0,0 @@-module XMonad.Layout.ThreeColumnsMiddle {-# DEPRECATED "Import XMonad.Layout.ThreeColumns instead" #-}-    (module XMonad.Layout.ThreeColumns) where--import XMonad.Layout.ThreeColumns (ThreeCol(ThreeColMid))
XMonad/Layout/ToggleLayouts.hs view
@@ -1,5 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}  ----------------------------------------------------------------------------- -- |@@ -30,8 +29,8 @@ -- -- Then edit your @layoutHook@ by adding the ToggleLayouts layout: ----- > myLayouts = toggleLayouts Full (Tall 1 (3/100) (1/2)) ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = toggleLayouts Full (Tall 1 (3/100) (1/2)) ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -39,11 +38,11 @@ -- -- To toggle between layouts add a key binding like ----- >    , ((modMask x .|. controlMask, xK_space), sendMessage ToggleLayout)+-- >    , ((modm .|. controlMask, xK_space), sendMessage ToggleLayout) -- -- or a key binding like ----- >    , ((modMask x .|. controlMask, xK_space), sendMessage (Toggle "Full"))+-- >    , ((modm .|. controlMask, xK_space), sendMessage (Toggle "Full")) -- -- For detailed instruction on editing the key binding see: --
XMonad/Layout/TwoPane.hs view
@@ -5,7 +5,7 @@ -- Module      :  XMonad.Layout.TwoPane -- Copyright   :  (c) Spencer Janssen <spencerjanssen@gmail.com> -- License     :  BSD3-style (see LICENSE)--- +-- -- Maintainer  :  Spencer Janssen <spencerjanssen@gmail.com> -- Stability   :  unstable -- Portability :  unportable@@ -32,15 +32,15 @@ -- -- Then edit your @layoutHook@ by adding the TwoPane layout: ----- > myLayouts = TwoPane (3/100) (1/2)  ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = TwoPane (3/100) (1/2)  ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: -- -- "XMonad.Doc.Extending#Editing_the_layout_hook" -data TwoPane a = -    TwoPane Rational Rational +data TwoPane a =+    TwoPane Rational Rational     deriving ( Show, Read )  instance LayoutClass TwoPane a where@@ -53,7 +53,7 @@                                       [] -> [(focus st, rect)]               where (left, right) = splitHorizontallyBy split rect -    handleMessage (TwoPane delta split) x = +    handleMessage (TwoPane delta split) x =         return $ case fromMessage x of                    Just Shrink -> Just (TwoPane delta (split - delta))                    Just Expand -> Just (TwoPane delta (split + delta))
XMonad/Layout/WindowArranger.hs view
@@ -1,8 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- for deriving Typeable-{-# LANGUAGE PatternGuards           #-}-{-# LANGUAGE FlexibleInstances       #-}-{-# LANGUAGE MultiParamTypeClasses   #-}-{-# LANGUAGE TypeSynonymInstances    #-}+{-# LANGUAGE DeriveDataTypeable, PatternGuards, FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances    #-} ----------------------------------------------------------------------------- -- | -- Module      :  XMonad.Layout.WindowArranger@@ -36,7 +32,6 @@  import Control.Arrow import Data.List-import Data.Maybe  -- $usage -- You can use this module with the following in your@@ -57,31 +52,31 @@ -- You may also want to define some key binding to move or resize -- windows. These are good defaults: ----- >        , ((modMask x .|. controlMask              , xK_s    ), sendMessage  Arrange         )--- >        , ((modMask x .|. controlMask .|. shiftMask, xK_s    ), sendMessage  DeArrange       )--- >        , ((modMask x .|. controlMask              , xK_Left ), sendMessage (MoveLeft      1))--- >        , ((modMask x .|. controlMask              , xK_Right), sendMessage (MoveRight     1))--- >        , ((modMask x .|. controlMask              , xK_Down ), sendMessage (MoveDown      1))--- >        , ((modMask x .|. controlMask              , xK_Up   ), sendMessage (MoveUp        1))--- >        , ((modMask x                 .|. shiftMask, xK_Left ), sendMessage (IncreaseLeft  1))--- >        , ((modMask x                 .|. shiftMask, xK_Right), sendMessage (IncreaseRight 1))--- >        , ((modMask x                 .|. shiftMask, xK_Down ), sendMessage (IncreaseDown  1))--- >        , ((modMask x                 .|. shiftMask, xK_Up   ), sendMessage (IncreaseUp    1))--- >        , ((modMask x .|. controlMask .|. shiftMask, xK_Left ), sendMessage (DecreaseLeft  1))--- >        , ((modMask x .|. controlMask .|. shiftMask, xK_Right), sendMessage (DecreaseRight 1))--- >        , ((modMask x .|. controlMask .|. shiftMask, xK_Down ), sendMessage (DecreaseDown  1))--- >        , ((modMask x .|. controlMask .|. shiftMask, xK_Up   ), sendMessage (DecreaseUp    1))+-- >        , ((modm .|. controlMask              , xK_s    ), sendMessage  Arrange         )+-- >        , ((modm .|. controlMask .|. shiftMask, xK_s    ), sendMessage  DeArrange       )+-- >        , ((modm .|. controlMask              , xK_Left ), sendMessage (MoveLeft      1))+-- >        , ((modm .|. controlMask              , xK_Right), sendMessage (MoveRight     1))+-- >        , ((modm .|. controlMask              , xK_Down ), sendMessage (MoveDown      1))+-- >        , ((modm .|. controlMask              , xK_Up   ), sendMessage (MoveUp        1))+-- >        , ((modm                 .|. shiftMask, xK_Left ), sendMessage (IncreaseLeft  1))+-- >        , ((modm                 .|. shiftMask, xK_Right), sendMessage (IncreaseRight 1))+-- >        , ((modm                 .|. shiftMask, xK_Down ), sendMessage (IncreaseDown  1))+-- >        , ((modm                 .|. shiftMask, xK_Up   ), sendMessage (IncreaseUp    1))+-- >        , ((modm .|. controlMask .|. shiftMask, xK_Left ), sendMessage (DecreaseLeft  1))+-- >        , ((modm .|. controlMask .|. shiftMask, xK_Right), sendMessage (DecreaseRight 1))+-- >        , ((modm .|. controlMask .|. shiftMask, xK_Down ), sendMessage (DecreaseDown  1))+-- >        , ((modm .|. controlMask .|. shiftMask, xK_Up   ), sendMessage (DecreaseUp    1)) -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".  -- | A layout modifier to float the windows in a workspace windowArrange :: l a -> ModifiedLayout WindowArranger l a-windowArrange = ModifiedLayout (WA True False Nothing [])+windowArrange = ModifiedLayout (WA True False [])  -- | A layout modifier to float all the windows in a workspace windowArrangeAll :: l a -> ModifiedLayout WindowArranger l a-windowArrangeAll = ModifiedLayout (WA True True Nothing [])+windowArrangeAll = ModifiedLayout (WA True True [])  data WindowArrangerMsg = DeArrange                        | Arrange@@ -106,22 +101,21 @@                         deriving (Read, Show)  type ArrangeAll = Bool-data WindowArranger a = WA Bool ArrangeAll (Maybe Rectangle) [ArrangedWindow a] deriving (Read, Show)+data WindowArranger a = WA Bool ArrangeAll [ArrangedWindow a] deriving (Read, Show)  instance (Show a, Read a, Eq a) => LayoutModifier WindowArranger a where-    pureModifier (WA True b _   []) sr (Just _)               wrs = arrangeWindows b sr wrs+    pureModifier (WA True b   []) _ (Just _)               wrs = arrangeWindows b wrs -    pureModifier (WA True b maybeSr awrs) sr (Just (S.Stack w _ _)) wrs = curry process wrs awrs'+    pureModifier (WA True b awrs) _ (Just (S.Stack w _ _)) wrs = curry process wrs awrs         where-          (maybeSr', awrs') = adjustForNewScreenRectangle sr maybeSr awrs           wins         = map fst       *** map awrWin           update (a,r) = mkNewAWRs b a *** removeAWRs r >>> uncurry (++)           process      = wins &&&  id  >>> first diff   >>> uncurry update >>>-                         replaceWR wrs >>> putOnTop w   >>> map fromAWR &&& Just . WA True b maybeSr'+                         replaceWR wrs >>> putOnTop w   >>> map fromAWR &&& Just . WA True b      pureModifier _ _ _ wrs = (wrs, Nothing) -    pureMess (WA True b maybeSr (wr:wrs)) m+    pureMess (WA True b (wr:wrs)) m         -- increase the window's size         | Just (IncreaseRight i) <- fm, (win, Rectangle x y w h) <- fa = res win  x         y        (w + fi i) h         | Just (IncreaseLeft  i) <- fm, (win, Rectangle x y w h) <- fa = res win (x - fi i) y        (w + fi i) h@@ -138,35 +132,21 @@         | Just (MoveUp        i) <- fm, (win, Rectangle x y w h) <- fa = res win  x        (y - fi i) w         h         | Just (MoveDown      i) <- fm, (win, Rectangle x y w h) <- fa = res win  x        (y + fi i) w         h -        where res wi x y w h = Just . WA True b maybeSr $ AWR (wi,Rectangle x y w h):wrs+        where res wi x y w h = Just . WA True b $ AWR (wi,Rectangle x y w h):wrs               fm             = fromMessage m               fa             = fromAWR     wr               chk        x y = fi $ max 1 (fi x - y) -    pureMess (WA t b maybeSr (wr:wrs)) m-        | Just (SetGeometry   r) <- fromMessage m, (w,_) <- fromAWR wr = Just . WA t b maybeSr $ AWR (w,r):wrs+    pureMess (WA t b (wr:wrs)) m+        | Just (SetGeometry   r) <- fromMessage m, (w,_) <- fromAWR wr = Just . WA t b $ AWR (w,r):wrs -    pureMess (WA _ b maybeSr l) m-        | Just DeArrange <- fromMessage m = Just $ WA False b maybeSr l-        | Just Arrange   <- fromMessage m = Just $ WA True  b maybeSr l+    pureMess (WA _ b l) m+        | Just DeArrange <- fromMessage m = Just $ WA False b l+        | Just Arrange   <- fromMessage m = Just $ WA True  b l         | otherwise                       = Nothing -adjustForNewScreenRectangle :: Rectangle -> (Maybe Rectangle) -> [ArrangedWindow a] -> (Maybe Rectangle, [ArrangedWindow a])-adjustForNewScreenRectangle sr Nothing awrs = (Just sr, awrs)-adjustForNewScreenRectangle sr@(Rectangle x y _ _) (Just oldSr@(Rectangle oldX oldY _ _)) awrs-    | (sr == oldSr)     = (Just sr, awrs)-    | otherwise         = (Just sr, map (adjustRectangle offsetX offsetY) awrs)-    where-        offsetX = x - oldX-        offsetY = y - oldY--adjustRectangle :: Position -> Position -> ArrangedWindow a -> ArrangedWindow a-adjustRectangle _ _ (WR x) = (WR x)-adjustRectangle offsetX offsetY (AWR (win, Rectangle x y w h)) =-                             (AWR (win, Rectangle (x + offsetX) (y + offsetY) w h))--arrangeWindows :: ArrangeAll -> Rectangle -> [(a,Rectangle)] -> ([(a, Rectangle)], Maybe (WindowArranger a))-arrangeWindows b sr wrs = (wrs, Just $ WA True b (Just sr) (map t wrs))+arrangeWindows :: ArrangeAll -> [(a,Rectangle)] -> ([(a, Rectangle)], Maybe (WindowArranger a))+arrangeWindows b wrs = (wrs, Just $ WA True b (map t wrs))     where t = if b then AWR else WR  fromAWR :: ArrangedWindow a -> (a, Rectangle)@@ -218,7 +198,7 @@ memberFromList f g l = foldr (h l) []     where h x y ys = if g (f y) x then [y] else ys --- | Get the list of elements to be deleted and the list ef elements to+-- | Get the list of elements to be deleted and the list of elements to -- be added to the first list in order to get the second list. diff :: Eq a => ([a],[a]) -> ([a],[a]) diff (x,y) = (x \\ y, y \\ x)
XMonad/Layout/WindowNavigation.hs view
@@ -1,5 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeSynonymInstances #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeSynonymInstances, PatternGuards #-}  ----------------------------------------------------------------------------- -- |@@ -19,7 +18,7 @@                                    -- * Usage                                    -- $usage                                    windowNavigation, configurableNavigation,-                                   Navigate(..), Direction(..),+                                   Navigate(..), Direction2D(..),                                    MoveWindowToWindow(..),                                    navigateColor, navigateBrightness,                                    noNavigateBorders, defaultWNConfig@@ -30,10 +29,9 @@ import qualified XMonad.StackSet as W import XMonad.Layout.LayoutModifier import XMonad.Util.Invisible+import XMonad.Util.Types (Direction2D(..)) import XMonad.Util.XUtils -import XMonad.Hooks.ManageDocks (Direction(..))- -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: --@@ -42,8 +40,8 @@ -- Then edit your @layoutHook@ by adding the WindowNavigation layout modifier -- to some layout: ----- > myLayouts = windowNavigation (Tall 1 (3/100) (1/2))  ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = windowNavigation (Tall 1 (3/100) (1/2))  ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -51,14 +49,14 @@ -- -- In keybindings: ----- >    , ((modMask x,                 xK_Right), sendMessage $ Go R)--- >    , ((modMask x,                 xK_Left ), sendMessage $ Go L)--- >    , ((modMask x,                 xK_Up   ), sendMessage $ Go U)--- >    , ((modMask x,                 xK_Down ), sendMessage $ Go D)--- >    , ((modMask x .|. controlMask, xK_Right), sendMessage $ Swap R)--- >    , ((modMask x .|. controlMask, xK_Left ), sendMessage $ Swap L)--- >    , ((modMask x .|. controlMask, xK_Up   ), sendMessage $ Swap U)--- >    , ((modMask x .|. controlMask, xK_Down ), sendMessage $ Swap D)+-- >    , ((modm,                 xK_Right), sendMessage $ Go R)+-- >    , ((modm,                 xK_Left ), sendMessage $ Go L)+-- >    , ((modm,                 xK_Up   ), sendMessage $ Go U)+-- >    , ((modm,                 xK_Down ), sendMessage $ Go D)+-- >    , ((modm .|. controlMask, xK_Right), sendMessage $ Swap R)+-- >    , ((modm .|. controlMask, xK_Left ), sendMessage $ Swap L)+-- >    , ((modm .|. controlMask, xK_Up   ), sendMessage $ Swap U)+-- >    , ((modm .|. controlMask, xK_Down ), sendMessage $ Swap D) -- -- For detailed instruction on editing the key binding see: --@@ -68,8 +66,8 @@ data MoveWindowToWindow a = MoveWindowToWindow a a deriving ( Read, Show, Typeable ) instance Typeable a => Message (MoveWindowToWindow a) -data Navigate = Go Direction | Swap Direction | Move Direction-              | Apply (Window -> X()) Direction -- ^ Apply action with destination window+data Navigate = Go Direction2D | Swap Direction2D | Move Direction2D+              | Apply (Window -> X()) Direction2D -- ^ Apply action with destination window         deriving ( Typeable ) instance Message Navigate @@ -90,9 +88,7 @@     WNC Nothing c c c c  navigateBrightness :: Double -> WNConfig-navigateBrightness f | f > 1 = navigateBrightness 1-                     | f < 0 = navigateBrightness 0-navigateBrightness f = defaultWNConfig { brightness = Just f }+navigateBrightness f = defaultWNConfig { brightness = Just $ max 0 $ min 1 f }  defaultWNConfig :: WNConfig defaultWNConfig = WNC (Just 0.4) "#0000FF" "#00FFFF" "#FF0000" "#FF00FF"@@ -129,10 +125,10 @@                wrs = filter ((`elem` existing_wins) . fst) $ filter ((/=r) . snd) $                      filter ((/=w) . fst) origwrs                wnavigable = nub $ concatMap-                            (\d -> truncHead $ navigable d pt wrs) [U,D,R,L]+                            (\d -> take 1 $ navigable d pt wrs) [U,D,R,L]                wnavigablec = nub $ concatMap                             (\d -> map (\(win,_) -> (win,dirc d)) $-                                   truncHead $ navigable d pt wrs) [U,D,R,L]+                                   take 1 $ navigable d pt wrs) [U,D,R,L]                wothers = case state of Just (NS _ wo) -> map fst wo                                        _              -> []            mapM_ (sc nbc) (wothers \\ map fst wnavigable)@@ -191,24 +187,20 @@                handleMessOrMaybeModifyIt (WindowNavigation conf (I $ Just (NS pt wrs))) (SomeMessage Hide)     handleMessOrMaybeModifyIt _ _ = return Nothing -navigable :: Direction -> Point -> [(Window, Rectangle)] -> [(Window, Rectangle)]+navigable :: Direction2D -> Point -> [(Window, Rectangle)] -> [(Window, Rectangle)] navigable d pt = sortby d . filter (inr d pt . snd) -truncHead :: [a] -> [a]-truncHead (x:_) = [x]-truncHead [] = []- sc :: Pixel -> Window -> X () sc c win = withDisplay $ \dpy -> io $ setWindowBorder dpy win c  center :: Rectangle -> Point center (Rectangle x y w h) = P (fromIntegral x + fromIntegral w/2)  (fromIntegral y + fromIntegral h/2) -centerd :: Direction -> Point -> Rectangle -> Point+centerd :: Direction2D -> Point -> Rectangle -> Point centerd d (P xx yy) (Rectangle x y w h) | d == U || d == D = P xx (fromIntegral y + fromIntegral h/2)                                         | otherwise = P (fromIntegral x + fromIntegral w/2) yy -inr :: Direction -> Point -> Rectangle -> Bool+inr :: Direction2D -> Point -> Rectangle -> Bool inr D (P x y) (Rectangle l yr w h) = x >= fromIntegral l && x < fromIntegral l + fromIntegral w &&                                      y <  fromIntegral yr + fromIntegral h inr U (P x y) (Rectangle l yr w _) = x >= fromIntegral l && x < fromIntegral l + fromIntegral w &&@@ -222,7 +214,7 @@ inrect (P x y) (Rectangle a b w h) = x >  fromIntegral a && x < fromIntegral a + fromIntegral w &&                                      y >  fromIntegral b && y < fromIntegral b + fromIntegral h -sortby :: Direction -> [(a,Rectangle)] -> [(a,Rectangle)]+sortby :: Direction2D -> [(a,Rectangle)] -> [(a,Rectangle)] sortby U = sortBy (\(_,Rectangle _ y _ _) (_,Rectangle _ y' _ _) -> compare y' y) sortby D = sortBy (\(_,Rectangle _ y _ _) (_,Rectangle _ y' _ _) -> compare y y') sortby R = sortBy (\(_,Rectangle x _ _ _) (_,Rectangle x' _ _ _) -> compare x x')
XMonad/Layout/WindowSwitcherDecoration.hs view
@@ -9,32 +9,71 @@ -- Stability   :  unstable -- Portability :  not portable --+-- A decoration that allows to switch the position of windows by dragging+-- them onto each other.+-- -----------------------------------------------------------------------------  module XMonad.Layout.WindowSwitcherDecoration-    ( windowSwitcherDecoration+    ( -- * Usage:+      -- $usage+      windowSwitcherDecoration,+      windowSwitcherDecorationWithButtons     ) where  import XMonad import XMonad.Layout.Decoration+import XMonad.Layout.DecorationAddons import XMonad.Layout.DraggingVisualizer import qualified XMonad.StackSet as S import Control.Monad import Foreign.C.Types(CInt) +-- $usage+-- You can use this module with the following in your+-- @~\/.xmonad\/xmonad.hs@:+--+-- > import XMonad.Layout.WindowSwitcherDecoration+-- > import XMonad.Layout.DraggingVisualizer+--+-- Then edit your @layoutHook@ by adding the WindowSwitcherDecoration to+-- your layout:+--+-- > myL = windowSwitcherDecoration shrinkText defaultTheme (draggingVisualizer $ layoutHook defaultConfig)+-- > main = xmonad defaultConfig { layoutHook = myL }+--+-- There is also a version of the decoration that contains buttons like+-- "XMonad.Layout.ButtonDecoration". To use that version, you will need to+-- import "XMonad.Layout.DecorationAddons" as well and modify your @layoutHook@+-- in the following way:+--+-- > import XMonad.Layout.DecorationAddons+-- >+-- > myL = windowSwitcherDecorationWithButtons shrinkText defaultThemeWithButtons (draggingVisualizer $ layoutHook defaultConfig)+-- > main = xmonad defaultConfig { layoutHook = myL }+--+ windowSwitcherDecoration :: (Eq a, Shrinker s) => s -> Theme            -> l a -> ModifiedLayout (Decoration WindowSwitcherDecoration s) l a-windowSwitcherDecoration s c = decoration s c $ WindowSwitcherDecoration+windowSwitcherDecoration s c = decoration s c $ WSD False -data WindowSwitcherDecoration a = WindowSwitcherDecoration deriving (Show, Read)+windowSwitcherDecorationWithButtons :: (Eq a, Shrinker s) => s -> Theme+           -> l a -> ModifiedLayout (Decoration WindowSwitcherDecoration s) l a+windowSwitcherDecorationWithButtons s c = decoration s c $ WSD True +data WindowSwitcherDecoration a = WSD Bool deriving (Show, Read)+ instance Eq a => DecorationStyle WindowSwitcherDecoration a where     describeDeco _ = "WindowSwitcherDeco" +    decorationCatchClicksHook (WSD withButtons) mainw dFL dFR = if withButtons+                                                                    then titleBarButtonHandler mainw dFL dFR+                                                                    else return False     decorationWhileDraggingHook _ ex ey (mainw, r) x y = handleTiledDraggingInProgress ex ey (mainw, r) x y-    decorationAfterDraggingHookAddon _ (mainw, _) hasCrossed = unless hasCrossed $ do-                                                                 sendMessage $ DraggingStopped-                                                                 performWindowSwitching mainw+    decorationAfterDraggingHook _ (mainw, _) decoWin = do focus mainw+                                                          hasCrossed <- handleScreenCrossing mainw decoWin+                                                          unless hasCrossed $ do sendMessage $ DraggingStopped+                                                                                 performWindowSwitching mainw  handleTiledDraggingInProgress :: CInt -> CInt -> (Window, Rectangle) -> Position -> Position -> X () handleTiledDraggingInProgress ex ey (mainw, r) x y = do
XMonad/Layout/WorkspaceDir.hs view
@@ -1,5 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances, PatternGuards #-}  ----------------------------------------------------------------------------- -- |@@ -47,8 +46,8 @@ -- Then edit your @layoutHook@ by adding the Workspace layout modifier -- to some layout: ----- > myLayouts = workspaceDir "~" (Tall 1 (3/100) (1/2))  ||| Full ||| etc..--- > main = xmonad defaultConfig { layoutHook = myLayouts }+-- > myLayout = workspaceDir "~" (Tall 1 (3/100) (1/2))  ||| Full ||| etc..+-- > main = xmonad defaultConfig { layoutHook = myLayout } -- -- For more detailed instructions on editing the layoutHook see: --@@ -57,7 +56,7 @@ -- WorkspaceDir provides also a prompt. To use it you need to import -- "XMonad.Prompt" and add something like this to your key bindings: ----- >  , ((modMask x .|. shiftMask, xK_x     ), changeDir defaultXPConfig)+-- >  , ((modm .|. shiftMask, xK_x     ), changeDir defaultXPConfig) -- -- For detailed instruction on editing the key binding see: --
XMonad/Prompt.hs view
@@ -25,6 +25,15 @@     , XPPosition (..)     , XPConfig (..)     , XPrompt (..)+    , XP+    , defaultXPKeymap+    , quit+    , killBefore, killAfter, startOfLine, endOfLine+    , pasteString, moveCursor+    , setInput, getInput+    , moveWord, killWord, deleteString+    , moveHistory, setSuccess, setDone+    , Direction1D(..)     , ComplFunction     -- * X Utilities     -- $xutils@@ -46,35 +55,43 @@     , decodeInput     , encodeOutput     , historyCompletion+    , historyCompletionP     -- * History filters     , deleteAllDuplicates     , deleteConsecutive+    , HistoryMatches+    , initMatches+    , historyUpMatching+    , historyDownMatching     ) where  import Prelude hiding (catch) -import XMonad  hiding (config, io)+import XMonad  hiding (config, cleanMask)+import qualified XMonad as X (numberlockMask) import qualified XMonad.StackSet as W import XMonad.Util.Font+import XMonad.Util.Types import XMonad.Util.XSelection (getSelection)+import XMonad.Util.XUtils (fi) -import Control.Arrow ((&&&))+import Control.Arrow ((&&&),first) import Control.Concurrent (threadDelay) import Control.Monad.Reader import Control.Monad.State import Control.Applicative ((<$>)) import Data.Char-import Data.Bits ((.&.))+import Data.Bits import Data.Maybe import Data.List+import Data.IORef import Data.Set (fromList, toList) import System.Directory import System.IO import System.Posix.Files-import Control.Exception hiding (handle)+import Control.Exception.Extensible hiding (handle) -import qualified Data.Map as Map-import Data.Map (Map)+import qualified Data.Map as M  -- $usage -- For usage examples see "XMonad.Prompt.Shell",@@ -102,6 +119,8 @@         , offset             :: !Int         , config             :: XPConfig         , successful         :: Bool+        , numlockMask        :: KeyMask+        , done               :: Bool         }  data XPConfig =@@ -116,12 +135,18 @@         , height            :: !Dimension -- ^ Window height         , historySize       :: !Int       -- ^ The number of history entries to be saved         , historyFilter     :: [String] -> [String]-                                          -- ^ a filter to determine which-                                          -- history entries to remember+                                         -- ^ a filter to determine which+                                         -- history entries to remember+        , promptKeymap      :: M.Map (KeyMask,KeySym) (XP ())+                                         -- ^ Mapping from key combinations to actions+        , completionKey     :: KeySym     -- ^ Key that should trigger completion         , defaultText       :: String     -- ^ The text by default in the prompt line         , autoComplete      :: Maybe Int  -- ^ Just x: if only one completion remains, auto-select it,         , showCompletionOnTab :: Bool     -- ^ Only show list of completions when Tab was pressed                                           --   and delay by x microseconds+        , searchPredicate   :: String -> String -> Bool+                                          -- ^ Given the typed string and a possible+                                          --   completion, is the completion valid?         }  data XPType = forall p . XPrompt p => XPT p@@ -156,12 +181,12 @@     -- string presently in the command line and the list of     -- completion.     nextCompletion :: t -> String -> [String] -> String-    nextCompletion t c l = getNextOfLastWord t c l+    nextCompletion = getNextOfLastWord      -- | This method is used to generate the string to be passed to     -- the completion function.     commandToComplete :: t -> String -> String-    commandToComplete _ c = getLastWord c+    commandToComplete _ = getLastWord      -- | This method is used to process each completion in order to     -- generate the string that will be compared with the command@@ -178,6 +203,7 @@                   deriving (Show,Read)  amberXPConfig, defaultXPConfig, greenXPConfig :: XPConfig+ defaultXPConfig =     XPC { font              = "-misc-fixed-*-*-*-*-12-*-*-*-*-*-*-*"         , bgColor           = "grey22"@@ -186,21 +212,25 @@         , bgHLight          = "grey"         , borderColor       = "white"         , promptBorderWidth = 1+        , promptKeymap      = defaultXPKeymap+        , completionKey     = xK_Tab         , position          = Bottom         , height            = 18         , historySize       = 256         , historyFilter     = id         , defaultText       = []         , autoComplete      = Nothing-        , showCompletionOnTab = False }-greenXPConfig = defaultXPConfig { fgColor = "green", bgColor = "black" }+        , showCompletionOnTab = False+        , searchPredicate   = isPrefixOf+        }+greenXPConfig = defaultXPConfig { fgColor = "green", bgColor = "black", promptBorderWidth = 0 } amberXPConfig = defaultXPConfig { fgColor = "#ca8f2d", bgColor = "black", fgHLight = "#eaaf4c" }  type ComplFunction = String -> IO [String]  initState :: XPrompt p => Display -> Window -> Window -> Rectangle -> ComplFunction-          -> GC -> XMonadFont -> p -> [String] -> XPConfig -> XPState-initState d rw w s compl gc fonts pt h c =+          -> GC -> XMonadFont -> p -> [String] -> XPConfig -> KeyMask -> XPState+initState d rw w s compl gc fonts pt h c nm =     XPS { dpy                = d         , rootw              = rw         , win                = w@@ -218,6 +248,8 @@         , offset             = length (defaultText c)         , config             = c         , successful         = False+        , done               = False+        , numlockMask        = nm         }  -- this would be much easier with functional references@@ -227,6 +259,15 @@ setCommand :: String -> XPState -> XPState setCommand xs s = s { commandHistory = (commandHistory s) { W.focus = xs }} +-- | Sets the input string to the given value.+setInput :: String -> XP ()+setInput = modify . setCommand++-- | Returns the current input string. Intented for use in custom keymaps+-- where the 'get' or similar can't be used to retrieve it.+getInput :: XP String+getInput = gets command+ -- | Same as 'mkXPrompt', except that the action function can have --   type @String -> X a@, for any @a@, and the final action returned --   by 'mkXPromptWithReturn' will have type @X (Maybe a)@.  @Nothing@@@ -235,28 +276,31 @@ --   module. mkXPromptWithReturn :: XPrompt p => p -> XPConfig -> ComplFunction -> (String -> X a)  -> X (Maybe a) mkXPromptWithReturn t conf compl action = do-  c <- ask-  let d = display c-      rw = theRoot c-  s <- gets $ screenRect . W.screenDetail . W.current . windowset-  hist <- liftIO $ readHistory-  w <- liftIO $ createWin d rw conf s-  liftIO $ selectInput d w $ exposureMask .|. keyPressMask-  gc <- liftIO $ createGC d w-  liftIO $ setGraphicsExposures d gc False+  XConf { display = d, theRoot = rw } <- ask+  s    <- gets $ screenRect . W.screenDetail . W.current . windowset+  hist <- io readHistory+  w    <- io $ createWin d rw conf s+  io $ selectInput d w $ exposureMask .|. keyPressMask+  gc <- io $ createGC d w+  io $ setGraphicsExposures d gc False   fs <- initXMF (font conf)-  let hs = fromMaybe [] $ Map.lookup (showXPrompt t) hist-      st = initState d rw w s compl gc fs (XPT t) hs conf-  st' <- liftIO $ execStateT runXP st+  numlock <- gets $ X.numberlockMask+  let hs = fromMaybe [] $ M.lookup (showXPrompt t) hist+      st = initState d rw w s compl gc fs (XPT t) hs conf numlock+  st' <- io $ execStateT runXP st    releaseXMF fs-  liftIO $ freeGC d gc+  io $ freeGC d gc   if successful st'     then do-      liftIO $ writeHistory $ Map.insertWith+      io $ writeHistory $ M.insertWith                                 (\xs ys -> take (historySize conf)                                         . historyFilter conf $ xs ++ ys)-                                (showXPrompt t) [command st'] hist+                                (showXPrompt t) (historyFilter conf [command st'])+                                hist+                                -- we need to apply historyFilter before as well, since+                                -- otherwise the filter would not be applied if+                                -- there is no history       Just <$> action (command st')     else return Nothing @@ -276,8 +320,7 @@  runXP :: XP () runXP = do-  st <- get-  let (d,w) = (dpy &&& win) st+  (d,w) <- gets (dpy &&& win)   status <- io $ grabKeyboard d w True grabModeAsync grabModeAsync currentTime   when (status == grabSuccess) $ do           updateWindows@@ -301,43 +344,54 @@                         else return (Nothing, "")               return (ks,s,ev)   action (fromMaybe xK_VoidSymbol keysym,string) event+  gets done >>= flip unless (eventLoop handle) +-- | Removes numlock and capslock from a keymask.+-- Duplicate of cleanMask from core, but in the+-- XP monad instead of X.+cleanMask :: KeyMask -> XP KeyMask+cleanMask msk = do+  numlock <- gets numlockMask+  let highMasks = 1 `shiftL` 12 - 1+  return (complement (numlock .|. lockMask) .&. msk .&. highMasks)+ -- Main event handler handle :: KeyStroke -> Event -> XP ()-handle k@(ks,_) e@(KeyEvent {ev_event_type = t})-    | t == keyPress && ks == xK_Tab    = do+handle ks@(sym,_) e@(KeyEvent {ev_event_type = t, ev_state = m}) = do+  complKey <- gets $ completionKey . config   c <- getCompletions-  if length c > 1 then modify $ \s -> s { showComplWin = True } else return ()-  completionHandle c k e-handle ks (KeyEvent {ev_event_type = t, ev_state = m})-    | t == keyPress = keyPressHandle m ks+  when (length c > 1) $ modify (\s -> s { showComplWin = True })+  if complKey == sym+     then completionHandle c ks e+     else when (t == keyPress) $ keyPressHandle m ks handle _ (ExposeEvent {ev_window = w}) = do   st <- get   when (win st == w) updateWindows-  eventLoop handle-handle _  _ = eventLoop handle+handle _  _ = return ()  -- completion event handler completionHandle ::  [String] -> KeyStroke -> Event -> XP ()-completionHandle c (ks,_) (KeyEvent {ev_event_type = t})-    | t == keyPress && ks == xK_Tab = do-  st <- get-  let updateState l = do let new_command = nextCompletion (xptype st) (command st) l-                         modify $ \s ->  setCommand new_command $ s { offset = length new_command }-      updateWins  l = do redrawWindows l-                         eventLoop (completionHandle l)-  case c of-    []  -> updateWindows   >> eventLoop handle-    [x] -> updateState [x] >> getCompletions >>= updateWins-    l   -> updateState l   >> updateWins l--- key release-    | t == keyRelease && ks == xK_Tab = eventLoop (completionHandle c)--- other keys-completionHandle _ ks (KeyEvent {ev_event_type = t, ev_state = m})-    | t == keyPress = keyPressHandle m ks+completionHandle c ks@(sym,_) (KeyEvent { ev_event_type = t, ev_state = m }) = do+  complKey <- gets $ completionKey . config+  case () of+    () | t == keyPress && sym == complKey ->+          do+            st <- get+            let updateState l =+                    let new_command = nextCompletion (xptype st) (command st) l+                    in modify $ \s -> setCommand new_command $ s { offset = length new_command }+                updateWins  l = redrawWindows l >>+                                eventLoop (completionHandle l)+            case c of+              []  -> updateWindows   >> eventLoop handle+              [x] -> updateState [x] >> getCompletions >>= updateWins+              l   -> updateState l   >> updateWins l+      | t == keyRelease && sym == complKey -> eventLoop (completionHandle c)+      | otherwise -> keyPressHandle m ks -- some other key, handle it normally -- some other event: go back to main loop completionHandle _ k e = handle k e + tryAutoComplete :: XP Bool tryAutoComplete = do     ac <- gets (autoComplete . config)@@ -358,52 +412,62 @@  -- KeyPresses -data Direction = Prev | Next deriving (Eq,Show,Read)+defaultXPKeymap :: M.Map (KeyMask,KeySym) (XP ())+defaultXPKeymap = M.fromList $+  map (first $ (,) controlMask) -- control + <key>+  [ (xK_u, killBefore)+  , (xK_k, killAfter)+  , (xK_a, startOfLine)+  , (xK_e, endOfLine)+  , (xK_y, pasteString)+  , (xK_Right, moveWord Next)+  , (xK_Left, moveWord Prev)+  , (xK_Delete, killWord Next)+  , (xK_BackSpace, killWord Prev)+  , (xK_w, killWord Prev)+  , (xK_g, quit)+  , (xK_bracketleft, quit)+  ] +++  map (first $ (,) 0)+  [ (xK_Return, setSuccess True >> setDone True)+  , (xK_KP_Enter, setSuccess True >> setDone True)+  , (xK_BackSpace, deleteString Prev)+  , (xK_Delete, deleteString Next)+  , (xK_Left, moveCursor Prev)+  , (xK_Right, moveCursor Next)+  , (xK_Home, startOfLine)+  , (xK_End, endOfLine)+  , (xK_Down, moveHistory W.focusUp')+  , (xK_Up, moveHistory W.focusDown')+  , (xK_Escape, quit)+  ]  keyPressHandle :: KeyMask -> KeyStroke -> XP ()--- commands: ctrl + ... todo-keyPressHandle mask (ks,_)-    | (mask .&. controlMask) > 0 =-        -- control sequences-        case () of-          _ | ks == xK_u               -> killBefore    >> go-            | ks == xK_k               -> killAfter     >> go-            | ks == xK_a               -> startOfLine   >> go-            | ks == xK_e               -> endOfLine     >> go-            | ks == xK_y               -> pasteString   >> go-            | ks == xK_Right           -> moveWord Next >> go-            | ks == xK_Left            -> moveWord Prev >> go-            | ks == xK_Delete          -> killWord Next >> go-            | ks == xK_BackSpace       -> killWord Prev >> go-            | ks == xK_w               -> killWord Prev >> go-            | ks == xK_g || ks == xK_c -> quit-            | otherwise  -> eventLoop handle -- unhandled control sequence-    | ks == xK_Return || ks == xK_KP_Enter    = setSuccess True-    | ks == xK_BackSpace = deleteString Prev >> go-    | ks == xK_Delete    = deleteString Next >> go-    | ks == xK_Left      = moveCursor   Prev >> go-    | ks == xK_Right     = moveCursor   Next >> go-    | ks == xK_Home      = startOfLine       >> go-    | ks == xK_End       = endOfLine         >> go-    | ks == xK_Down      = moveHistory  W.focusUp' >> go-    | ks == xK_Up        = moveHistory  W.focusDown' >> go-    | ks == xK_Escape    = quit-    where-      go   = updateWindows >> eventLoop handle-      quit = flushString >> setSuccess False -- quit and discard everything--- insert a character-keyPressHandle _ (_,s)-    | s == "" = eventLoop handle-    | otherwise = do insertString (decodeInput s)-                     updateWindows-                     completed <- tryAutoComplete-                     if completed then setSuccess True else eventLoop handle+keyPressHandle m (ks,str) = do+  km <- gets (promptKeymap . config)+  mask <- cleanMask m+  case M.lookup (mask,ks) km of+    Just action -> action >> updateWindows+    Nothing -> case str of+                 "" -> eventLoop handle+                 _ -> when (mask .&. controlMask == 0) $ do+                                 insertString (decodeInput str)+                                 updateWindows+                                 completed <- tryAutoComplete+                                 when completed $ setSuccess True >> setDone True  setSuccess :: Bool -> XP () setSuccess b = modify $ \s -> s { successful = b } +setDone :: Bool -> XP ()+setDone b = modify $ \s -> s { done = b }+ -- KeyPress and State +-- | Quit.+quit :: XP ()+quit = flushString >> setSuccess False >> setDone True+ -- | Kill the portion of the command before the cursor killBefore :: XP () killBefore =@@ -415,7 +479,7 @@   modify $ \s -> setCommand (take (offset s) (command s)) s  -- | Kill the next\/previous word-killWord :: Direction -> XP ()+killWord :: Direction1D -> XP () killWord d = do   o <- gets offset   c <- gets command@@ -443,8 +507,7 @@  -- |  Flush the command string and reset the offset flushString :: XP ()-flushString = do-  modify $ \s -> setCommand "" $ s { offset = 0}+flushString = modify $ \s -> setCommand "" $ s { offset = 0}  -- | Insert a character at the cursor position insertString :: String -> XP ()@@ -457,10 +520,10 @@  -- | Insert the current X selection string at the cursor position. pasteString :: XP ()-pasteString = join $ io $ liftM insertString $ getSelection+pasteString = join $ io $ liftM insertString getSelection  -- | Remove a character at the cursor position-deleteString :: Direction -> XP ()+deleteString :: Direction1D -> XP () deleteString d =   modify $ \s -> setCommand (c (command s) (offset s)) $ s { offset = o (offset s)}   where o oo = if d == Prev then max 0 (oo - 1) else oo@@ -472,13 +535,13 @@             where (f,ss) = splitAt oo oc  -- | move the cursor one position-moveCursor :: Direction -> XP ()+moveCursor :: Direction1D -> XP () moveCursor d =   modify $ \s -> s { offset = o (offset s) (command s)}   where o oo c = if d == Prev then max 0 (oo - 1) else min (length c) (oo + 1)  -- | move the cursor one word-moveWord :: Direction -> XP ()+moveWord :: Direction1D -> XP () moveWord d = do   c <- gets command   o <- gets offset@@ -488,8 +551,8 @@                  ' ':x -> 1 + lenToS x                  x     -> lenToS x       newoff = case d of-                 Prev -> o - (ln reverse f )-                 Next -> o + (ln id      ss)+                 Prev -> o - ln reverse f+                 Next -> o + ln id ss   modify $ \s -> s { offset = newoff }  moveHistory :: (W.Stack String -> W.Stack String) -> XP ()@@ -576,8 +639,8 @@ getCompletions :: XP [String] getCompletions = do   s <- get-  io $ (completionFunction s) (commandToComplete (xptype s) (command s))-       `catch` \_ -> return []+  io $ completionFunction s (commandToComplete (xptype s) (command s))+       `catch` \(SomeException _) -> return []  setComplWin :: Window -> ComplWindowDim -> XP () setComplWin w wi =@@ -616,9 +679,9 @@    tws <- mapM (textWidthXMF (dpy st) fs) compl   let max_compl_len =  fromIntegral ((fi ht `div` 2) + maximum tws)-      columns = max 1 $ wh `div` (fi max_compl_len)+      columns = max 1 $ wh `div` fi max_compl_len       rem_height =  rect_height scr - ht-      (rows,r) = (length compl) `divMod` fi columns+      (rows,r) = length compl `divMod` fi columns       needed_rows = max 1 (rows + if r == 0 then 0 else 1)       actual_max_number_of_rows = rem_height `div` ht       actual_rows = min actual_max_number_of_rows (fi needed_rows)@@ -650,7 +713,7 @@   p <- io $ createPixmap d w wh ht                          (defaultDepthOfScreen scr)   io $ fillDrawable d p gc border bgcolor (fi bw) wh ht-  let ac = splitInSubListsAt (length yy) (take ((length xx) * (length yy)) compl)+  let ac = splitInSubListsAt (length yy) (take (length xx * length yy) compl)   printComplList d p gc (fgColor c) (bgColor c) xx yy ac   io $ copyArea d p w gc 0 0 wh ht 0 0   io $ freePixmap d p@@ -662,7 +725,7 @@   let recreate = do destroyComplWin                     w <- createComplWin nwi                     drawComplWin w compl-  if (compl /= [] && showComplWin st)+  if compl /= [] && showComplWin st      then case complWin st of             Just w -> case complWinDim st of                         Just wi -> if nwi == wi -- complWinDim did not change@@ -674,41 +737,28 @@  printComplList :: Display -> Drawable -> GC -> String -> String                -> [Position] -> [Position] -> [[String]] -> XP ()-printComplList _ _ _ _ _ _ _ [] = return ()-printComplList _ _ _ _ _ [] _ _ = return ()-printComplList d drw gc fc bc (x:xs) y (s:ss) = do-  printComplColumn d drw gc fc bc x y s-  printComplList d drw gc fc bc xs y ss--printComplColumn :: Display -> Drawable -> GC -> String -> String-                 -> Position -> [Position] -> [String] -> XP ()-printComplColumn _ _ _ _ _ _ _ [] = return ()-printComplColumn _ _ _ _ _ _ [] _ = return ()-printComplColumn d drw gc fc bc x (y:yy) (s:ss) = do-  printComplString d drw gc fc bc x y s-  printComplColumn d drw gc fc bc x yy ss--printComplString :: Display -> Drawable -> GC -> String -> String-                 -> Position -> Position -> String  -> XP ()-printComplString d drw gc fc bc x y s = do-  st <- get-  if completionToCommand (xptype st) s == commandToComplete (xptype st) (command st)-     then printStringXMF d drw (fontS st) gc-                            (fgHLight $ config st) (bgHLight $ config st) x y s-     else printStringXMF d drw (fontS st) gc fc bc x y s+printComplList d drw gc fc bc xs ys sss =+    zipWithM_ (\x ss ->+        zipWithM_ (\y s -> do+            st <- get+            let (f,b) = if completionToCommand (xptype st) s == commandToComplete (xptype st) (command st)+                            then (fgHLight $ config st,bgHLight $ config st)+                            else (fc,bc)+            printStringXMF d drw (fontS st) gc f b x y s)+        ys ss) xs sss  -- History -type History = Map String [String]+type History = M.Map String [String]  emptyHistory :: History-emptyHistory = Map.empty+emptyHistory = M.empty  getHistoryFile :: IO FilePath getHistoryFile = fmap (++ "/history") $ getAppUserDataDirectory "xmonad"  readHistory :: IO History-readHistory = catch readHist (const (return emptyHistory))+readHistory = readHist `catch` \(SomeException _) -> return emptyHistory  where     readHist = do         path <- getHistoryFile@@ -718,8 +768,8 @@ writeHistory :: History -> IO () writeHistory hist = do   path <- getHistoryFile-  catch (writeFile path (show hist)) $ const $ hPutStrLn stderr "error in writing"-  setFileMode path mode +  writeFile path (show hist) `catch` \(SomeException _) -> hPutStrLn stderr "error in writing"+  setFileMode path mode     where mode = ownerReadMode .|. ownerWriteMode  -- $xutils@@ -784,14 +834,6 @@                   Just i  -> if i >= length l - 1 then 0 else i + 1                   Nothing -> 0 --- Lift an IO action into the XP-io :: IO a -> XP a-io = liftIO---- Shorthand for fromIntegral-fi :: (Num b, Integral a) => a -> b-fi = fromIntegral- -- | Given a maximum length, splits a list into sublists splitInSubListsAt :: Int -> [a] -> [[a]] splitInSubListsAt _ [] = []@@ -819,8 +861,14 @@ --   'getShellCompl'; you pass it to mkXPrompt, and it will make completions work --   from the query history stored in ~\/.xmonad\/history. historyCompletion :: ComplFunction-historyCompletion x = fmap (deleteConsecutive . filter (isInfixOf x) . Map.fold (++) []) readHistory+historyCompletion = historyCompletionP (const True) +-- | Like 'historyCompletion' but only uses history data from Prompts whose+-- name satisfies the given predicate.+historyCompletionP :: (String -> Bool) -> ComplFunction+historyCompletionP p x = fmap (toComplList . M.filterWithKey (const . p)) readHistory+    where toComplList = deleteConsecutive . filter (isInfixOf x) . M.fold (++) []+ -- | Sort a list and remove duplicates. Like 'deleteAllDuplicates', but trades off --   laziness and stability for efficiency. uniqSort :: Ord a => [a] -> [a]@@ -833,3 +881,45 @@ deleteAllDuplicates, deleteConsecutive :: [String] -> [String] deleteAllDuplicates = nub deleteConsecutive = map head . group++newtype HistoryMatches = HistoryMatches (IORef ([String],Maybe (W.Stack String)))++-- | Initializes a new HistoryMatches structure to be passed+-- to historyUpMatching+initMatches :: (Functor m, MonadIO m) => m HistoryMatches+initMatches = HistoryMatches <$> liftIO (newIORef ([],Nothing))++historyNextMatching :: HistoryMatches -> (W.Stack String -> W.Stack String) -> XP ()+historyNextMatching hm@(HistoryMatches ref) next = do+  (completed,completions) <- io $ readIORef ref+  input <- getInput+  if input `elem` completed+     then case completions of+            Just cs -> do+                let cmd = W.focus cs+                modify $ setCommand cmd+                modify $ \s -> s { offset = length cmd }+                io $ writeIORef ref (cmd:completed,Just $ next cs)+            Nothing -> return ()+     else do -- the user typed something new, recompute completions+       io . writeIORef ref . ((,) [input]) . filterMatching input =<< gets commandHistory+       historyNextMatching hm next+    where filterMatching :: String -> W.Stack String -> Maybe (W.Stack String)+          filterMatching prefix = W.filter (prefix `isPrefixOf`) . next++-- | Retrieve the next history element that starts with+-- the current input. Pass it the result of initMatches+-- when creating the prompt. Example:+--+-- > ..+-- > ((modMask,xK_p), shellPrompt . myPrompt =<< initMatches)+-- > ..+-- > myPrompt ref = defaultPrompt+-- >   { promptKeymap = M.union [((0,xK_Up), historyUpMatching ref)+-- >                            ,((0,xK_Down), historyDownMatching ref)]+-- >                            (promptKeymap defaultPrompt)+-- >   , .. }+--+historyUpMatching, historyDownMatching :: HistoryMatches -> XP ()+historyUpMatching hm = historyNextMatching hm W.focusDown'+historyDownMatching hm = historyNextMatching hm W.focusUp'
XMonad/Prompt/AppLauncher.hs view
@@ -8,7 +8,7 @@ -- Stability   :  unstable -- Portability :  unportable ----- A module for launch applicationes that receive parameters in the command +-- A module for launch applicationes that receive parameters in the command -- line. The launcher call a prompt to get the parameters. -- -----------------------------------------------------------------------------@@ -31,7 +31,7 @@    you want to open a image in gimp program, you can open gimp and then use    the File Menu to open the image or you can use this module to select    the image in the command line.-   +    We use Prompt to get the user command line. This also allow to autoexpand    the names of the files when we are writing the command line.  -}
XMonad/Prompt/AppendFile.hs view
@@ -5,7 +5,7 @@ -- License     :  BSD-style (see LICENSE) -- -- Maintainer  :  <byorgey@gmail.com>--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- A prompt for appending a single line of text to a file.  Useful for@@ -29,7 +29,7 @@ import XMonad.Prompt  import System.IO-import Control.Exception+import Control.Exception.Extensible (bracket)  -- $usage --@@ -41,7 +41,7 @@ -- -- and adding an appropriate keybinding, for example: ----- >  , ((modMask x .|. controlMask, xK_n), appendFilePrompt defaultXPConfig "/home/me/NOTES")+-- >  , ((modm .|. controlMask, xK_n), appendFilePrompt defaultXPConfig "/home/me/NOTES") -- -- For detailed instructions on editing your key bindings, see -- "XMonad.Doc.Extending#Editing_key_bindings".@@ -61,6 +61,4 @@  -- | Append a string to a file. doAppend :: FilePath -> String -> X ()-doAppend fn s = io $ bracket (openFile fn AppendMode)-                             hClose-                             (flip hPutStrLn s)+doAppend fn = io . bracket (openFile fn AppendMode) hClose . flip hPutStrLn
XMonad/Prompt/Directory.hs view
@@ -4,7 +4,7 @@ -- Copyright   :  (C) 2007 Andrea Rossato, David Roundy -- License     :  BSD3 ----- Maintainer  :  droundy@darcs.net+-- Maintainer  : -- Stability   :  unstable -- Portability :  unportable --@@ -31,7 +31,7 @@     showXPrompt (Dir x) = x  directoryPrompt :: XPConfig -> String -> (String -> X ()) -> X ()-directoryPrompt c prom job = mkXPrompt (Dir prom) c getDirCompl job+directoryPrompt c prom = mkXPrompt (Dir prom) c getDirCompl  getDirCompl :: String -> IO [String] getDirCompl s = (filter notboring . lines) `fmap`
XMonad/Prompt/Email.hs view
@@ -5,7 +5,7 @@ -- License     :  BSD-style (see LICENSE) -- -- Maintainer  :  <byorgey@gmail.com>--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- A prompt for sending quick, one-line emails, via the standard GNU@@ -36,7 +36,7 @@ -- -- and adding an appropriate keybinding, for example: ----- >  , ((modMask x .|. controlMask, xK_e), emailPrompt defaultXPConfig addresses)+-- >  , ((modm .|. controlMask, xK_e), emailPrompt defaultXPConfig addresses) -- -- where @addresses@ is a list of email addresses that should -- autocomplete, for example:@@ -59,5 +59,5 @@     inputPromptWithCompl c "To" (mkComplFunFromList addrs) ?+ \to ->     inputPrompt c "Subject" ?+ \subj ->     inputPrompt c "Body" ?+ \body ->-    io $ runProcessWithInput "mail" ["-s", subj, to] (body ++ "\n")+    runProcessWithInput "mail" ["-s", subj, to] (body ++ "\n")          >> return ()
XMonad/Prompt/Input.hs view
@@ -5,7 +5,7 @@ -- License     :  BSD-style (see LICENSE) -- -- Maintainer  :  <byorgey@gmail.com>--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- A generic framework for prompting the user for input and passing it@@ -59,7 +59,7 @@ -- Now all he has to do is add a keybinding to @firingPrompt@ (or -- @firingPrompt'@), such as ----- >  , ((modMask x .|. controlMask, xK_f),  firingPrompt)+-- >  , ((modm .|. controlMask, xK_f),  firingPrompt) -- -- Now when Mr. Big hits mod-ctrl-f, a prompt will pop up saying -- \"Fire: \", waiting for him to type the name of someone to fire.
XMonad/Prompt/Layout.hs view
@@ -4,7 +4,7 @@ -- Copyright   :  (C) 2007 Andrea Rossato, David Roundy -- License     :  BSD3 ----- Maintainer  :  droundy@darcs.net+-- Maintainer  : -- Stability   :  unstable -- Portability :  unportable --@@ -30,7 +30,7 @@ -- > import XMonad.Prompt -- > import XMonad.Prompt.Layout ----- >   , ((modMask x .|. shiftMask, xK_m     ), layoutPrompt defaultXPConfig)+-- >   , ((modm .|. shiftMask, xK_m     ), layoutPrompt defaultXPConfig) -- -- For detailed instruction on editing the key binding see -- "XMonad.Doc.Extending#Editing_key_bindings".@@ -50,7 +50,4 @@  layoutPrompt :: XPConfig -> X () layoutPrompt c = do ls <- gets (map (description . layout) . workspaces . windowset)-                    mkXPrompt (Wor "") c (mkCompl $ sort $ nub ls) (sendMessage . JumpToLayout)--mkCompl :: [String] -> String -> IO [String]-mkCompl l s = return $ filter (\x -> take (length s) x == s) l+                    mkXPrompt (Wor "") c (mkComplFunFromList' $ sort $ nub ls) (sendMessage . JumpToLayout)
XMonad/Prompt/Man.hs view
@@ -31,7 +31,7 @@ import System.Process import System.IO -import qualified Control.Exception as E+import qualified Control.Exception.Extensible as E import Control.Monad import Data.List import Data.Maybe@@ -44,7 +44,7 @@ -- -- 2. In your keybindings add something like: ----- >     , ((modMask x, xK_F1), manPrompt defaultXPConfig)+-- >     , ((modm, xK_F1), manPrompt defaultXPConfig) -- -- For detailed instruction on editing the key binding see -- "XMonad.Doc.Extending#Editing_key_bindings".@@ -62,7 +62,8 @@  getMans :: IO [String] getMans = do-  paths <- getCommandOutput "manpath -g 2>/dev/null" `E.catch` \_ -> return []+  paths <- getCommandOutput "manpath -g 2>/dev/null" `E.catch`+            \(E.SomeException _) -> return []   let sects    = ["man" ++ show n | n <- [1..9 :: Int]]       dirs     = [d ++ "/" ++ s | d <- split ':' paths, s <- sects]   mans <- forM dirs $ \d -> do
XMonad/Prompt/RunOrRaise.hs view
@@ -25,8 +25,7 @@ import XMonad.Actions.WindowGo (runOrRaise) import XMonad.Util.Run (runProcessWithInput) -import Control.Monad (liftM2)-import Data.Maybe+import Control.Monad (liftM, liftM2) import System.Directory (doesDirectoryExist, doesFileExist, executable, getPermissions)  {- $usage@@ -37,7 +36,7 @@  2. In your keybindings add something like: ->   , ((modMask x .|. controlMask, xK_x), runOrRaisePrompt defaultXPConfig)+>   , ((modm .|. controlMask, xK_x), runOrRaisePrompt defaultXPConfig)  For detailed instruction on editing the key binding see "XMonad.Doc.Extending#Editing_key_bindings". -}@@ -47,15 +46,15 @@     showXPrompt RRP = "Run or Raise: "  runOrRaisePrompt :: XPConfig -> X ()-runOrRaisePrompt c = do cmds <- io $ getCommands+runOrRaisePrompt c = do cmds <- io getCommands                         mkXPrompt RRP c (getShellCompl cmds) open open :: String -> X ()-open path = (io $ isNormalFile path) >>= \b ->+open path = io (isNormalFile path) >>= \b ->             if b             then spawn $ "xdg-open \"" ++ path ++ "\""             else uncurry runOrRaise . getTarget $ path     where-      isNormalFile f = exists f >>= \e -> if e then (notExecutable f) else return False+      isNormalFile f = exists f >>= \e -> if e then notExecutable f else return False       exists f = fmap or $ sequence [doesFileExist f,doesDirectoryExist f]       notExecutable = fmap (not . executable) . getPermissions       getTarget x = (x,isApp x)@@ -66,12 +65,12 @@ isApp x = liftM2 (==) pid $ pidof x  pidof :: String -> Query Int-pidof x = io $ (runProcessWithInput "pidof" [x] [] >>= readIO) `catch` (\_ -> return $ 0)+pidof x = io $ (runProcessWithInput "pidof" [x] [] >>= readIO) `catch` (\_ -> return 0)  pid :: Query Int pid = ask >>= (\w -> liftX $ withDisplay $ \d -> getPID d w)     where getPID d w = getAtom "_NET_WM_PID" >>= \a -> io $-                       getWindowProperty32 d a w >>= return . getPID'+                       liftM getPID' (getWindowProperty32 d a w)           getPID' (Just (x:_)) = fromIntegral x           getPID' (Just [])     = -1           getPID' (Nothing)     = -1
XMonad/Prompt/Shell.hs view
@@ -30,7 +30,6 @@ import Control.Monad import Data.List import System.Directory-import System.IO import System.Posix.Files import XMonad.Util.Run import XMonad hiding (config)@@ -44,7 +43,7 @@ -- -- 2. In your keybindings add something like: ----- >   , ((modMask x .|. controlMask, xK_x), shellPrompt defaultXPConfig)+-- >   , ((modm .|. controlMask, xK_x), shellPrompt defaultXPConfig) -- -- For detailed instruction on editing the key binding see -- "XMonad.Doc.Extending#Editing_key_bindings".@@ -57,7 +56,7 @@  shellPrompt :: XPConfig -> X () shellPrompt c = do-    cmds <- io $ getCommands+    cmds <- io getCommands     mkXPrompt Shell c (getShellCompl cmds) (spawn . encodeOutput)  -- | See safe and unsafeSpawn. prompt is an alias for safePrompt;@@ -67,8 +66,8 @@ -- is the program to be run with the interactive input. -- You would use these like this: ----- >     , ((modMask,               xK_b), safePrompt "firefox" greenXPConfig)--- >     , ((modMask .|. shiftMask, xK_c), prompt ("xterm" ++ " -e") greenXPConfig)+-- >     , ((modm,               xK_b), safePrompt "firefox" greenXPConfig)+-- >     , ((modm .|. shiftMask, xK_c), prompt ("xterm" ++ " -e") greenXPConfig) -- -- Note that you want to use safePrompt for Firefox input, as Firefox -- wants URLs, and unsafePrompt for the XTerm example because this allows@@ -77,7 +76,7 @@ prompt, unsafePrompt, safePrompt :: FilePath -> XPConfig -> X () prompt = unsafePrompt safePrompt c config = mkXPrompt Shell config (getShellCompl [c]) run-    where run = safeSpawn c . encodeOutput+    where run = safeSpawn c . return . encodeOutput unsafePrompt c config = mkXPrompt Shell config (getShellCompl [c]) run     where run a = unsafeSpawn $ c ++ " " ++ encodeOutput a @@ -99,7 +98,7 @@ getCommands :: IO [String] getCommands = do     p  <- getEnv "PATH" `catch` const (return [])-    let ds = split ':' p+    let ds = filter (/= "") $ split ':' p     es <- forM ds $ \d -> do         exists <- doesDirectoryExist d         if exists
XMonad/Prompt/Ssh.hs view
@@ -26,7 +26,6 @@ import System.Environment  import Control.Monad-import Data.List import Data.Maybe  -- $usage@@ -37,7 +36,7 @@ -- -- 2. In your keybindings add something like: ----- >   , ((modMask x .|. controlMask, xK_s), sshPrompt defaultXPConfig)+-- >   , ((modm .|. controlMask, xK_s), sshPrompt defaultXPConfig) -- -- Keep in mind, that if you want to use the completion you have to -- disable the "HashKnownHosts" option in your ssh_config@@ -54,11 +53,11 @@  sshPrompt :: XPConfig -> X () sshPrompt c = do-  sc <- io $ sshComplList+  sc <- io sshComplList   mkXPrompt Ssh c (mkComplFunFromList sc) ssh  ssh :: String -> X ()-ssh s = runInTerm "" ("ssh " ++ s)+ssh = runInTerm "" . ("ssh " ++ )  sshComplList :: IO [String] sshComplList = uniqSort `fmap` liftM2 (++) sshComplListLocal sshComplListGlobal
XMonad/Prompt/Theme.hs view
@@ -20,7 +20,6 @@ import Control.Arrow ( (&&&) ) import qualified Data.Map as M import Data.Maybe ( fromMaybe )-import Data.List import XMonad import XMonad.Prompt import XMonad.Layout.Decoration@@ -35,7 +34,7 @@ -- -- in your keybindings add: ----- >   , ((modMask x .|. controlMask, xK_t), themePrompt defaultXPConfig)+-- >   , ((modm .|. controlMask, xK_t), themePrompt defaultXPConfig) -- -- For detailed instruction on editing the key binding see -- "XMonad.Doc.Extending#Editing_key_bindings".
XMonad/Prompt/Window.hs view
@@ -24,7 +24,6 @@     ) where  import qualified Data.Map as M-import Data.List  import qualified XMonad.StackSet as W import XMonad@@ -44,12 +43,12 @@ -- -- and in the keys definition: ----- > , ((modMask x .|. shiftMask, xK_g     ), windowPromptGoto  defaultXPConfig)--- > , ((modMask x .|. shiftMask, xK_b     ), windowPromptBring defaultXPConfig)+-- > , ((modm .|. shiftMask, xK_g     ), windowPromptGoto  defaultXPConfig)+-- > , ((modm .|. shiftMask, xK_b     ), windowPromptBring defaultXPConfig) -- -- The autoComplete option is a handy complement here: ----- > , ((modMask x .|. shiftMask, xK_g     ), windowPromptGoto+-- > , ((modm .|. shiftMask, xK_g     ), windowPromptGoto -- >                                            defaultXPConfig { autoComplete = Just 500000 } ) -- -- The \'500000\' is the number of microseconds to pause before sending you to@@ -68,9 +67,9 @@     nextCompletion      _ = getNextCompletion  windowPromptGoto, windowPromptBring, windowPromptBringCopy :: XPConfig -> X ()-windowPromptGoto  c = doPrompt Goto  c-windowPromptBring c = doPrompt Bring c-windowPromptBringCopy c = doPrompt BringCopy c+windowPromptGoto  = doPrompt Goto+windowPromptBring = doPrompt Bring+windowPromptBringCopy = doPrompt BringCopy  -- | Pops open a prompt with window titles. Choose one, and you will be -- taken to the corresponding workspace.@@ -79,7 +78,7 @@   a <- case t of          Goto  -> fmap gotoAction  windowMap          Bring -> fmap bringAction windowMap-	 BringCopy -> fmap bringCopyAction windowMap+         BringCopy -> fmap bringCopyAction windowMap   wm <- windowMap   mkXPrompt t c (compList wm) a @@ -89,9 +88,9 @@       bringAction      = winAction bringWindow       bringCopyAction  = winAction bringCopyWindow -      compList m s = return . filter (isPrefixOf s) . map fst . M.toList $ m+      compList m s = return . filter (searchPredicate c s) . map fst . M.toList $ m   -- | Brings a copy of the specified window into the current workspace. bringCopyWindow :: Window -> WindowSet -> WindowSet-bringCopyWindow w ws = copyWindow w (W.currentTag $ ws) ws+bringCopyWindow w ws = copyWindow w (W.currentTag ws) ws
XMonad/Prompt/Workspace.hs view
@@ -4,7 +4,7 @@ -- Copyright   :  (C) 2007 Andrea Rossato, David Roundy -- License     :  BSD3 ----- Maintainer  :  droundy@darcs.net+-- Maintainer  : -- Stability   :  unstable -- Portability :  unportable --@@ -29,7 +29,7 @@ -- > import XMonad.Prompt -- > import XMonad.Prompt.Workspace ----- >   , ((modMask x .|. shiftMask, xK_m     ), workspacePrompt defaultXPConfig (windows . W.shift))+-- >   , ((modm .|. shiftMask, xK_m     ), workspacePrompt defaultXPConfig (windows . W.shift)) -- -- For detailed instruction on editing the key binding see -- "XMonad.Doc.Extending#Editing_key_bindings".@@ -43,7 +43,4 @@ workspacePrompt c job = do ws <- gets (workspaces . windowset)                            sort <- getSortByIndex                            let ts = map tag $ sort ws-                           mkXPrompt (Wor "") c (mkCompl ts) job--mkCompl :: [String] -> String -> IO [String]-mkCompl l s = return $ filter (\x -> take (length s) x == s) l+                           mkXPrompt (Wor "") c (mkComplFunFromList' ts) job
XMonad/Prompt/XMonad.hs view
@@ -32,7 +32,7 @@ -- -- in your keybindings add: ----- >   , ((modMask x .|. controlMask, xK_x), xmonadPrompt defaultXPConfig)+-- >   , ((modm .|. controlMask, xK_x), xmonadPrompt defaultXPConfig) -- -- For detailed instruction on editing the key binding see -- "XMonad.Doc.Extending#Editing_key_bindings".
+ XMonad/Util/Cursor.hs view
@@ -0,0 +1,46 @@+----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Util.Cursor+-- Copyright   :  (c) 2009 Collabora Ltd+-- License     :  BSD-style (see xmonad/LICENSE)+--+-- Maintainer  :  Andres Salomon <dilinger@collabora.co.uk>+-- Stability   :  unstable+-- Portability :  unportable+--+-- A module for setting the default mouse cursor.+--+-- Some ideas shamelessly stolen from Nils Schweinsberg; thanks!+-----------------------------------------------------------------------------++module XMonad.Util.Cursor+    ( -- * Usage:+      -- $usage+      module Graphics.X11.Xlib.Cursor,+      setDefaultCursor+    ) where++import Graphics.X11.Xlib.Cursor+import XMonad++-- $usage+--+-- >   setDefaultCursor xC_left_ptr+--+--   For example, to override the default gnome cursor:+--+-- >   import XMonad.Util.Cursor+-- >   main = xmonad gnomeConfig { startupHook = setDefaultCursor xC_pirate }+--+--   Arrr!++-- | Set the default (root) cursor+setDefaultCursor :: Glyph -> X ()+setDefaultCursor glyph = do+    dpy <- asks display+    rootw <- asks theRoot+    liftIO $ do+        curs <- createFontCursor dpy glyph+        defineCursor dpy rootw curs+        flush dpy+        freeCursor dpy curs
XMonad/Util/Dmenu.hs view
@@ -15,10 +15,10 @@ -----------------------------------------------------------------------------  module XMonad.Util.Dmenu (-			    -- * Usage-			    -- $usage-			    dmenu, dmenuXinerama, dmenuMap, menu, menuMap-			   ) where+                -- * Usage+                -- $usage+                dmenu, dmenuXinerama, dmenuMap, menu, menuArgs, menuMap, menuMapArgs+               ) where  import XMonad import qualified XMonad.StackSet as W@@ -37,20 +37,33 @@ dmenuXinerama :: [String] -> X String dmenuXinerama opts = do     curscreen <- (fromIntegral . W.screen . W.current) `fmap` gets windowset :: X Int-    io $ runProcessWithInput "dmenu" ["-xs", show (curscreen+1)] (unlines opts)+    runProcessWithInput "dmenu" ["-xs", show (curscreen+1)] (unlines opts)+    menuArgs "dmenu" ["-xs", show (curscreen+1)] opts +-- | Run dmenu to select an option from a list. dmenu :: [String] -> X String dmenu opts = menu "dmenu" opts +-- | like 'dmenu' but also takes the command to run. menu :: String -> [String] -> X String-menu menuCmd opts = io $ runProcessWithInput menuCmd [] (unlines opts)+menu menuCmd opts = menuArgs menuCmd [] opts +-- | Like 'menu' but also takes a list of command line arguments.+menuArgs :: String -> [String] -> [String] -> X String+menuArgs menuCmd args opts = runProcessWithInput menuCmd args (unlines opts)++-- | Like 'dmenuMap' but also takes the command to run. menuMap :: String -> M.Map String a -> X (Maybe a)-menuMap menuCmd selectionMap = do+menuMap menuCmd selectionMap = menuMapArgs menuCmd [] selectionMap++-- | Like 'menuMap' but also takes a list of command line arguments.+menuMapArgs :: String -> [String] -> M.Map String a -> X (Maybe a)+menuMapArgs menuCmd args selectionMap = do   selection <- menuFunction (M.keys selectionMap)   return $ M.lookup selection selectionMap       where-        menuFunction = menu menuCmd+        menuFunction = menuArgs menuCmd args +-- | Run dmenu to select an entry from a map based on the key. dmenuMap :: M.Map String a -> X (Maybe a) dmenuMap selectionMap = menuMap "dmenu" selectionMap
XMonad/Util/Dzen.hs view
@@ -5,7 +5,7 @@ -- License     :  BSD -- -- Maintainer  :  glasser@mit.edu--- Stability   :  unstable+-- Stability   :  stable -- Portability :  unportable -- -- Handy wrapper for dzen. Requires dzen >= 0.2.4.@@ -13,36 +13,168 @@ -----------------------------------------------------------------------------  module XMonad.Util.Dzen (+    -- * Flexible interface+    dzenConfig,+    timeout,+    font,+    xScreen,+    vCenter,+    hCenter,+    center,+    onCurr,+    x,+    y,+    addArgs,++    -- * Legacy interface     dzen,-    dzenWithArgs,     dzenScreen,-    seconds+    dzenWithArgs,++    -- * Miscellaneous+    seconds,+    chomp,+    (>=>)   ) where +import Control.Monad import XMonad+import XMonad.StackSet import XMonad.Util.Run (runProcessWithInputAndWait, seconds) +type DzenConfig = (Int, [String]) -> X (Int, [String])++-- | @dzenConfig config s@ will display the string @s@ according to the+-- configuration @config@.  For example, to display the string @\"foobar\"@ with+-- all the default settings, you can simply call+--+-- > dzenConfig return "foobar"+--+-- Or, to set a longer timeout, you could use+--+-- > dzenConfig (timeout 10) "foobar"+--+-- You can combine configurations with the (>=>) operator.  To display+-- @\"foobar\"@ for 10 seconds on the first screen, you could use+--+-- > dzenConfig (timeout 10 >=> xScreen 0) "foobar"+--+-- As a final example, you could adapt the above to display @\"foobar\"@ for+-- 10 seconds on the current screen with+--+-- > dzenConfig (timeout 10 >=> onCurr xScreen) "foobar"+dzenConfig :: DzenConfig -> String -> X ()+dzenConfig conf s = do+    (t, args) <- conf (seconds 3, [])+    runProcessWithInputAndWait "dzen2" args (chomp s) t++-- | dzen wants exactly one newline at the end of its input, so this can be+-- used for your own invocations of dzen.  However, all functions in this+-- module will call this for you.+chomp :: String -> String+chomp = (++"\n") . reverse . dropWhile ('\n' ==) . reverse++-- | Set the timeout, in seconds.  This defaults to 3 seconds if not+-- specified.+timeout :: Rational -> DzenConfig+timeout = timeoutMicro . seconds++-- | Set the timeout, in microseconds.  Mostly here for the legacy+-- interface.+timeoutMicro :: Int -> DzenConfig+timeoutMicro n (_, ss) = return (n, ss)++-- | Add raw command-line arguments to the configuration.  These will be+-- passed on verbatim to dzen2.  The default includes no arguments.+addArgs :: [String] -> DzenConfig+addArgs ss (n, ss') = return (n, ss ++ ss')++-- | Start dzen2 on a particular screen.  Only works with versions of dzen+-- that support the "-xs" argument.+xScreen :: ScreenId -> DzenConfig+xScreen sc = addArgs ["-xs", show (fromIntegral sc + 1 :: Int)]++-- | Take a screen-specific configuration and supply it with the screen ID+-- of the currently focused screen, according to xmonad.  For example, show+-- a 100-pixel wide bar centered within the current screen, you could use+--+-- > dzenConfig (onCurr (hCenter 100)) "foobar"+--+-- Of course, you can still combine these with (>=>); for example, to center+-- the string @\"foobar\"@ both horizontally and vertically in a 100x14 box+-- using the lovely Terminus font, you could use+--+-- > terminus = "-*-terminus-*-*-*-*-12-*-*-*-*-*-*-*"+-- > dzenConfig (onCurr (center 100 14) >=> font terminus) "foobar"+onCurr :: (ScreenId -> DzenConfig) -> DzenConfig+onCurr f conf = gets (screen . current . windowset) >>= flip f conf++-- | Put the top of the dzen bar at a particular pixel.+x :: Int -> DzenConfig+x n = addArgs ["-x", show n]+-- | Put the left of the dzen bar at a particular pixel.+y :: Int -> DzenConfig+y n = addArgs ["-y", show n]++-- | Specify the font.  Check out xfontsel to get the format of the String+-- right; if your dzen supports xft, then you can supply that here, too.+font :: String -> DzenConfig+font fn = addArgs ["-fn", fn]++-- | @vCenter height sc@ sets the configuration to have the dzen bar appear+-- on screen @sc@ with height @height@, vertically centered with respect to+-- the actual size of that screen.+vCenter :: Int -> ScreenId -> DzenConfig+vCenter = center' rect_height "-h" "-y"++-- | @hCenter width sc@ sets the configuration to have the dzen bar appear+-- on screen @sc@ with width @width@, horizontally centered with respect to+-- the actual size of that screen.+hCenter :: Int -> ScreenId -> DzenConfig+hCenter = center' rect_width  "-w" "-x"++-- | @center width height sc@ sets the configuration to have the dzen bar+-- appear on screen @sc@ with width @width@ and height @height@, centered+-- both horizontally and vertically with respect to the actual size of that+-- screen.+center :: Int -> Int -> ScreenId -> DzenConfig+center width height sc = hCenter width sc >=> vCenter height sc++-- Center things along a single dimension on a particular screen.+center' :: (Rectangle -> Dimension) -> String -> String -> Int -> ScreenId -> DzenConfig+center' selector extentName positionName extent sc conf = do+    rect <- gets (detailFromScreenId sc . windowset)+    case rect of+        Nothing -> return conf+        Just r  -> addArgs+            [extentName  , show extent,+             positionName, show ((fromIntegral (selector r) - extent) `div` 2),+             "-xs"       , show (fromIntegral sc + 1 :: Int)+            ] conf++-- Get the rectangle outlining a particular screen.+detailFromScreenId :: ScreenId -> WindowSet -> Maybe Rectangle+detailFromScreenId sc ws = fmap screenRect maybeSD where+    c       = current ws+    v       = visible ws+    mapping = map (\s -> (screen s, screenDetail s)) (c:v)+    maybeSD = lookup sc mapping+ -- | @dzen str timeout@ pipes @str@ to dzen2 for @timeout@ microseconds. -- Example usage: -- -- > dzen "Hi, mom!" (5 `seconds`) dzen :: String -> Int -> X ()-dzen str timeout = dzenWithArgs str [] timeout+dzen = flip (dzenConfig . timeoutMicro)  -- | @dzen str args timeout@ pipes @str@ to dzen2 for @timeout@ seconds, passing @args@ to dzen. -- Example usage: -- -- > dzenWithArgs "Hi, dons!" ["-ta", "r"] (5 `seconds`) dzenWithArgs :: String -> [String] -> Int -> X ()-dzenWithArgs str args timeout = io $ runProcessWithInputAndWait "dzen2" args (unchomp str) timeout-  -- dzen seems to require the input to terminate with exactly one newline.-  where unchomp s@['\n'] = s-        unchomp []       = ['\n']-        unchomp (c:cs)   = c : unchomp cs+dzenWithArgs str args t = dzenConfig (timeoutMicro t >=> addArgs args) str  -- | @dzenScreen sc str timeout@ pipes @str@ to dzen2 for @timeout@ microseconds, and on screen @sc@. -- Requires dzen to be compiled with Xinerama support.-dzenScreen :: ScreenId -> String -> Int -> X()-dzenScreen sc str timeout = dzenWithArgs str ["-xs", screen] timeout-    where screen  = toXineramaArg sc-          toXineramaArg n = show ( ((fromIntegral n)+1)::Int )+dzenScreen :: ScreenId -> String -> Int -> X ()+dzenScreen sc str t = dzenConfig (timeoutMicro t >=> xScreen sc) str
XMonad/Util/EZConfig.hs view
@@ -27,13 +27,18 @@                              -- * Emacs-style keybinding specifications                               mkKeymap, checkKeymap,+                             mkNamedKeymap,++                             parseKey -- used by XMonad.Util.Paste                             ) where  import XMonad import XMonad.Actions.Submap +import XMonad.Util.NamedActions+ import qualified Data.Map as M-import Data.List (foldl', intersperse, sortBy, groupBy, nub)+import Data.List (foldl', sortBy, groupBy, nub) import Data.Ord (comparing) import Data.Maybe import Control.Arrow (first, (&&&))@@ -56,7 +61,7 @@ -- provided, suitable for adding to your 'startupHook', which can warn -- you of any parse errors or duplicate bindings in your keymap. ----- For more information and usage eamples, see the documentation+-- For more information and usage examples, see the documentation -- provided with each exported function, and check the xmonad config -- archive (<http://haskell.org/haskellwiki/Xmonad/Config_archive>) -- for some real examples of use.@@ -220,7 +225,7 @@ -- > <KP_0>-<KP_9> -- -- Long list of multimedia keys. Please note that not all keys may be--- present in your particular setup althrough most likely they will do.+-- present in your particular setup although most likely they will do. -- -- > <XF86ModeLock> -- > <XF86MonBrightnessUp>@@ -349,16 +354,26 @@ mkKeymap :: XConfig l -> [(String, X ())] -> M.Map (KeyMask, KeySym) (X ()) mkKeymap c = M.fromList . mkSubmaps . readKeymap c +mkNamedKeymap :: XConfig l -> [(String, NamedAction)] -> [((KeyMask, KeySym), NamedAction)]+mkNamedKeymap c = mkNamedSubmaps . readKeymap c+ -- | Given a list of pairs of parsed key sequences and actions, --   group them into submaps in the appropriate way.++mkNamedSubmaps :: [([(KeyMask, KeySym)], NamedAction)] -> [((KeyMask, KeySym), NamedAction)]+mkNamedSubmaps = mkSubmaps' submapName+ mkSubmaps :: [ ([(KeyMask,KeySym)], X ()) ] -> [((KeyMask, KeySym), X ())]-mkSubmaps binds = map combine gathered+mkSubmaps = mkSubmaps' $ submap . M.fromList++mkSubmaps' ::  (Ord a) => ([(a, c)] -> c) -> [([a], c)] -> [(a, c)]+mkSubmaps' subm binds = map combine gathered   where gathered = groupBy fstKey                  . sortBy (comparing fst)                  $ binds         combine [([k],act)] = (k,act)         combine ks = (head . fst . head $ ks,-                      submap . M.fromList . mkSubmaps $ map (first tail) ks)+                      subm . mkSubmaps' subm $ map (first tail) ks)         fstKey = (==) `on` (head . fst)  on :: (a -> a -> b) -> (c -> a) -> c -> c -> b@@ -368,7 +383,7 @@ --   description, action) pairs, parse the key sequences into lists of --   @(KeyMask,KeySym)@ pairs.  Key sequences which fail to parse will --   be ignored.-readKeymap :: XConfig l -> [(String, X())] -> [([(KeyMask,KeySym)], X())]+readKeymap :: XConfig l -> [(String, t)] -> [([(KeyMask, KeySym)], t)] readKeymap c = mapMaybe (maybeKeys . first (readKeySequence c))   where maybeKeys (Nothing,_) = Nothing         maybeKeys (Just k, act) = Just (k, act)@@ -400,7 +415,8 @@                +++ do char 'M'                       n <- satisfy (`elem` ['1'..'5'])                       char '-'-                      return (mod1Mask + (read [n]) - 1)+                      return $ indexMod (read [n] - 1)+    where indexMod = (!!) [mod1Mask,mod2Mask,mod3Mask,mod4Mask,mod5Mask]  -- | Parse an unmodified basic key, like @\"x\"@, @\"<F1>\"@, etc. parseKey :: ReadP KeySym@@ -428,7 +444,7 @@ -- | A list pairing function key descriptor strings (e.g. @\"<F2>\"@) with --   the associated KeySyms. functionKeys :: [(String, KeySym)]-functionKeys = [ ("F" ++ show n, k)+functionKeys = [ ('F' : show n, k)                | (n,k) <- zip ([1..24] :: [Int]) [xK_F1..] ]  -- | A list of special key names and their corresponding KeySyms.@@ -690,7 +706,7 @@                             ++ msg "duplicate" dup ++ "'"         msg _ [] = ""         msg m xs = m ++ " keybindings detected: " ++ showBindings xs-        showBindings = concat . intersperse " " . map ((++"\"") . ("\""++))+        showBindings = unwords . map (("\""++) . (++"\""))  -- | Given a config and a list of (key sequence description, action) --   pairs, check the key sequence descriptions for validity,
+ XMonad/Util/ExtensibleState.hs view
@@ -0,0 +1,115 @@+{-# LANGUAGE PatternGuards #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Util.ExtensibleState+-- Copyright   :  (c) Daniel Schoepe 2009+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  daniel.schoepe@gmail.com+-- Stability   :  unstable+-- Portability :  not portable+--+-- Module for storing custom mutable state in xmonad.+--+-----------------------------------------------------------------------------++module XMonad.Util.ExtensibleState (+                              -- * Usage+                              -- $usage+                              put+                              , modify+                              , remove+                              , get+                              , gets+                              ) where++import Data.Typeable (typeOf,Typeable,cast)+import qualified Data.Map as M+import XMonad.Core+import qualified Control.Monad.State as State+import Data.Maybe (fromMaybe)++-- ---------------------------------------------------------------------+-- $usage+--+-- To utilize this feature in a contrib module create a data type,+-- and make it an instance of ExtensionClass. You can then use+-- the functions from this module for storing your data:+--+-- > {-# LANGUAGE DeriveDataTypeable #-}+-- > import qualified XMonad.Util.ExtensibleState as XS+-- >+-- > data ListStorage = ListStorage [Integer] deriving Typeable+-- > instance ExtensionClass ListStorage where+-- >   initialValue = ListStorage []+-- >+-- > .. XS.put (ListStorage [23,42])+--+-- To retrieve the stored data call:+--+-- > .. XS.get+--+-- If the type can't be infered from the usage of the retrieved data, you+-- might need to add an explicit type signature:+--+-- > .. XS.get :: X ListStorage+--+-- To make your data persistent between restarts, the data type needs to be+-- an instance of Read and Show and the instance declaration has to be changed:+--+-- > data ListStorage = ListStorage [Integer] deriving (Typeable,Read,Show)+-- >+-- > instance ExtensionClass ListStorage where+-- >   initialValue = ListStorage []+-- >   extensionType = PersistentExtension+--+-- One should take care that the string representation of the chosen type+-- is unique among the stored values, otherwise it will be overwritten.+-- Normally these values contain fully qualified module names when deriving Typeable, so+-- name collisions should not be a problem in most cases.+-- A module should not try to store common datatypes(e.g. a list of Integers)+-- without a custom data type as a wrapper to avoid those collisions.+--++-- | Modify the map of state extensions by applying the given function.+modifyStateExts :: (M.Map String (Either String StateExtension)+                   -> M.Map String (Either String StateExtension))+                -> X ()+modifyStateExts f = State.modify $ \st -> st { extensibleState = f (extensibleState st) }++-- | Apply a function to a stored value of the matching type or the initial value if there+-- is none.+modify :: ExtensionClass a => (a -> a) -> X ()+modify f = put . f =<< get++-- | Add a value to the extensible state field. A previously stored value with the same+-- type will be overwritten. (More precisely: A value whose string representation of its type+-- is equal to the new one's)+put :: ExtensionClass a => a -> X ()+put v = modifyStateExts . M.insert (show . typeOf $ v) . Right . extensionType $ v++-- | Try to retrieve a value of the requested type, return an initial value if there is no such value.+get :: ExtensionClass a => X a+get = getState' undefined -- `trick' to avoid needing -XScopedTypeVariables+  where toValue val = maybe initialValue id $ cast val+        getState' :: ExtensionClass a => a -> X a+        getState' k = do+          v <- State.gets $ M.lookup (show . typeOf $ k) . extensibleState+          case v of+            Just (Right (StateExtension val)) -> return $ toValue val+            Just (Right (PersistentExtension val)) -> return $ toValue val+            Just (Left str) | PersistentExtension x <- extensionType k -> do+                let val = fromMaybe initialValue $ cast =<< safeRead str `asTypeOf` Just x+                put (val `asTypeOf` k)+                return val+            _ -> return $ initialValue+        safeRead str = case reads str of+                         [(x,"")] -> Just x+                         _ -> Nothing++gets :: ExtensionClass a => (a -> b) -> X b+gets = flip fmap get++-- | Remove the value from the extensible state field that has the same type as the supplied argument+remove :: ExtensionClass a => a -> X ()+remove wit = modifyStateExts $ M.delete (show . typeOf $ wit)
XMonad/Util/Font.hsc view
@@ -43,10 +43,9 @@ import Graphics.X11.Xrender #endif -#if defined XFT || defined USE_UTF8 import Codec.Binary.UTF8.String (encodeString, decodeString)-#endif + -- Hide the Core Font/Xft switching here data XMonadFont = Core FontStruct                 | Utf8 FontSet@@ -92,7 +91,7 @@   d <- asks display   io $ freeFontSet d fs --- | When initXMF gets a font name that starts with 'xft:' it switchs to the Xft backend+-- | When initXMF gets a font name that starts with 'xft:' it switches to the Xft backend -- Example: 'xft: Sans-10' initXMF :: String -> X XMonadFont initXMF s =@@ -103,11 +102,7 @@         return (Xft xftdraw)   else #endif-#ifdef USE_UTF8       fmap Utf8 $ initUtf8Font s-#else-      fmap Core $ initCoreFont s-#endif #ifdef XFT   where xftPrefix = "xft:" #endif@@ -149,6 +144,7 @@  -- | String position data Align = AlignCenter | AlignRight | AlignLeft | AlignRightOffset Int+                deriving (Show, Read)  -- | Return the string x and y 'Position' in a 'Rectangle', given a -- 'FontStruct' and the 'Align'ment@@ -196,18 +192,10 @@ #endif  decodeInput :: String -> String-#if defined XFT || defined USE_UTF8 decodeInput = decodeString-#else-decodeInput = id-#endif  encodeOutput :: String -> String-#if defined XFT || defined USE_UTF8 encodeOutput = encodeString-#else-encodeOutput = id-#endif  -- | Short-hand for 'fromIntegral' fi :: (Integral a, Num b) => a -> b
XMonad/Util/Invisible.hs view
@@ -5,8 +5,8 @@ -- Module      :  XMonad.Util.Invisible -- Copyright   :  (c) 2007 Andrea Rossato, David Roundy -- License     :  BSD-style (see xmonad/LICENSE)--- --- Maintainer  :  andrea.rossato@unibz.it, droundy@darcs.net+--+-- Maintainer  :  andrea.rossato@unibz.it -- Stability   :  unstable -- Portability :  unportable --@@ -14,7 +14,7 @@ -- ----------------------------------------------------------------------------- -module XMonad.Util.Invisible ( +module XMonad.Util.Invisible (                              -- * Usage:                              -- $usage                              Invisible (..)
XMonad/Util/Loggers.hs view
@@ -116,7 +116,7 @@ --   At some point it would be nice to make this more general\/have --   fewer dependencies (assumes @\/usr\/bin\/acpi@ and @sed@ are installed.) battery :: Logger-battery = logCmd "/usr/bin/acpi | sed -r 's/.*?: (.*%).*/\\1/; s/discharging, ([0-9]+%)/\\1-/; s/charging, ([0-9]+%)/\\1+/; s/charged, //'"+battery = logCmd "/usr/bin/acpi | sed -r 's/.*?: (.*%).*/\\1/; s/[dD]ischarging, ([0-9]+%)/\\1-/; s/[cC]harging, ([0-9]+%)/\\1+/; s/[cC]harged, //'"  -- | Get the current date and time, and format them via the --   given format string.  The format used is the same as that used
+ XMonad/Util/NamedActions.hs view
@@ -0,0 +1,305 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE ExistentialQuantification, FlexibleContexts, FlexibleInstances, StandaloneDeriving #-}+--------------------------------------------------------------------+-- |+-- Module      :  XMonad.Util.NamedActions+-- Copyright   :  2009 Adam Vogt <vogt.adam@gmail.com>+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Adam Vogt <vogt.adam@gmail.com>+-- Stability   :  unstable+-- Portability :  unportable+--+-- A wrapper for keybinding configuration that can list the available+-- keybindings.+--------------------------------------------------------------------++module XMonad.Util.NamedActions (+    -- * Usage:+    -- $usage+    sendMessage',+    spawn',+    submapName,+    addDescrKeys,+    xMessage,++    showKmSimple,+    showKm,++    noName,+    oneName,+    addName,++    separator,+    subtitle,++    (^++^),++    NamedAction(..),+    HasName,+    defaultKeysDescr+    ) where+++import XMonad.Actions.Submap(submap)+import XMonad+import System.Posix.Process(executeFile)+import Control.Arrow(Arrow((&&&), second, (***)))+import Data.Bits(Bits((.&.), complement))+import Data.List (groupBy)+import System.Exit(ExitCode(ExitSuccess), exitWith)++import Control.Applicative ((<*>))++import qualified Data.Map as M+import qualified XMonad.StackSet as W++-- $usage+-- Here is an example config that demonstrates the usage of 'sendMessage'',+-- 'mkNamedKeymap', 'addDescrKeys', and '^++^'+--+-- > import XMonad+-- > import XMonad.Util.NamedActions+-- > import XMonad.Util.EZConfig+-- >+-- > main = xmonad $ addDescrKeys ((mod4Mask, xK_F1), xMessage) myKeys+-- >                    defaultConfig { modMask = mod4Mask }+-- >+-- > myKeys c = (subtitle "Custom Keys":) $ mkNamedKeymap c $+-- >    [("M-x a", addName "useless message" $ spawn "xmessage foo"),+-- >     ("M-c", sendMessage' Expand)]+-- >     ^++^+-- >    [("<XF86AudioPlay>", spawn "mpc toggle" :: X ()),+-- >     ("<XF86AudioNext>", spawn "mpc next")]+--+-- Using '^++^', you can combine bindings whose actions are @X ()@+-- as well as actions that have descriptions. However you cannot mix the two in+-- a single list, unless each is prefixed with 'addName' or 'noName'.+--+-- If you don't like EZConfig, you can still use '^++^' with the basic XMonad+-- keybinding configuration too.+--+-- Also note the unfortunate necessity of a type annotation, since 'spawn' is+-- too general.++-- TODO: squeeze titles that have no entries (consider titles containing \n)+--+-- Output to Multiple columns+--+-- Devin Mullin's suggestions:+--+-- Reduce redundancy wrt mkNamedSubmaps, mkSubmaps and mkNamedKeymap to have a+-- HasName context (and leave mkKeymap as a specific case of it?)+--    Currently kept separate to aid error messages, common lines factored out+--+-- Suggestions for UI:+--+-- - An IO () -> IO () that wraps the main xmonad action and wrests control+--   from it if the user asks for --keys.+--+-- Just a separate binary: keep this as the only way to show keys for simplicity+--+-- - An X () that toggles a cute little overlay like the ? window for gmail+--   and reader.+--+-- Add dzen binding++deriving instance Show XMonad.Resize+deriving instance Show XMonad.IncMasterN++-- | 'sendMessage' but add a description that is @show message@. Note that not+-- all messages have show instances.+sendMessage' :: (Message a, Show a) => a -> NamedAction+sendMessage' x = NamedAction $ (XMonad.sendMessage x,show x)++-- | 'spawn' but the description is the string passed+spawn' :: String -> NamedAction+spawn' x = addName x $ spawn x++class HasName a where+    showName :: a -> [String]+    showName = const [""]+    getAction :: a -> X ()++instance HasName (X ()) where+    getAction = id++instance HasName (IO ()) where+    getAction = io++instance HasName [Char] where+    getAction _ = return ()+    showName = (:[])++instance HasName (X (),String) where+    showName = (:[]) . snd+    getAction = fst++instance HasName (X (),[String]) where+    showName = snd+    getAction = fst++-- show only the outermost description+instance HasName (NamedAction,String) where+    showName = (:[]) . snd+    getAction = getAction . fst++instance HasName NamedAction where+    showName (NamedAction x) = showName x+    getAction (NamedAction x) = getAction x++-- | An existential wrapper so that different types can be combined in lists,+-- and maps+data NamedAction = forall a. HasName a => NamedAction a++-- | 'submap', but propagate the descriptions of the actions. Does this belong+-- in "XMonad.Actions.Submap"?+submapName :: (HasName a) => [((KeyMask, KeySym), a)] -> NamedAction+submapName = NamedAction . (submap . M.map getAction . M.fromList &&& showKm)+                . map (second NamedAction)++-- | Combine keymap lists with actions that may or may not have names+(^++^) :: (HasName b, HasName b1) =>+     [(d, b)] -> [(d, b1)] -> [(d, NamedAction)]+a ^++^ b = map (second NamedAction) a ++ map (second NamedAction) b++-- | Or allow another lookup table?+modToString :: KeyMask -> String+modToString mask = concatMap (++"-") $ filter (not . null)+                $ map (uncurry pick)+                [(mod1Mask, "M1")+                ,(mod2Mask, "M2")+                ,(mod3Mask, "M3")+                ,(mod4Mask, "M4")+                ,(mod5Mask, "M5")+                ,(controlMask, "C")+                ,(shiftMask,"Shift")]+    where pick m str = if m .&. complement mask == 0 then str else ""++keyToString :: (KeyMask, KeySym) -> [Char]+keyToString = uncurry (++) . (modToString *** keysymToString)++showKmSimple :: [((KeyMask, KeySym), NamedAction)] -> [[Char]]+showKmSimple = concatMap (\(k,e) -> if snd k == 0 then "":showName e else map ((keyToString k ++) . smartSpace) $ showName e)++smartSpace :: String -> String+smartSpace [] = []+smartSpace xs = ' ':xs++_test :: String+_test = unlines $ showKm $ defaultKeysDescr XMonad.defaultConfig { XMonad.layoutHook = XMonad.Layout $ XMonad.layoutHook XMonad.defaultConfig }++showKm :: [((KeyMask, KeySym), NamedAction)] -> [String]+showKm keybindings = padding $ do+    (k,e) <- keybindings+    if snd k == 0 then map ((,) "") $ showName e+        else map ((,) (keyToString k) . smartSpace) $ showName e+    where padding = let pad n (k,e) = if null k then "\n>> "++e else take n (k++repeat ' ') ++ e+                        expand xs n = map (pad n) xs+                        getMax = map (maximum . map (length . fst))+            in concat . (zipWith expand <*> getMax) . groupBy (const $ not . null . fst)++-- | An action to send to 'addDescrKeys' for showing the keybindings. See also 'showKm' and 'showKmSimple'+xMessage :: [((KeyMask, KeySym), NamedAction)] -> NamedAction+xMessage x = addName "Show Keybindings" $ io $ do+    xfork $ executeFile "xmessage" True ["-default", "okay", unlines $ showKm x] Nothing+    return ()++-- | Merge the supplied keys with 'defaultKeysDescr', also adding a keybinding+-- to run an action for showing the keybindings.+addDescrKeys :: (HasName b1, HasName b) =>+    ((KeyMask, KeySym),[((KeyMask, KeySym), NamedAction)] -> b)+    -> (XConfig Layout -> [((KeyMask, KeySym), b1)])+    -> XConfig l+    -> XConfig l+addDescrKeys k ks = addDescrKeys' k (\l -> defaultKeysDescr l ^++^ ks l)++-- | Without merging with 'defaultKeysDescr'+addDescrKeys' :: (HasName b) =>+    ((KeyMask, KeySym),[((KeyMask, KeySym), NamedAction)] -> b)+    -> (XConfig Layout -> [((KeyMask, KeySym), NamedAction)]) -> XConfig l -> XConfig l+addDescrKeys' (k,f) ks conf =+    let shk l = f $ [(k,f $ ks l)] ^++^ ks l+        keylist l = M.map getAction $ M.fromList $ ks l ^++^ [(k, shk l)]+    in conf { keys = keylist }++-- | A version of the default keys from 'XMonad.Config.defaultConfig', but with+-- 'NamedAction'  instead of @X ()@+defaultKeysDescr :: XConfig Layout -> [((KeyMask, KeySym), NamedAction)]+defaultKeysDescr conf@(XConfig {XMonad.modMask = modm}) =+    [ subtitle "launching and killing programs"+    , ((modm .|. shiftMask, xK_Return), addName "Launch Terminal" $ spawn $ XMonad.terminal conf) -- %! Launch terminal+    , ((modm,               xK_p     ), addName "Launch dmenu" $ spawn "exe=`dmenu_path | dmenu` && eval \"exec $exe\"") -- %! Launch dmenu+    , ((modm .|. shiftMask, xK_p     ), addName "Launch gmrun" $ spawn "gmrun") -- %! Launch gmrun+    , ((modm .|. shiftMask, xK_c     ), addName "Close the focused window" kill) -- %! Close the focused window++    , subtitle "changing layouts"+    , ((modm,               xK_space ), sendMessage' NextLayout) -- %! Rotate through the available layout algorithms+    , ((modm .|. shiftMask, xK_space ), addName "Reset the layout" $ setLayout $ XMonad.layoutHook conf) -- %!  Reset the layouts on the current workspace to default++    , separator+    , ((modm,               xK_n     ), addName "Refresh" refresh) -- %! Resize viewed windows to the correct size++    , subtitle "move focus up or down the window stack"+    , ((modm,               xK_Tab   ), addName "Focus down" $ windows W.focusDown) -- %! Move focus to the next window+    , ((modm .|. shiftMask, xK_Tab   ), addName "Focus up"   $ windows W.focusUp  ) -- %! Move focus to the previous window+    , ((modm,               xK_j     ), addName "Focus down" $ windows W.focusDown) -- %! Move focus to the next window+    , ((modm,               xK_k     ), addName "Focus up"   $ windows W.focusUp  ) -- %! Move focus to the previous window+    , ((modm,               xK_m     ), addName "Focus the master" $ windows W.focusMaster  ) -- %! Move focus to the master window++    , subtitle "modifying the window order"+    , ((modm,               xK_Return), addName "Swap with the master" $ windows W.swapMaster) -- %! Swap the focused window and the master window+    , ((modm .|. shiftMask, xK_j     ), addName "Swap down" $ windows W.swapDown  ) -- %! Swap the focused window with the next window+    , ((modm .|. shiftMask, xK_k     ), addName "Swap up"   $ windows W.swapUp    ) -- %! Swap the focused window with the previous window++    , subtitle "resizing the master/slave ratio"+    , ((modm,               xK_h     ), sendMessage' Shrink) -- %! Shrink the master area+    , ((modm,               xK_l     ), sendMessage' Expand) -- %! Expand the master area++    , subtitle "floating layer support"+    , ((modm,               xK_t     ), addName "Push floating to tiled" $ withFocused $ windows . W.sink) -- %! Push window back into tiling++    , subtitle "change the number of windows in the master area"+    , ((modm              , xK_comma ), sendMessage' (IncMasterN 1)) -- %! Increment the number of windows in the master area+    , ((modm              , xK_period), sendMessage' (IncMasterN (-1))) -- %! Deincrement the number of windows in the master area++    , subtitle "quit, or restart"+    , ((modm .|. shiftMask, xK_q     ), addName "Quit" $ io (exitWith ExitSuccess)) -- %! Quit xmonad+    , ((modm              , xK_q     ), addName "Restart" $ spawn "xmonad --recompile && xmonad --restart") -- %! Restart xmonad+    ]++    -- mod-[1..9] %! Switch to workspace N+    -- mod-shift-[1..9] %! Move client to workspace N+    +++    subtitle "switching workspaces":+    [((m .|. modm, k), addName (n ++ i) $ windows $ f i)+        | (f, m, n) <- [(W.greedyView, 0, "Switch to workspace "), (W.shift, shiftMask, "Move client to workspace ")]+        , (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9]]+    -- mod-{w,e,r} %! Switch to physical/Xinerama screens 1, 2, or 3+    -- mod-shift-{w,e,r} %! Move client to screen 1, 2, or 3+   +++   subtitle "switching screens" :+   [((m .|. modm, key), addName (n ++ show sc) $ screenWorkspace sc >>= flip whenJust (windows . f))+        | (f, m, n) <- [(W.view, 0, "Switch to screen number "), (W.shift, shiftMask, "Move client to screen number ")]+        , (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]]++-- | For a prettier presentation: keymask, keysym of 0 are reserved for this+-- purpose: they do not happen, afaik, and keysymToString 0 would raise an+-- error otherwise+separator :: ((KeyMask,KeySym), NamedAction)+separator = ((0,0), NamedAction (return () :: X (),[] :: [String]))++subtitle ::  String -> ((KeyMask, KeySym), NamedAction)+subtitle x = ((0,0), NamedAction $ x ++ ":")++-- | These are just the @NamedAction@ constructor but with a more specialized+-- type, so that you don't have to supply any annotations, for ex coercing+-- spawn to @X ()@ from the more general @MonadIO m => m ()@+noName :: X () -> NamedAction+noName = NamedAction++oneName :: (X (), String) -> NamedAction+oneName = NamedAction++addName :: String -> X () -> NamedAction+addName = flip (curry NamedAction)
XMonad/Util/NamedScratchpad.hs view
@@ -17,6 +17,9 @@   -- * Usage   -- $usage   NamedScratchpad(..),+  nonFloating,+  defaultFloating,+  customFloating,   NamedScratchpads,   namedScratchpadAction,   namedScratchpadManageHook,@@ -24,13 +27,11 @@   ) where  import XMonad-import XMonad.Core-import XMonad.ManageHook (composeAll,doFloat) import XMonad.Hooks.ManageHelpers (doRectFloat) import XMonad.Actions.DynamicWorkspaces (addHiddenWorkspace)  import Control.Monad (filterM)-import Data.Maybe (maybe,listToMaybe)+import Data.Maybe (listToMaybe)  import qualified XMonad.StackSet as W @@ -54,19 +55,24 @@ -- > import XMonad.Util.NamedScratchpad -- > -- > scratchpads = [--- > -- run htop in xterm, find it by title, use default geometry--- >     NS "htop" "xterm -e htop" (title =? "htop") Nothing ,--- > -- run stardict, find it by class name, place the window+-- > -- run htop in xterm, find it by title, use default floating window placement+-- >     NS "htop" "xterm -e htop" (title =? "htop") defaultFloating ,+-- >+-- > -- run stardict, find it by class name, place it in the floating window -- > -- 1/6 of screen width from the left, 1/6 of screen height -- > -- from the top, 2/3 of screen width by 2/3 of screen height -- >     NS "stardict" "stardict" (className =? "Stardict")--- >         (Just $ W.RationalRect (1/6) (1/6) (2/3) (2/3))--- > ]+-- >         (customFloating $ W.RationalRect (1/6) (1/6) (2/3) (2/3)) ,+-- >+-- > -- run gvim, find by role, don't float+-- >     NS "notes" "gvim --role notes ~/notes.txt" (role =? "notes") nonFloating+-- > ] where role = stringProperty "WM_WINDOW_ROLE" -- -- Add keybindings: ----- >  , ((modMask x .|. controlMask .|. shiftMask, xK_t), namedScratchpadAction scratchpads "htop")--- >  , ((modMask x .|. controlMask .|. shiftMask, xK_s), namedScratchpadAction scratchpads "stardict")+-- >  , ((modm .|. controlMask .|. shiftMask, xK_t), namedScratchpadAction scratchpads "htop")+-- >  , ((modm .|. controlMask .|. shiftMask, xK_s), namedScratchpadAction scratchpads "stardict")+-- >  , ((modm .|. controlMask .|. shiftMask, xK_n), namedScratchpadAction scratchpads "notes") -- -- ... and a manage hook: --@@ -77,18 +83,30 @@ --  -- | Single named scratchpad configuration-data NamedScratchpad = NS { name  :: String               -- ^ Scratchpad name-                          , cmd   :: String               -- ^ Command used to run application-                          , query :: Query Bool           -- ^ Query to find already running application-                          , rect  :: Maybe W.RationalRect -- ^ Floating window geometry+data NamedScratchpad = NS { name   :: String      -- ^ Scratchpad name+                          , cmd    :: String      -- ^ Command used to run application+                          , query  :: Query Bool  -- ^ Query to find already running application+                          , hook   :: ManageHook  -- ^ Manage hook called for application window, use it to define the placement. See @nonFloating@, @defaultFloating@ and @customFloating@                           } +-- | Manage hook that makes the window non-floating+nonFloating :: ManageHook+nonFloating = idHook++-- | Manage hook that makes the window floating with the default placement+defaultFloating :: ManageHook+defaultFloating = doFloat++-- | Manage hook that makes the window floating with custom placement+customFloating :: W.RationalRect -> ManageHook+customFloating = doRectFloat+ -- | Named scratchpads configuration type NamedScratchpads = [NamedScratchpad]  -- | Finds named scratchpad configuration by name findByName :: NamedScratchpads -> String -> Maybe NamedScratchpad-findByName c s = listToMaybe $ filter ((s==).name) c+findByName c s = listToMaybe $ filter ((s==) . name) c  -- | Runs application which should appear in specified scratchpad runApplication :: NamedScratchpad -> X ()@@ -128,7 +146,7 @@ -- | Manage hook to use with named scratchpads namedScratchpadManageHook :: NamedScratchpads -- ^ Named scratchpads configuration                           -> ManageHook-namedScratchpadManageHook = composeAll . fmap (\c -> query c --> maybe doFloat doRectFloat (rect c))+namedScratchpadManageHook = composeAll . fmap (\c -> query c --> hook c)  -- | Transforms a workspace list containing the NSP workspace into one that -- doesn't contain it. Intended for use with logHooks.
XMonad/Util/NamedWindows.hs view
@@ -24,7 +24,7 @@  import Prelude hiding ( catch ) import Control.Applicative ( (<$>) )-import Control.Exception ( bracket, catch )+import Control.Exception.Extensible ( bracket, catch, SomeException(..) ) import Data.Maybe ( fromMaybe, listToMaybe )  import qualified XMonad.StackSet as W ( peek )@@ -50,11 +50,11 @@     let getIt = bracket getProp (xFree . tp_value) (fmap (`NW` w) . copy)          getProp = (internAtom d "_NET_WM_NAME" False >>= getTextProperty d w)-                      `catch` \_ -> getTextProperty d w wM_NAME+                      `catch` \(SomeException _) -> getTextProperty d w wM_NAME          copy prop = fromMaybe "" . listToMaybe <$> wcTextPropertyToTextList d prop -    io $ getIt `catch` \_ ->  ((`NW` w) . resName) `fmap` getClassHint d w+    io $ getIt `catch` \(SomeException _) ->  ((`NW` w) . resName) `fmap` getClassHint d w  unName :: NamedWindow -> Window unName (NW _ w) = w
XMonad/Util/Paste.hs view
@@ -28,8 +28,10 @@ import Control.Monad.Reader (asks) import XMonad.Operations (withFocused) import Data.Char (isUpper)-import Graphics.X11.Xlib.Misc (stringToKeysym)+import Data.Maybe (listToMaybe) import XMonad.Util.XSelection (getSelection)+import XMonad.Util.EZConfig (parseKey)+import Text.ParserCombinators.ReadP (readP_to_S)  {- $usage @@ -70,7 +72,8 @@    have trouble with any 'Char' outside ASCII. -} pasteChar :: KeyMask -> Char -> X ()-pasteChar m c = sendKey m $ stringToKeysym [c]+pasteChar m c = sendKey m $ maybe (stringToKeysym [c]) fst+                $ listToMaybe $ readP_to_S parseKey [c]  sendKey :: KeyMask -> KeySym -> X () sendKey = (withFocused .) . sendKeyWindow
+ XMonad/Util/PositionStore.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE DeriveDataTypeable #-}++----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Util.PositionStore+-- Copyright   :  (c) Jan Vornberger 2009+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de+-- Stability   :  unstable+-- Portability :  not portable+--+-- A utility module to store information about position and size of a window.+-- See "XMonad.Layout.PositionStoreFloat" for a layout that makes use of this.+--+-----------------------------------------------------------------------------++module XMonad.Util.PositionStore (+        getPosStore,+        modifyPosStore,++        posStoreInsert,+        posStoreMove,+        posStoreQuery,+        posStoreRemove+    ) where++import XMonad+import qualified XMonad.Util.ExtensibleState as XS+import qualified Data.Map as M++-- Store window positions relative to the upper left screen edge+-- and windows sizes as well as positions as fractions of the screen size.+-- This way windows can be easily relocated and scaled when switching screens.++data PositionStore = PS (M.Map Window PosStoreRectangle)+                            deriving (Read,Show,Typeable)+data PosStoreRectangle = PSRectangle Double Double Double Double+                            deriving (Read,Show,Typeable)++instance ExtensionClass PositionStore where+  initialValue = PS M.empty+  extensionType = PersistentExtension++getPosStore :: X (PositionStore)+getPosStore = XS.get++modifyPosStore :: (PositionStore -> PositionStore) -> X ()+modifyPosStore = XS.modify++posStoreInsert :: PositionStore -> Window -> Rectangle -> Rectangle -> PositionStore+posStoreInsert (PS posStoreMap) w (Rectangle x y wh ht) (Rectangle srX srY srWh srHt) =+    let offsetX = x - srX+        offsetY = y - srY+    in PS $ M.insert w (PSRectangle (fromIntegral offsetX / fromIntegral srWh)+                                               (fromIntegral offsetY / fromIntegral srHt)+                                               (fromIntegral wh / fromIntegral srWh)+                                               (fromIntegral ht / fromIntegral srHt)) posStoreMap++posStoreRemove :: PositionStore -> Window -> PositionStore+posStoreRemove (PS posStoreMap) w = PS $ M.delete w posStoreMap++posStoreQuery :: PositionStore -> Window -> Rectangle -> Maybe Rectangle+posStoreQuery (PS posStoreMap) w (Rectangle srX srY srWh srHt) = do+    (PSRectangle x y wh ht) <- M.lookup w posStoreMap+    let realWh = fromIntegral srWh * wh+        realHt = fromIntegral srHt * ht+        realOffsetX = fromIntegral srWh * x+        realOffsetY = fromIntegral srHt * y+    return (Rectangle (srX + round realOffsetX) (srY + round realOffsetY)+                        (round realWh) (round realHt))++posStoreMove :: PositionStore -> Window -> Position -> Position -> Rectangle -> Rectangle -> PositionStore+posStoreMove posStore w x y oldSr newSr =+    case (posStoreQuery posStore w oldSr) of+        Nothing -> posStore     -- not in store, can't move -> do nothing+        Just (Rectangle _ _ wh ht) -> posStoreInsert posStore w (Rectangle x y wh ht) newSr
+ XMonad/Util/Replace.hs view
@@ -0,0 +1,116 @@+{-# LANGUAGE DeriveDataTypeable #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Util.Replace+-- Copyright   :  (c) Jan Vornberger 2009+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Adam Vogt <vogt.adam@gmail.com>+-- Stability   :  unstable+-- Portability :  unportable+--+-- Implements a @--replace@ behavior outside of core.+--+-----------------------------------------------------------------------------++-- refer to core patches:+-- http://article.gmane.org/gmane.comp.lang.haskell.xmonad/8358+module XMonad.Util.Replace+    ( -- * Usage+      -- $usage+      replace++      -- * Notes+      -- $shortcomings++      -- ** Implementing a @--replace@ flag+      -- $getArgs+    ) where++import XMonad+import Data.Function+import Control.Monad++-- $usage+-- You must run the 'replace' action before starting xmonad proper, this+-- results in xmonad replacing the currently running WM regardless of the+-- arguments it is run with:+--+-- > import XMonad+-- > import XMonad.Util.Replace+-- > main = do+-- >    replace+-- >    xmonad $ defaultConfig { .... }+--++-- $shortcomings+-- This doesn't seem to work for replacing WMs that have been started+-- from within xmonad, such as with @'restart' "openbox" False@, but no other+-- WMs that implements --replace manage this either. 'replace' works for+-- replacing metacity when the full gnome-session is started at least.++-- $getArgs+-- You can use 'System.Environment.getArgs' to watch for an explicit+-- @--replace@ flag:+--+-- > import XMonad+-- > import XMonad.Util.Replace (replace)+-- > import Control.Monad (when)+-- > import System.Environment (getArgs)+-- >+-- > main = do+-- >    args <- getArgs+-- >    when ("--replace" `elem` args) replace+-- >    xmonad $ defaultConfig { .... }+--+--+-- Note that your @~\/.xmonad/xmonad-$arch-$os@ binary is not run with the same+-- flags as the @xmonad@ binary that calls it. You may be able to work around+-- this by running your @~\/.xmonad/xmonad-$arch-$os@ binary directly, which is+-- otherwise not recommended.++-- | @replace@ must be run before xmonad starts to signals to compliant window+-- managers that they must exit and let xmonad take over.+replace :: IO ()+replace = do+    dpy   <- openDisplay ""+    let dflt = defaultScreen dpy++    rootw  <- rootWindow dpy dflt++    -- check for other WM+    wmSnAtom <- internAtom dpy ("WM_S" ++ (show dflt)) False+    currentWmSnOwner <- xGetSelectionOwner dpy wmSnAtom+    when (currentWmSnOwner /= 0) $ do+        putStrLn $ "Screen " ++ (show dflt) ++ " on display \""+                    ++ (displayString dpy) ++ "\" already has a window manager."++        -- prepare to receive destroyNotify for old WM+        selectInput dpy currentWmSnOwner structureNotifyMask++        -- create off-screen window+        netWmSnOwner <- allocaSetWindowAttributes $ \attributes -> do+            set_override_redirect attributes True+            set_event_mask attributes propertyChangeMask+            let screen = defaultScreenOfDisplay dpy+            let visual = defaultVisualOfScreen screen+            let attrmask = cWOverrideRedirect .|. cWEventMask+            createWindow dpy rootw (-100) (-100) 1 1 0 copyFromParent copyFromParent visual attrmask attributes++        -- try to acquire wmSnAtom, this should signal the old WM to terminate+        putStrLn $ "Replacing existing window manager..."+        xSetSelectionOwner dpy wmSnAtom netWmSnOwner currentTime++        -- SKIPPED: check if we acquired the selection+        -- SKIPPED: send client message indicating that we are now the WM++        -- wait for old WM to go away+        putStr $ "Waiting for other window manager to terminate... "+        fix $ \again -> do+            evt <- allocaXEvent $ \event -> do+                windowEvent dpy currentWmSnOwner structureNotifyMask event+                get_EventType event++            when (evt /= destroyNotify) again+        putStrLn $ "done"+    closeDisplay dpy
XMonad/Util/Run.hs view
@@ -21,6 +21,7 @@                           runProcessWithInput,                           runProcessWithInputAndWait,                           safeSpawn,+                          safeSpawnProg,                           unsafeSpawn,                           runInTerm,                           safeRunInTerm,@@ -31,9 +32,10 @@                          ) where  import System.Posix.IO-import System.Posix.Process (executeFile, forkProcess, createSession)+import System.Posix.Process (executeFile)+import System.Posix.Types (ProcessID) import Control.Concurrent (threadDelay)-import Control.Exception (try) -- use OldException with base 4+import Control.Exception.Extensible (try,SomeException) import System.IO import System.Process (runInteractiveProcess) import XMonad@@ -50,10 +52,9 @@ -- For an example usage of 'runProcessWithInputAndWait' see -- "XMonad.Util.Dzen" --- | Return output if the command succeeded, otherwise return @()@.--- This corresponds to dmenu's notion of exit code 1 for a cancelled invocation.-runProcessWithInput :: FilePath -> [String] -> String -> IO String-runProcessWithInput cmd args input = do+-- | Returns the output.+runProcessWithInput :: MonadIO m => FilePath -> [String] -> String -> m String+runProcessWithInput cmd args input = io $ do     (pin, pout, perr, _) <- runInteractiveProcess cmd args Nothing Nothing     hPutStr pin input     hClose pin@@ -65,9 +66,9 @@     return output  -- | Wait is in µs (microseconds)-runProcessWithInputAndWait :: FilePath -> [String] -> String -> Int -> IO ()-runProcessWithInputAndWait cmd args input timeout = do-    forkProcess $ do+runProcessWithInputAndWait :: MonadIO m => FilePath -> [String] -> String -> Int -> m ()+runProcessWithInputAndWait cmd args input timeout = io $ do+    xfork $ do         (pin, pout, perr, _) <- runInteractiveProcess cmd args Nothing Nothing         hPutStr pin input         hFlush pin@@ -99,16 +100,24 @@ of it can be, well, unsafe. Examples: -> , ((modMask, xK_Print), unsafeSpawn "import -window root $HOME/xwd-$(date +%s)$$.png")-> , ((modMask, xK_d    ), safeSpawn "firefox" "")+> , ((modm, xK_Print), unsafeSpawn "import -window root $HOME/xwd-$(date +%s)$$.png")+> , ((modm, xK_d    ), safeSpawn "firefox" "")  Note that the unsafeSpawn example must be unsafe and not safe because it makes use of shell interpretation by relying on @$HOME@ and interpolation, whereas the safeSpawn example can be safe because Firefox doesn't need any arguments if it is just being started. -}-safeSpawn :: MonadIO m => FilePath -> String -> m ()-safeSpawn prog arg = liftIO (try (forkProcess $ executeFile prog True [arg] Nothing) >> return ())+safeSpawn :: MonadIO m => FilePath -> [String] -> m ()+safeSpawn prog args = liftIO $ do+    try $ xfork $ executeFile prog True args Nothing :: IO (Either SomeException ProcessID)+    return () +-- | Like 'safeSpawn', but only takes a program (and no arguments for it). eg.+--+-- > safeSpawnProg "firefox"+safeSpawnProg :: MonadIO m => FilePath -> m ()+safeSpawnProg = flip safeSpawn []+ unsafeSpawn :: MonadIO m => String -> m () unsafeSpawn = spawn @@ -120,18 +129,17 @@  -- | Run a given program in the preferred terminal emulator; see 'runInTerm'. This makes use of 'safeSpawn'. safeRunInTerm :: String -> String -> X ()-safeRunInTerm options command = asks (terminal . config) >>= \t -> safeSpawn t (options ++ " -e " ++ command)+safeRunInTerm options command = asks (terminal . config) >>= \t -> safeSpawn t [options, " -e " ++ command]  -- | Launch an external application through the system shell and return a @Handle@ to its standard input.-spawnPipe :: String -> IO Handle-spawnPipe x = do+spawnPipe :: MonadIO m => String -> m Handle+spawnPipe x = io $ do     (rd, wr) <- createPipe     setFdOption wr CloseOnExec True     h <- fdToHandle wr     hSetBuffering h LineBuffering-    forkProcess $ do-        createSession-        uninstallSignalHandlers+    xfork $ do         dupTo rd stdInput         executeFile "/bin/sh" False ["-c", x] Nothing+    closeFd rd     return h
XMonad/Util/Scratchpad.hs view
@@ -24,13 +24,8 @@   ) where  import XMonad-import XMonad.Core-import XMonad.Hooks.ManageHelpers (doRectFloat)-import XMonad.Actions.DynamicWorkspaces (addHiddenWorkspace)--import Control.Monad (filterM)- import qualified XMonad.StackSet as W+import XMonad.Util.NamedScratchpad   -- $usage@@ -38,10 +33,10 @@ -- Pressing it will spawn the terminal, or bring it to the current -- workspace if it already exists. -- Pressing the key with the terminal on the current workspace will--- send it to a hidden workspace called @SP@.+-- send it to a hidden workspace called @NSP@. ----- If you already have a workspace called @SP@, it will use that.--- @SP@ will also appear in xmobar and dzen status bars. You can tweak your+-- If you already have a workspace called @NSP@, it will use that.+-- @NSP@ will also appear in xmobar and dzen status bars. You can tweak your -- @dynamicLog@ settings to filter it out if you like. -- -- A tool like detach (<http://detach.sourceforge.net>) turns it@@ -73,53 +68,23 @@ scratchpadSpawnAction :: XConfig l -- ^ The configuration, to retrieve the terminal                       -> X () scratchpadSpawnAction conf =-    scratchpadAction $ spawn $ terminal conf ++ " -name scratchpad"+    scratchpadSpawnActionCustom $ terminal conf ++ " -name scratchpad"   -- | Action to pop up the terminal, with a directly specified terminal. scratchpadSpawnActionTerminal :: String -- ^ Name of the terminal program                                  -> X () scratchpadSpawnActionTerminal term =-    scratchpadAction $ spawn $ term ++ " -name scratchpad"+    scratchpadSpawnActionCustom $ term ++ " -name scratchpad"  --- | Action to pop up any program with the user specifiying how to set---   its resource to \"scratchpad\". For example, with gnome-terminal---   bind the following to a key:+-- | Action to pop up any program with the user specifying how to set+--   its resource to \"scratchpad\". For example, with gnome-terminal: -----   > scratchpadSpawnActionCustom "gnome-terminal --name scratchpad"+-- > scratchpadSpawnActionCustom "gnome-terminal --disable-factory --name scratchpad" scratchpadSpawnActionCustom :: String -- ^ Command to spawn a program with resource \"scratchpad\"                                  -> X ()-scratchpadSpawnActionCustom = scratchpadAction . spawn---- The heart of the new summon/banish terminal.--- The logic is thus:--- 1. if the scratchpad is on the current workspace, send it to the hidden one.---    - if the scratchpad workspace doesn't exist yet, create it first.--- 2. if the scratchpad is elsewhere, bring it here.-scratchpadAction :: X () -> X ()-scratchpadAction action = withWindowSet $ \s -> do-  filterCurrent <- filterM (runQuery scratchpadQuery)-                     ( (maybe [] W.integrate-                        . W.stack-                        . W.workspace-                        . W.current) s)-  case filterCurrent of-    (x:_) -> do-      if null (filter ( (== scratchpadWorkspaceTag) . W.tag) (W.workspaces s))-         then addHiddenWorkspace scratchpadWorkspaceTag-         else return ()-      windows (W.shiftWin scratchpadWorkspaceTag x)-    []    -> do-      filterAll <- filterM (runQuery scratchpadQuery) (W.allWindows s)-      case filterAll of-        (x:_) -> windows (W.shiftWin (W.currentTag s) x)-        []    -> action -- run the provided action to spawn it.----- factored out since it appears in several places-scratchpadWorkspaceTag :: String-scratchpadWorkspaceTag = "SP"+scratchpadSpawnActionCustom c = namedScratchpadAction [NS "scratchpad" c scratchpadQuery nonFloating] "scratchpad"  -- factored out since this is common to both the ManageHook and the action scratchpadQuery :: Query Bool@@ -129,7 +94,7 @@ -- | The ManageHook, with the default rectangle: -- Half the screen wide, a quarter of the screen tall, centered. scratchpadManageHookDefault :: ManageHook-scratchpadManageHookDefault = scratchpadManageHook scratchpadDefaultRect+scratchpadManageHookDefault = namedScratchpadManageHook [NS "" "" scratchpadQuery (customFloating scratchpadDefaultRect)]   -- | The ManageHook, with a user-specified StackSet.RationalRect,@@ -140,13 +105,13 @@ -- > scratchpadManageHook (W.RationalRect 0.4 0.5 0.6 0.3) scratchpadManageHook :: W.RationalRect -- ^ User-specified screen rectangle.                      -> ManageHook-scratchpadManageHook rect = scratchpadQuery --> doRectFloat rect+scratchpadManageHook rect = namedScratchpadManageHook [NS "" "" scratchpadQuery (customFloating rect)]   -- | Transforms a workspace list containing the SP workspace into one that -- doesn't contain it. Intended for use with logHooks. scratchpadFilterOutWorkspace :: [WindowSpace] -> [WindowSpace]-scratchpadFilterOutWorkspace = filter (\(W.Workspace tag _ _) -> tag /= scratchpadWorkspaceTag)+scratchpadFilterOutWorkspace = namedScratchpadFilterOutWorkspace   scratchpadDefaultRect :: W.RationalRect
+ XMonad/Util/SpawnOnce.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE DeriveDataTypeable #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Util.ExtensibleState+-- Copyright   :  (c) Spencer Janssen 2009+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  spencerjanssen@gmail.com+-- Stability   :  unstable+-- Portability :  not portable+--+-- A module for spawning a command once, and only once.  Useful to start+-- status bars and make session settings inside startupHook.+--+-----------------------------------------------------------------------------++module XMonad.Util.SpawnOnce (spawnOnce) where++import XMonad+import Data.Set as Set+import qualified XMonad.Util.ExtensibleState as XS+import Control.Monad++data SpawnOnce = SpawnOnce { unspawnOnce :: (Set String) }+    deriving (Read, Show, Typeable)++instance ExtensionClass SpawnOnce where+    initialValue = SpawnOnce Set.empty+    extensionType = PersistentExtension++-- | The first time 'spawnOnce' is executed on a particular command, that+-- command is executed.  Subsequent invocations for a command do nothing.+spawnOnce :: String -> X ()+spawnOnce xs = do+    b <- XS.gets (Set.member xs . unspawnOnce)+    when (not b) $ do+        spawn xs+        XS.modify (SpawnOnce . Set.insert xs . unspawnOnce)
+ XMonad/Util/StringProp.hs view
@@ -0,0 +1,56 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Util.StringProp+-- Copyright   :  (c) Nicolas Pouillard 2009+-- License     :  BSD-style (see LICENSE)+--+-- Maintainer  :  Nicolas Pouillard <nicolas.pouillard@gmail.com>+-- Stability   :  unstable+-- Portability :  unportable+--+-- Internal utility functions for storing Strings with the root window.+--+-- Used for global state like IORefs with string keys, but more latency,+-- persistent between xmonad restarts.++module XMonad.Util.StringProp (+    StringProp,+    getStringProp, setStringProp,+    getStringListProp, setStringListProp,+    ) where++import XMonad+import Control.Monad(liftM)+import Control.Applicative((<$>))+import Foreign.C.String (castCCharToChar,castCharToCChar)++type StringProp = String++withStringProp :: (MonadIO m) => StringProp -> Display -> (Window -> Atom -> m b) -> m b+withStringProp prop dpy f = do+    rootw <- io $ rootWindow dpy $ defaultScreen dpy+    a     <- io $ internAtom dpy prop False+    f rootw a++-- | Set the value of a string property.+setStringProp :: (MonadIO m) => Display -> StringProp -> [Char] -> m ()+setStringProp dpy prop string =+  withStringProp prop dpy $ \rootw a ->+    io $ changeProperty8 dpy rootw a a propModeReplace $ map castCharToCChar string++-- | Get the name of a string property and returns it as a 'Maybe'.+getStringProp :: (MonadIO m) => Display -> StringProp -> m (Maybe [Char])+getStringProp dpy prop =+  withStringProp prop dpy $ \rootw a -> do+    p <- io $ getWindowProperty8 dpy a rootw+    return $ map castCCharToChar <$> p++-- | Given a property name, returns its contents as a list. It uses the empty+-- list as default value.+getStringListProp :: (MonadIO m) => Display -> StringProp -> m [String]+getStringListProp dpy prop = maybe [] words `liftM` getStringProp dpy prop++-- | Given a property name and a list, sets the value of this property with+-- the list given as argument.+setStringListProp :: (MonadIO m) => Display -> StringProp -> [String] -> m ()+setStringListProp dpy prop str = setStringProp dpy prop (unwords str)
XMonad/Util/Themes.hs view
@@ -96,14 +96,14 @@                , robertTheme                , donaldTheme                , wfarrTheme-	       , kavonForestTheme-	       , kavonLakeTheme-	       , kavonPeacockTheme-	       , kavonVioGreenTheme-	       , kavonBluesTheme-	       , kavonAutumnTheme-	       , kavonFireTheme-	       , kavonChristmasTheme+               , kavonForestTheme+               , kavonLakeTheme+               , kavonPeacockTheme+               , kavonVioGreenTheme+               , kavonBluesTheme+               , kavonAutumnTheme+               , kavonFireTheme+               , kavonChristmasTheme                ]  -- | The default xmonad theme, by David Roundy.
XMonad/Util/Timer.hs view
@@ -23,7 +23,6 @@ import Control.Applicative import Control.Concurrent import Data.Unique-import System.Posix.Process (forkProcess)  -- $usage -- This module can be used to setup a timer to handle deferred events.@@ -36,7 +35,7 @@ startTimer :: Rational -> X TimerId startTimer s = io $ do   u   <- hashUnique <$> newUnique-  forkProcess $ do+  xfork $ do     d   <- openDisplay ""     rw  <- rootWindow d $ defaultScreen d     threadDelay (fromEnum $ s * 1000000)
+ XMonad/Util/Types.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE DeriveDataTypeable #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  XMonad.Util.Types+-- Copyright   :  (c) Daniel Schoepe (2009)+-- License     :  BSD3-style (see LICENSE)+--+-- Maintainer  :  Daniel Schoepe <daniel.schoepe@gmail.com>+-- Stability   :  unstable+-- Portability :  unportable+--+-- Miscellaneous commonly used types.+--+-----------------------------------------------------------------------------++module XMonad.Util.Types (Direction1D(..)+                         ,Direction2D(..)+                         ) where++import Data.Typeable (Typeable)++-- | One-dimensional directions:+data Direction1D = Next | Prev deriving (Eq,Read,Show,Typeable)++-- | Two-dimensional directions:+data Direction2D = U -- ^ Up+                 | D -- ^ Down+                 | R -- ^ Right+                 | L -- ^ Left+                   deriving (Eq,Read,Show,Ord,Enum,Bounded,Typeable)
XMonad/Util/WindowProperties.hs view
@@ -38,7 +38,8 @@               | ClassName String               | Resource String               | Role String -- ^ WM_WINDOW_ROLE property-              | And Property Property  +              | Machine String -- ^ WM_CLIENT_MACHINE property+              | And Property Property               | Or  Property Property               | Not Property               | Const Bool@@ -48,14 +49,7 @@  -- | Does given window have this property? hasProperty :: Property -> Window -> X Bool-hasProperty (Title s)     w = withDisplay $ \d -> fmap (Just s ==) $ io $ fetchName d w-hasProperty (Resource s)  w = withDisplay $ \d -> fmap ((==) s . resName ) $ io $ getClassHint d w-hasProperty (ClassName s) w = withDisplay $ \d -> fmap ((==) s . resClass) $ io $ getClassHint d w-hasProperty (Role s) w = withDisplay $ \d -> fmap ((==) (Just s)) $ getStringProperty d w "WM_WINDOW_ROLE"-hasProperty (And p1 p2)   w = do { r1 <- hasProperty p1 w; r2 <- hasProperty p2 w; return $ r1 && r2 }-hasProperty (Or p1 p2)    w = do { r1 <- hasProperty p1 w; r2 <- hasProperty p2 w; return $ r1 || r2 }-hasProperty (Not p1)      w = do { r1 <- hasProperty p1 w; return $ not r1 }-hasProperty (Const b)     _ = return b+hasProperty p w = runQuery (propertyToQuery p) w  -- | Does the focused window have this property? focusedHasProperty :: Property -> X Bool@@ -79,6 +73,7 @@ propertyToQuery (Resource s) = resource =? s propertyToQuery (ClassName s) = className =? s propertyToQuery (Role s) = stringProperty "WM_WINDOW_ROLE" =? s+propertyToQuery (Machine s) = stringProperty "WM_CLIENT_MACHINE" =? s propertyToQuery (And p1 p2) = propertyToQuery p1 <&&> propertyToQuery p2 propertyToQuery (Or p1 p2) = propertyToQuery p1 <||> propertyToQuery p2 propertyToQuery (Not p) = not `fmap` propertyToQuery p
XMonad/Util/WorkspaceCompare.hs view
@@ -8,15 +8,18 @@ -- Stability   :  unstable -- Portability :  unportable --+-----------------------------------------------------------------------------  module XMonad.Util.WorkspaceCompare ( WorkspaceCompare, WorkspaceSort                                     , getWsIndex                                     , getWsCompare                                     , getWsCompareByTag+                                    , getXineramaPhysicalWsCompare                                     , getXineramaWsCompare                                     , mkWsSort                                     , getSortByIndex                                     , getSortByTag+                                    , getSortByXineramaPhysicalRule                                     , getSortByXineramaRule ) where  import XMonad@@ -57,10 +60,17 @@ --   and screen id. It produces the same ordering as --   'XMonad.Hooks.DynamicLog.pprWindowSetXinerama'. getXineramaWsCompare :: X WorkspaceCompare-getXineramaWsCompare = do+getXineramaWsCompare = getXineramaWsCompare' False++-- | A comparison function like 'getXineramaWsCompare', but uses physical locations for screens.+getXineramaPhysicalWsCompare :: X WorkspaceCompare+getXineramaPhysicalWsCompare = getXineramaWsCompare' True++getXineramaWsCompare' :: Bool -> X WorkspaceCompare+getXineramaWsCompare' phy = do     w <- gets windowset     return $ \ a b -> case (isOnScreen a w, isOnScreen b w) of-        (True, True)   -> comparing (tagToSid (onScreen w)) a b+        (True, True)   -> cmpPosition phy w a b         (False, False) -> compare a b         (True, False)  -> LT         (False, True)  -> GT@@ -68,6 +78,10 @@     onScreen w =  S.current w : S.visible w     isOnScreen a w  = a `elem` map (S.tag . S.workspace) (onScreen w)     tagToSid s x = S.screen $ fromJust $ find ((== x) . S.tag . S.workspace) s+    cmpPosition False w a b = comparing (tagToSid $ onScreen w) a b+    cmpPosition True w a b = comparing (rect.(tagToSid $ onScreen w)) a b+      where rect i = let (Rectangle x y _ _) = screens !! fromIntegral i in (y,x)+            screens = map (screenRect . S.screenDetail) $ sortBy (comparing S.screen) $ S.current w : S.visible w  -- | Create a workspace sorting function from a workspace comparison --   function.@@ -91,4 +105,8 @@ --   sorted by tag. getSortByXineramaRule :: X WorkspaceSort getSortByXineramaRule = mkWsSort getXineramaWsCompare++-- | Like 'getSortByXineramaRule', but uses physical locations for screens.+getSortByXineramaPhysicalRule :: X WorkspaceSort+getSortByXineramaPhysicalRule = mkWsSort getXineramaPhysicalWsCompare 
XMonad/Util/XSelection.hs view
@@ -9,7 +9,7 @@ Portability :  unportable  A module for accessing and manipulating X Window's mouse selection (the buffer used in copy and pasting).-'getSelection' and 'putSelection' are adaptations of Hxsel.hs and Hxput.hs from the XMonad-utils, available:+'getSelection' is an adaptation of Hxsel.hs and Hxput.hs from the XMonad-utils, available:  > $ darcs get <http://gorgias.mine.nu/repos/xmonad-utils> -}@@ -20,61 +20,16 @@                                  promptSelection,                                  safePromptSelection,                                  transformPromptSelection,-                                 transformSafePromptSelection,-                                 putSelection) where+                                 transformSafePromptSelection) where -import Control.Concurrent (forkIO)-import Control.Exception as E (catch)-import Control.Monad(Monad (return, (>>)), Functor(..), liftM, join)-import Data.Char (ord)+import Control.Exception.Extensible as E (catch,SomeException(..))+import Control.Monad (liftM, join) import Data.Maybe (fromMaybe) import XMonad import XMonad.Util.Run (safeSpawn, unsafeSpawn) -#ifdef USE_UTF8 import Codec.Binary.UTF8.String (decode)-#else-import Data.Bits (shiftL, (.&.), (.|.))-import Data.Char (chr)-import Data.Word (Word8)-{- | Decode a UTF8 string packed into a list of Word8 values, directly to-   String; does not deal with CChar, hence you will want the counter-intuitive @map fromIntegral@-   UTF-8 decoding for internal use in getSelection. -   This code is copied from Eric Mertens's "utf-string" library <http://code.haskell.org/utf8-string/>-   (as of version 0.1),\which is BSD-3 licensed like this module.-   It'd be better to just @import Codec.Binary.UTF8.String (decode)@, but then users of this would need to install it; XMonad has enough-   dependencies already. -}-decode :: [Word8] -> String-decode [] = ""-decode (c:cs)-  | c < 0x80  = chr (fromEnum c) : decode cs-  | c < 0xc0  = replacement_character : decode cs-  | c < 0xe0  = multi_byte 1 0x1f 0x80-  | c < 0xf0  = multi_byte 2 0xf  0x800-  | c < 0xf8  = multi_byte 3 0x7  0x10000-  | c < 0xfc  = multi_byte 4 0x3  0x200000-  | c < 0xfe  = multi_byte 5 0x1  0x4000000-  | otherwise = replacement_character : decode cs-  where--    replacement_character :: Char-    replacement_character = '\xfffd'--    multi_byte :: Int -> Word8 -> Int -> [Char]-    multi_byte i mask overlong = aux i cs (fromEnum (c .&. mask))-      where-        aux 0 rs acc-          | overlong <= acc && acc <= 0x10ffff &&-            (acc < 0xd800 || 0xdfff < acc)     &&-            (acc < 0xfffe || 0xffff < acc)      = chr acc : decode rs-          | otherwise = replacement_character : decode rs-        aux n (r:rs) acc-          | r .&. 0xc0 == 0x80 = aux (n-1) rs-                               $ shiftL acc 6 .|. fromEnum (r .&. 0x3f)-        aux _ rs     _ = replacement_character : decode rs-#endif- {- $usage    Add @import XMonad.Util.XSelection@ to the top of Config.hs    Then make use of getSelection or promptSelection as needed; if@@ -82,7 +37,7 @@    the selection string is an URL you just highlighted), then one could add    to the xmonad.hs a line like thus: -   > , ((modMask .|. shiftMask, xK_b), promptSelection "firefox")+   > , ((modm .|. shiftMask, xK_b), promptSelection "firefox")     There are a number of known problems with XSelection: @@ -111,8 +66,8 @@   ty <- E.catch                (E.catch                      (internAtom dpy "UTF8_STRING" False)-                     (\_ -> internAtom dpy "COMPOUND_TEXT" False))-             (\_ -> internAtom dpy "sTring" False)+                     (\(E.SomeException _) -> internAtom dpy "COMPOUND_TEXT" False))+             (\(E.SomeException _) -> internAtom dpy "sTring" False)   clp <- internAtom dpy "BLITZ_SEL_STRING" False   xConvertSelection dpy p ty clp win currentTime   allocaXEvent $ \e -> do@@ -123,43 +78,6 @@                return $ decode . map fromIntegral . fromMaybe [] $ res        else destroyWindow dpy win >> return "" --- | Set the current X Selection to a specified string.-putSelection :: MonadIO m => String -> m ()-putSelection text = io $ do-  dpy <- openDisplay ""-  let dflt = defaultScreen dpy-  rootw  <- rootWindow dpy dflt-  win <- createSimpleWindow dpy rootw 0 0 1 1 0 0 0-  p <- internAtom dpy "PRIMARY" True-  ty <- internAtom dpy "UTF8_STRING" False-  xSetSelectionOwner dpy p win currentTime-  winOwn <- xGetSelectionOwner dpy p-  if winOwn == win-    then do forkIO ((allocaXEvent $ processEvent dpy ty text) >> destroyWindow dpy win) >> return ()-    else do putStrLn "Unable to obtain ownership of the selection" >> destroyWindow dpy win-  return ()-                     where-                       processEvent :: Display -> Atom -> [Char] -> XEventPtr -> IO ()-                       processEvent dpy ty txt e = do-                                                      nextEvent dpy e-                                                      ev <- getEvent e-                                                      if ev_event_type ev == selectionRequest-                                                       then do print ev-                                                               allocaXEvent $ \replyPtr -> do-                                                                 changeProperty8 (ev_event_display ev)-                                                                                 (ev_requestor ev)-                                                                                 (ev_property ev)-                                                                                 ty-                                                                                 propModeReplace-                                                                                 (map (fromIntegral . ord) txt)-                                                                 setSelectionNotify replyPtr (ev_requestor ev) (ev_selection ev)-                                                                                        (ev_target ev) (ev_property ev) (ev_time ev)-                                                                 sendEvent dpy (ev_requestor ev) False noEventMask replyPtr-                                                                 sync dpy False-                                                       else do putStrLn "Unexpected Message Received"-                                                               print ev-                                                      processEvent dpy ty text e- {- | A wrapper around 'getSelection'. Makes it convenient to run a program with the current selection as an argument. This is convenient for handling URLs, in particular. For example, in your Config.hs you could bind a key to          @promptSelection \"firefox\"@;@@ -171,12 +89,12 @@ details on the advantages and disadvantages of using safeSpawn. -} promptSelection, safePromptSelection, unsafePromptSelection :: String -> X () promptSelection = unsafePromptSelection-safePromptSelection app = join $ io $ liftM (safeSpawn app) getSelection+safePromptSelection app = join $ io $ liftM (safeSpawn app . return) getSelection unsafePromptSelection app = join $ io $ liftM unsafeSpawn $ fmap (\x -> app ++ " " ++ x) getSelection  {- | A wrapper around 'promptSelection' and its safe variant. They take two parameters, the first is a function that transforms strings, and the second is the application to run. The transformer essentially transforms the selection in X.-One example is to wrap code, such as a command line action copied out of the browser to be run as '"sudo" ++ cmd' or '"su - -c \"" ++ cmd ++ "\"".+One example is to wrap code, such as a command line action copied out of the browser to be run as @"sudo" ++ cmd@ or @"su - -c \""++ cmd ++"\""@. -} transformPromptSelection, transformSafePromptSelection :: (String -> String) -> String -> X ()-transformPromptSelection f app = join $ io $ liftM (safeSpawn app) (fmap f getSelection)+transformPromptSelection f app = join $ io $ liftM (safeSpawn app . return) (fmap f getSelection) transformSafePromptSelection f app = join $ io $ liftM unsafeSpawn $ fmap (\x -> app ++ " " ++ x) (fmap f getSelection)
xmonad-contrib-bluetilebranch.cabal view
@@ -1,5 +1,5 @@ name:               xmonad-contrib-bluetilebranch-version:            0.8.1.3+version:            0.9.1.4 homepage:           http://xmonad.org/ synopsis:           Third party extensions for xmonad description:        This is a modified version of xmonad-contrib used by Bluetile.@@ -27,7 +27,14 @@  library     if flag(small_base)-        build-depends: base >= 3 && < 4, containers, directory, process, random, old-time, old-locale+        build-depends: base >= 3 && < 5,+                       containers,+                       directory,+                       extensible-exceptions,+                       old-locale,+                       old-time,+                       process,+                       random     else         build-depends: base < 3 @@ -36,14 +43,19 @@         extensions: ForeignFunctionInterface         cpp-options: -DXFT -    build-depends:      mtl, unix, X11>=1.4.3, xmonad-bluetilebranch>=0.8.1.3, utf8-string-    ghc-options:        -Wall+    build-depends:      mtl, unix, X11>=1.5.0.0 && < 1.6, xmonad-bluetilebranch>=0.9.1, xmonad-bluetilebranch<0.10, utf8-string++    if true+        ghc-options:    -fwarn-tabs -Wall+     extensions:         ForeignFunctionInterface-    cpp-options:        -DUSE_UTF8      if flag(testing)-        ghc-options:    -Werror+        ghc-options:    -fwarn-tabs -Werror +    if impl(ghc >= 6.12.1)+        ghc-options:    -fno-warn-unused-do-bind+     if impl (ghc == 6.10.1) && arch (x86_64)         ghc-options:    -O0 @@ -63,20 +75,25 @@                         XMonad.Actions.DeManage                         XMonad.Actions.DwmPromote                         XMonad.Actions.DynamicWorkspaces+                        XMonad.Actions.DynamicWorkspaceGroups+                        XMonad.Actions.DynamicWorkspaceOrder                         XMonad.Actions.FindEmptyWorkspace                         XMonad.Actions.FlexibleManipulate                         XMonad.Actions.FlexibleResize                         XMonad.Actions.FloatKeys+                        XMonad.Actions.FloatSnap                         XMonad.Actions.FocusNth                         XMonad.Actions.GridSelect                         XMonad.Actions.MessageFeedback                         XMonad.Actions.MouseGestures                         XMonad.Actions.MouseResize                         XMonad.Actions.NoBorders+                        XMonad.Actions.OnScreen                         XMonad.Actions.PerWorkspaceKeys                         XMonad.Actions.PhysicalScreens                         XMonad.Actions.Plane                         XMonad.Actions.Promote+                        XMonad.Actions.RandomBackground                         XMonad.Actions.RotSlaves                         XMonad.Actions.Search                         XMonad.Actions.SimpleDate@@ -86,27 +103,28 @@                         XMonad.Actions.SwapWorkspaces                         XMonad.Actions.TagWindows                         XMonad.Actions.TopicSpace-                        XMonad.Actions.UpdatePointer                         XMonad.Actions.UpdateFocus+                        XMonad.Actions.UpdatePointer                         XMonad.Actions.Warp+                        XMonad.Actions.WindowBringer+                        XMonad.Actions.WindowGo                         XMonad.Actions.WindowMenu                         XMonad.Actions.WindowNavigation-                        XMonad.Actions.WindowGo-                        XMonad.Actions.WindowBringer                         XMonad.Actions.WithAll+                        XMonad.Actions.WorkspaceCursors+                        XMonad.Actions.WorkspaceNames                         XMonad.Config.Arossato                         XMonad.Config.Azerty+                        XMonad.Config.Bluetile                         XMonad.Config.Desktop                         XMonad.Config.Droundy                         XMonad.Config.Gnome                         XMonad.Config.Kde                         XMonad.Config.Sjanssen                         XMonad.Config.Xfce-                        XMonad.Hooks.BluetileDock-                        XMonad.Hooks.CustomRestart+                        XMonad.Hooks.CurrentWorkspaceOnTop                         XMonad.Hooks.DynamicHooks                         XMonad.Hooks.DynamicLog-                        XMonad.Hooks.EventHook                         XMonad.Hooks.EwmhDesktops                         XMonad.Hooks.FadeInactive                         XMonad.Hooks.FloatNext@@ -114,27 +132,33 @@                         XMonad.Hooks.ManageDocks                         XMonad.Hooks.ManageHelpers                         XMonad.Hooks.Place+                        XMonad.Hooks.PositionStoreHooks                         XMonad.Hooks.RestoreMinimized+                        XMonad.Hooks.ScreenCorners                         XMonad.Hooks.Script-                        XMonad.Hooks.SetWMName                         XMonad.Hooks.ServerMode+                        XMonad.Hooks.SetWMName                         XMonad.Hooks.UrgencyHook                         XMonad.Hooks.WorkspaceByPos                         XMonad.Hooks.XPropManage                         XMonad.Layout.Accordion+                        XMonad.Layout.AutoMaster                         XMonad.Layout.BorderResize                         XMonad.Layout.BoringWindows+                        XMonad.Layout.ButtonDecoration                         XMonad.Layout.CenteredMaster                         XMonad.Layout.Circle-                        XMonad.Layout.Cross+                        XMonad.Layout.Column                         XMonad.Layout.Combo                         XMonad.Layout.ComboP+                        XMonad.Layout.Cross                         XMonad.Layout.Decoration+                        XMonad.Layout.DecorationAddons                         XMonad.Layout.DecorationMadness-                        XMonad.Layout.DecorationUtils                         XMonad.Layout.Dishes                         XMonad.Layout.DraggingVisualizer                         XMonad.Layout.DragPane+                        XMonad.Layout.Drawer                         XMonad.Layout.DwmStyle                         XMonad.Layout.FixedColumn                         XMonad.Layout.Gaps@@ -149,15 +173,18 @@                         XMonad.Layout.LayoutHints                         XMonad.Layout.LayoutModifier                         XMonad.Layout.LayoutScreens+                        XMonad.Layout.LimitWindows                         XMonad.Layout.MagicFocus                         XMonad.Layout.Magnifier                         XMonad.Layout.Master                         XMonad.Layout.Maximize+                        XMonad.Layout.MessageControl                         XMonad.Layout.Minimize                         XMonad.Layout.Monitor                         XMonad.Layout.Mosaic                         XMonad.Layout.MosaicAlt                         XMonad.Layout.MouseResizableTile+                        XMonad.Layout.MultiColumns                         XMonad.Layout.MultiToggle                         XMonad.Layout.MultiToggle.Instances                         XMonad.Layout.Named@@ -170,34 +197,34 @@                         XMonad.Layout.ResizableTile                         XMonad.Layout.ResizeScreen                         XMonad.Layout.Roledex-                        XMonad.Layout.Simplest+                        XMonad.Layout.ShowWName                         XMonad.Layout.SimpleDecoration                         XMonad.Layout.SimpleFloat+                        XMonad.Layout.Simplest+                        XMonad.Layout.SimplestFloat+                        XMonad.Layout.Spacing                         XMonad.Layout.Spiral                         XMonad.Layout.Square-                        XMonad.Layout.ShowWName                         XMonad.Layout.StackTile                         XMonad.Layout.SubLayouts-                        XMonad.Layout.Tabbed                         XMonad.Layout.TabBarDecoration+                        XMonad.Layout.Tabbed                         XMonad.Layout.ThreeColumns-                        XMonad.Layout.ThreeColumnsMiddle                         XMonad.Layout.ToggleLayouts                         XMonad.Layout.TwoPane                         XMonad.Layout.WindowArranger                         XMonad.Layout.WindowNavigation                         XMonad.Layout.WindowSwitcherDecoration                         XMonad.Layout.WorkspaceDir-                        XMonad.Layout.SimplestFloat-                        XMonad.Prompt.Directory                         XMonad.Prompt                         XMonad.Prompt.AppendFile                         XMonad.Prompt.AppLauncher-                        XMonad.Prompt.Input+                        XMonad.Prompt.Directory+                        XMonad.Prompt.DirExec                         XMonad.Prompt.Email+                        XMonad.Prompt.Input                         XMonad.Prompt.Layout                         XMonad.Prompt.Man-                        XMonad.Prompt.DirExec                         XMonad.Prompt.RunOrRaise                         XMonad.Prompt.Shell                         XMonad.Prompt.Ssh@@ -205,21 +232,29 @@                         XMonad.Prompt.Window                         XMonad.Prompt.Workspace                         XMonad.Prompt.XMonad+                        XMonad.Util.Cursor                         XMonad.Util.CustomKeys                         XMonad.Util.Dmenu                         XMonad.Util.Dzen+                        XMonad.Util.ExtensibleState                         XMonad.Util.EZConfig                         XMonad.Util.Font                         XMonad.Util.Invisible                         XMonad.Util.Loggers+                        XMonad.Util.NamedActions                         XMonad.Util.NamedScratchpad                         XMonad.Util.NamedWindows+                        XMonad.Util.Paste+                        XMonad.Util.PositionStore+                        XMonad.Util.Replace                         XMonad.Util.Run                         XMonad.Util.Scratchpad+                        XMonad.Util.SpawnOnce+                        XMonad.Util.StringProp                         XMonad.Util.Themes                         XMonad.Util.Timer+                        XMonad.Util.Types                         XMonad.Util.WindowProperties                         XMonad.Util.WorkspaceCompare-                        XMonad.Util.Paste                         XMonad.Util.XSelection                         XMonad.Util.XUtils