From bee3e6b8722d585ac562773498c295a51da6faff Mon Sep 17 00:00:00 2001 From: Brent Yorgey Date: Tue, 27 Nov 2007 20:03:45 +0100 Subject: Doc/Developing: various edits darcs-hash:20071127190345-bd4d7-e19ddf8332cc37eb2fdc4f00ae07f4d51874c1ef.gz --- XMonad/Doc/Developing.hs | 202 +++++++++++++++++++++++------------------------ 1 file changed, 97 insertions(+), 105 deletions(-) (limited to 'XMonad/Doc') diff --git a/XMonad/Doc/Developing.hs b/XMonad/Doc/Developing.hs index 180fc8a..ced3175 100644 --- a/XMonad/Doc/Developing.hs +++ b/XMonad/Doc/Developing.hs @@ -8,29 +8,29 @@ -- Stability : unstable -- Portability : portable -- --- This module documents the xmonad internals. +-- This module documents the xmonad internals. It is intended for +-- advanced users who are curious about the xmonad source code and +-- want an brief overview. This document may also be helpful for the +-- beginner\/intermediate Haskell programmer who is motivated to write +-- an xmonad extension as a way to deepen her understanding of this +-- powerful functional language; however, there is not space here to +-- go into much detail. A more comprehensive document introducing +-- beginner\/intermediate Haskell programmers to the xmonad source is +-- planned for the xmonad users' wiki +-- (). -- --- It is intended for the advanced users who are curious about the --- xmonad source code and want an brief overview of it. --- --- While some knowledge of Haskell is required, still this document is --- also intended for the beginner\/intermediate Haskell programmer who --- could find writing an xmonad extension a motivation for deepening --- her understanding of this powerful functional language. --- --- It may be useful also for those who would like to extend xmonad. If --- you think your extension may be useful for other users too, you may --- consider about releasing it. --- --- Coding guidelines and licencing policies must be followed if you --- want your code to be included in the official repositories. +-- If you write an extension module and think it may be useful for +-- others, consider releasing it. Coding guidelines and licensing +-- policies are covered at the end of this document, and must be +-- followed if you want your code to be included in the official +-- repositories. -- ----------------------------------------------------------------------------- module XMonad.Doc.Developing ( - -- -- * Writing new extensions - -- -- $writing + -- * Writing new extensions + -- $writing -- * Libraries for writing window managers -- $xmonad-libs @@ -68,30 +68,23 @@ module XMonad.Doc.Developing {- $xmonad-libs -Starting from version 0.5, xmonad and xmonad-contrib are packaged and -distributed as libraries. This way of distributing xmonad has many -advantages, since it allows the packaging by GNU\/Linux distributions -while letting the user have the possibility of greatly customizing the -window manager to fit her needs. +Starting with version 0.5, xmonad and xmonad-contrib are packaged and +distributed as libraries, instead of components which must be compiled +by the user into a binary (as they were prior to version 0.5). This +way of distributing xmonad has many advantages, since it allows +packaging by GNU\/Linux distributions while still allowing the user to +customize the window manager to fit her needs. Basically, xmonad and the xmonad-contrib libraries let users write -their own window manager in a matter of a few lines of code. +their own window manager in just a few lines of code. While +@~\/.xmonad\/xmonad.hs@ at first seems to be simply a configuration +file, it is actually a complete Haskell program which uses the xmonad +and xmonad-contrib libraries to create a custom window manager. -In fact, what seems to be just a configuration file, -@~\/.xmonad\/xmonad.hs@ (whose presence is not necessary for running -the default configuration), is indeed a full Haskell program, with its -@main@ entry point. - -This makes it possible, not only to edit the xmonad default -configuration, as we have seen the "XMonad.Doc.Extending" document, -but also to use the Haskell programming language to extend the tasks -performed by the window manager you are writing every time you write -your own @~\/.xmonad\/xmonad.hs@. - -This is obviously out of the scope of this document, which instead -will be focused on the xmonad internals, by describing, very briefly, -the programming techniques that have been employed in order to make -writing new extensions very simple. +This makes it possible not only to edit the default xmonad +configuration, as we have seen in the "XMonad.Doc.Extending" document, +but to use the Haskell programming language to extend the window +manager you are writing in any way you see fit. -} @@ -106,21 +99,20 @@ Xsession starting script. This binary, whose code can be read in @Main.hs@ of the xmonad source tree, will use 'XMonad.Core.recompile' to run @ghc@ in order to build a binary from @~\/.xmonad\/xmonad.hs@. If this compilation process fails, for any reason, a default @main@ -entry point will be used, which calls 'XMonad.Main.xmonad', from the -"XMonad.Main" module. - -So, the real @main@ entry point, the one that even users' application -in @~\/.xmonad\/xmonad.hs@ must call, is 'XMonad.Main.xmonad' +entry point will be used, which calls the 'XMonad.Main.xmonad' +function with a default configuration. -'XMonad.Main.xmonad' takes the configuration as its only argument, -configuration whose type ('XMonad.Core.XConfig') is defined in -"XMonad.Core". +Thus, the real @main@ entry point, the one that even the users' custom +window manager application in @~\/.xmonad\/xmonad.hs@ must call, is +the 'XMonad.Main.xmonad' function. This function takes a configuration +as its only argument, whose type ('XMonad.Core.XConfig') +is defined in "XMonad.Core". 'XMonad.Main.xmonad' takes care of opening the connection with the X server, initializing the state (or deserializing it when restarted) and the configuration, and calling the event handler -('XMonad.Main.handle') that will 'Prelude.forever' loop waiting for -events and acting accordingly. +('XMonad.Main.handle') that goes into an infinite loop (using +'Prelude.forever') waiting for events and acting accordingly. -} @@ -130,25 +122,26 @@ The event loop which calls 'XMonad.Main.handle' to react to events is run within the 'XMonad.Core.X' monad, which is a 'Control.Monad.State.StateT' transformer over 'IO', encapsulated within a 'Control.Monad.Reader.ReaderT' transformer. The -'Control.Monad.State.StateT' transformer encapsulates the (writable) -state of the window manager ('XMonad.Core.XState'), whereas the -'Control.Monad.Reader.ReaderT' transformer encapsulates the -(read-only) configuration ('XMonad.Core.XConf'). +'Control.Monad.State.StateT' transformer encapsulates the +(read\/writable) state of the window manager (of type +'XMonad.Core.XState'), whereas the 'Control.Monad.Reader.ReaderT' +transformer encapsulates the (read-only) configuration (of type +'XMonad.Core.XConf'). -Thanks to the @newtype deriving@ clause the instance of the +Thanks to GHC's newtype deriving feature, the instance of the 'Control.Monad.State.MonadState' class parametrized over 'XMonad.Core.XState' and the instance of the 'Control.Monad.Reader.MonadReader' class parametrized over -'XMonad.Core.XConf' are automatically derived from us by ghc. This way -we can use 'Control.Monad.State.get', 'Control.Monad.State.gets' and -'Control.Monad.State.modify' for the 'XMonad.Core.XState', and -'Control.Monad.Reader.ask' and 'Control.Monad.Reader.asks' for -reading the 'XMonad.Core.XConf'. +'XMonad.Core.XConf' are automatically derived for the 'XMonad.Core.X' +monad. This way we can use 'Control.Monad.State.get', +'Control.Monad.State.gets' and 'Control.Monad.State.modify' for the +'XMonad.Core.XState', and 'Control.Monad.Reader.ask' and +'Control.Monad.Reader.asks' for reading the 'XMonad.Core.XConf'. 'XMonad.Core.XState' is where all the sensitive information about -windows managing is stored. And the main record of the +window management is stored. The most important field of the 'XMonad.Core.XState' is the 'XMonad.Core.windowset', whose type -('XMonad.Core.WindowSet') is a type synonymous for a +('XMonad.Core.WindowSet') is a synonym for a 'XMonad.StackSet.StackSet' parametrized over a 'XMonad.Core.WorkspaceID' (a 'String'), a layout type wrapped inside the 'XMonad.Layout.Layout' existential data type, the @@ -156,81 +149,80 @@ the 'XMonad.Layout.Layout' existential data type, the 'XMonad.Core.ScreenDetail's. What a 'XMonad.StackSet.StackSet' is and how it can be manipulated -with pure functions is perfectly described in the Haddock -documentation of the "XMonad.StackSet" module, and will not be repeated -here. +with pure functions is described in the Haddock documentation of the +"XMonad.StackSet" module. -The 'XMonad.StackSet.StackSet' ('XMonad.Core.WindowSet') has 4 -records: +The 'XMonad.StackSet.StackSet' ('XMonad.Core.WindowSet') has four +fields: * 'XMonad.StackSet.current', for the current, focused workspace. This - is a 'XMonad.StackSet.Screen', composed by a - 'XMonad.StackSet.Workspace', and the screen information (for + is a 'XMonad.StackSet.Screen', which is composed of a + 'XMonad.StackSet.Workspace' together with the screen information (for Xinerama support). * 'XMonad.StackSet.visible', a list of 'XMonad.StackSet.Screen's for - the other visible (with Xinerama) workspaces. + the other visible (with Xinerama) workspaces. For non-Xinerama + setups, this list is always empty. -* 'XMonad.StackSet.hidden', the list of 'XMonad.StackSet.Screen's for - non visible workspaces. +* 'XMonad.StackSet.hidden', the list of non-visible + 'XMonad.StackSet.Workspace's. + +* 'XMonad.StackSet.floating', a map from floating + 'Graphics.X11.Types.Window's to 'XMonad.StackSet.RationalRect's + specifying their geometry. The 'XMonad.StackSet.Workspace' type is made of a 'XMonad.StackSet.tag', a 'XMonad.StackSet.layout' and -'XMonad.StackSet.stack', possibly empy, of windows. - -"XMonad.StackSet", to be imported qualified, provides many pure -functions to manipulate the 'XMonad.StackSet.StackSet'. These -functions are usually used as the argument of -'XMonad.Operations.windows', which indeed takes a pure function to -manipulate the 'XMonad.Core.WindowSet' and does all the needed -operations to refresh the screen and save the modified +a (possibly empty) 'XMonad.StackSet.stack' of windows. + +"XMonad.StackSet" (which should usually be imported qualified, to +avoid name clashes with Prelude functions such as 'Prelude.delete' and +'Prelude.filter') provides many pure functions to manipulate the +'XMonad.StackSet.StackSet'. These functions are most commonlyq used as +an argument to 'XMonad.Operations.windows', which takes a pure +function to manipulate the 'XMonad.Core.WindowSet' and does all the +needed operations to refresh the screen and save the modified 'XMonad.Core.XState'. -During 'XMonad.Operations.windows' calls the 'XMonad.StackSet.layout' -record of the 'XMonad.StackSet.current' and 'XMonad.StackSet.visible' -'XMonad.StackSet.Workspace's is used to arrange the -'XMonad.StackSet.stack' of windows of each workspace. +During each 'XMonad.Operations.windows' call, the +'XMonad.StackSet.layout' field of the 'XMonad.StackSet.current' and +'XMonad.StackSet.visible' 'XMonad.StackSet.Workspace's are used to +physically arrange the 'XMonad.StackSet.stack' of windows on each +workspace. The possibility of manipulating the 'XMonad.StackSet.StackSet' ('XMonad.Core.WindowSet') with pure functions makes it possible to test all the properties of those functions with QuickCheck, providing -greater reliability of the core code. - -Every change to the "XMonad.StackSet" module must be accompanied with -the set of property to be tested with QuickCheck before being applied. +greater reliability of the core code. Every change to the +"XMonad.StackSet" module must be accompanied by appropriate QuickCheck +properties before being applied. -} {- $events -Events and event handling are the main data and activity xmonad is -involved with. And X Events are one of the most important. - -Still there may be events that are generated by layouts, or by the -user, for sending commands to layouts, for instance. +Event handling is the core activity of xmonad. Events generated by +the X server are most important, but there may also be events +generated by layouts or the user. "XMonad.Core" defines a class that generalizes the concept of events, 'XMonad.Core.Message', constrained to types with a 'Data.Typeable.Typeable' instance definition (which can be -automatically derived by ghc). - -'XMonad.Core.Message's are wrapped within an existential type -'XMonad.Core.SomeMessage'. - -The 'Data.Typeable.Typeable' constraint allows us to define a +automatically derived by ghc). 'XMonad.Core.Message's are wrapped +within an existential type 'XMonad.Core.SomeMessage'. The +'Data.Typeable.Typeable' constraint allows for the definition of a 'XMonad.Core.fromMessage' function that can unwrap the message with -'Data.Typeable.cast'. - -X Events are instances of this class. +'Data.Typeable.cast'. X Events are instances of this class, along +with any messages used by xmonad itself or by extension modules. -By using the 'Data.Typeable.Typeable' class for any kind of -'XMonad.Core.Message's and events we can define polymorphic functions -and use them for processing messages or unhandled events. +Using the 'Data.Typeable.Typeable' class for any kind of +'XMonad.Core.Message's and events allows us to define polymorphic functions +for processing messages or unhandled events. This is precisely what happens with X events: xmonad passes them to 'XMonad.Main.handle'. If the main event handling function doesn't have anything to do with the event, the event is sent to all visible -layouts by 'XMonad.Operations.bradcastMessage'. +layouts by 'XMonad.Operations.broadcastMessage'. This messaging system allows the user to create new message types, simply declare an instance of the 'Data.Typeable.Typeable' and use @@ -261,7 +253,7 @@ xmonad contributed extensions. * Code should be compilable with -Wall -Werror. There should be no warnings. * Partial functions should be avoided: the window manager should not - crash, so do not call 'error' or 'undefined' + crash, so do not call 'error' or 'undefined'. * Tabs are /illegal/. Use 4 spaces for indenting. -- cgit v1.2.3