summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--XMonad/Core.hs89
-rw-r--r--XMonad/Main.hs5
2 files changed, 65 insertions, 29 deletions
diff --git a/XMonad/Core.hs b/XMonad/Core.hs
index 32fc234..c32678e 100644
--- a/XMonad/Core.hs
+++ b/XMonad/Core.hs
@@ -191,61 +191,95 @@ atom_WM_DELETE_WINDOW = getAtom "WM_DELETE_WINDOW"
atom_WM_STATE = getAtom "WM_STATE"
------------------------------------------------------------------------
--- | LayoutClass handling. See particular instances in Operations.hs
+-- LayoutClass handling. See particular instances in Operations.hs
--- | An existential type that can hold any object that is in Read and LayoutClass.
+-- | An existential type that can hold any object that is in 'Read'
+-- and 'LayoutClass'.
data Layout a = forall l. (LayoutClass l a, Read (l a)) => Layout (l a)
-- | Using the 'Layout' as a witness, parse existentially wrapped windows
--- from a 'String'
+-- from a 'String'.
readsLayout :: Layout a -> String -> [(Layout a, String)]
readsLayout (Layout l) s = [(Layout (asTypeOf x l), rs) | (x, rs) <- reads s]
--- | Every layout must be an instance of LayoutClass, which defines
+-- | Every layout must be an instance of 'LayoutClass', which defines
-- the basic layout operations along with a sensible default for each.
--
+-- Minimal complete definition:
+--
+-- * 'runLayout' || (('doLayout' || 'pureLayout') && 'emptyLayout'), and
+--
+-- * 'handleMessage' || 'pureMessage'
+--
+-- You should also strongly consider implementing 'description',
+-- although it is not required.
+--
+-- Note that any code which /uses/ 'LayoutClass' methods should only
+-- ever call 'runLayout', 'handleMessage', and 'description'! In
+-- other words, the only calls to 'doLayout', 'pureMessage', and other
+-- such methods should be from the default implementations of
+-- 'runLayout', 'handleMessage', and so on. This ensures that the
+-- proper methods will be used, regardless of the particular methods
+-- that any 'LayoutClass' instance chooses to define.
class Show (layout a) => LayoutClass layout a where
- -- | This calls doLayout if there are any windows to be laid out, and
- -- emptyLayout otherwise.
+ -- | By default, 'runLayout' calls 'doLayout' if there are any
+ -- windows to be laid out, and 'emptyLayout' otherwise. Most
+ -- instances of 'LayoutClass' probably do not need to implement
+ -- 'runLayout'; it is only useful for layouts which wish to make
+ -- use of more of the 'Workspace' information (for example,
+ -- "XMonad.Layout.PerWorkspace").
runLayout :: Workspace WorkspaceId (layout a) a -> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
runLayout (Workspace _ l ms) r = maybe (emptyLayout l r) (doLayout l r) ms
- -- | Given a Rectangle in which to place the windows, and a Stack
+ -- | Given a 'Rectangle' in which to place the windows, and a 'Stack'
-- of windows, return a list of windows and their corresponding
-- Rectangles. If an element is not given a Rectangle by
-- 'doLayout', then it is not shown on screen. The order of
-- windows in this list should be the desired stacking order.
--
- -- Also return a modified layout, if this layout needs to be modified
- -- (e.g. if we keep track of the windows we have displayed).
+ -- Also possibly return a modified layout (by returning @Just
+ -- newLayout@), if this layout needs to be modified (e.g. if it
+ -- keeps track of some sort of state). Return @Nothing@ if the
+ -- layout does not need to be modified.
+ --
+ -- Layouts which do not need access to the 'X' monad ('IO', window
+ -- manager state, or configuration) and do not keep track of their
+ -- own state should implement 'pureLayout' instead of 'doLayout'.
doLayout :: layout a -> Rectangle -> Stack a -> X ([(a, Rectangle)], Maybe (layout a))
doLayout l r s = return (pureLayout l r s, Nothing)
- -- | This is a pure version of doLayout, for cases where we don't need
- -- access to the X monad to determine how to layout the windows, and
- -- we don't need to modify our layout itself.
+ -- | This is a pure version of 'doLayout', for cases where we
+ -- don't need access to the 'X' monad to determine how to lay out
+ -- the windows, and we don't need to modify the layout itself.
pureLayout :: layout a -> Rectangle -> Stack a -> [(a, Rectangle)]
pureLayout _ r s = [(focus s, r)]
- -- | 'emptyLayout' is called when there is no window.
+ -- | 'emptyLayout' is called when there are no windows.
emptyLayout :: layout a -> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
emptyLayout _ _ = return ([], Nothing)
- -- | 'handleMessage' performs message handling for that layout. If
- -- 'handleMessage' returns Nothing, then the layout did not respond to
- -- that message and the screen is not refreshed. Otherwise, 'handleMessage'
- -- returns an updated 'Layout' and the screen is refreshed.
+ -- | 'handleMessage' performs message handling. If
+ -- 'handleMessage' returns @Nothing@, then the layout did not
+ -- respond to the message and the screen is not refreshed.
+ -- Otherwise, 'handleMessage' returns an updated layout and the
+ -- screen is refreshed.
+ --
+ -- Layouts which do not need access to the 'X' monad to decide how
+ -- to handle messages should implement 'pureMessage' instead of
+ -- 'handleMessage'.
handleMessage :: layout a -> SomeMessage -> X (Maybe (layout a))
handleMessage l = return . pureMessage l
- -- | Respond to a message by (possibly) changing our layout, but taking
- -- no other action. If the layout changes, the screen will be refreshed.
+ -- | Respond to a message by (possibly) changing our layout, but
+ -- taking no other action. If the layout changes, the screen will
+ -- be refreshed.
pureMessage :: layout a -> SomeMessage -> Maybe (layout a)
pureMessage _ _ = Nothing
- -- | This should be a human-readable string that is used when selecting
- -- layouts by name.
+ -- | This should be a human-readable string that is used when
+ -- selecting layouts by name. The default implementation is
+ -- 'show', which is in some cases a poor default.
description :: layout a -> String
description = show
@@ -258,29 +292,30 @@ instance LayoutClass Layout Window where
instance Show (Layout a) where show (Layout l) = show l
--- | Based on ideas in /An Extensible Dynamically-Typed Hierarchy of Exceptions/,
--- Simon Marlow, 2006. Use extensible messages to the handleMessage handler.
+-- | Based on ideas in /An Extensible Dynamically-Typed Hierarchy of
+-- Exceptions/, Simon Marlow, 2006. Use extensible messages to the
+-- 'handleMessage' handler.
--
-- User-extensible messages must be a member of this class.
--
class Typeable a => Message a
-- |
--- A wrapped value of some type in the Message class.
+-- A wrapped value of some type in the 'Message' class.
--
data SomeMessage = forall a. Message a => SomeMessage a
-- |
--- And now, unwrap a given, unknown Message type, performing a (dynamic)
+-- And now, unwrap a given, unknown 'Message' type, performing a (dynamic)
-- type check on the result.
--
fromMessage :: Message m => SomeMessage -> Maybe m
fromMessage (SomeMessage m) = cast m
--- | X Events are valid Messages
+-- X Events are valid Messages.
instance Message Event
--- | LayoutMessages are core messages that all layouts (especially stateful
+-- | 'LayoutMessages' are core messages that all layouts (especially stateful
-- layouts) should consider handling.
data LayoutMessages = Hide -- ^ sent when a layout becomes non-visible
| ReleaseResources -- ^ sent when xmonad is exiting or restarting
diff --git a/XMonad/Main.hs b/XMonad/Main.hs
index 405caec..667af81 100644
--- a/XMonad/Main.hs
+++ b/XMonad/Main.hs
@@ -109,7 +109,7 @@ xmonad initxmc = do
-- bootstrap the windowset, Operations.windows will identify all
-- the windows in winset as new and set initial properties for
-- those windows. Remove all windows that are no longer top-level
- -- children of the root, they may have disappeared since
+ -- children of the root, they may have disappeared since
-- restarting.
windows . const . foldr W.delete winset $ W.allWindows winset \\ ws
@@ -202,7 +202,8 @@ handle e@(ButtonEvent {ev_window = w,ev_event_type = t,ev_button = b })
else focus w
broadcastMessage e -- Always send button events.
--- entered a normal window, makes this focused.
+-- entered a normal window: focus it if focusFollowsMouse is set to
+-- True in the user's config.
handle e@(CrossingEvent {ev_window = w, ev_event_type = t})
| t == enterNotify && ev_mode e == notifyNormal
&& ev_detail e /= notifyInferior