summaryrefslogtreecommitdiffhomepage
path: root/doc/window-managers.org
diff options
context:
space:
mode:
Diffstat (limited to 'doc/window-managers.org')
-rw-r--r--doc/window-managers.org482
1 files changed, 241 insertions, 241 deletions
diff --git a/doc/window-managers.org b/doc/window-managers.org
index ea3aeea..db8207c 100644
--- a/doc/window-managers.org
+++ b/doc/window-managers.org
@@ -3,284 +3,284 @@
Listed below are ways to interface xmobar with your window manager of
choice.
-*** Property-based Logging
-***** =XMonadLog=
-
- - Aliases to XMonadLog
-
- - Displays information from xmonad's =_XMONAD_LOG=. You can use
- this by using functions from the [[https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Hooks-DynamicLog.html][XMonad.Hooks.DynamicLog]]
- module. By using the =xmonadPropLog= function in your logHook,
- you can write the the above property. The following shows a
- minimal xmonad configuration that spawns xmobar and then
- writes to the =_XMONAD_LOG= property.
+* Property-based Logging
+** =XMonadLog=
+
+ - Aliases to XMonadLog
+
+ - Displays information from xmonad's =_XMONAD_LOG=. You can use
+ this by using functions from the [[https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Hooks-DynamicLog.html][XMonad.Hooks.DynamicLog]]
+ module. By using the =xmonadPropLog= function in your logHook,
+ you can write the the above property. The following shows a
+ minimal xmonad configuration that spawns xmobar and then
+ writes to the =_XMONAD_LOG= property.
- #+begin_src haskell
- main = do
- spawn "xmobar"
- xmonad $ def
- { logHook = dynamicLogString defaultPP >>= xmonadPropLog
- }
- #+end_src
+ #+begin_src haskell
+ main = do
+ spawn "xmobar"
+ xmonad $ def
+ { logHook = dynamicLogString defaultPP >>= xmonadPropLog
+ }
+ #+end_src
- This plugin can be used as a sometimes more convenient
- alternative to =StdinReader=. For instance, it allows you to
- (re)start xmobar outside xmonad.
+ This plugin can be used as a sometimes more convenient
+ alternative to =StdinReader=. For instance, it allows you to
+ (re)start xmobar outside xmonad.
-***** =UnsafeXMonadLog=
+** =UnsafeXMonadLog=
- - Aliases to UnsafeXMonadLog
- - Displays any text received by xmobar on the =_XMONAD_LOG= atom.
- - Will not do anything to the text received. This means you can pass
- xmobar dynamic actions. Be careful to escape (using =<raw=…>=) or
- remove tags from dynamic text that you pipe through to xmobar in this
- way.
+ - Aliases to UnsafeXMonadLog
+ - Displays any text received by xmobar on the =_XMONAD_LOG= atom.
+ - Will not do anything to the text received. This means you can pass
+ xmobar dynamic actions. Be careful to escape (using =<raw=…>=) or
+ remove tags from dynamic text that you pipe through to xmobar in this
+ way.
- - Sample usage: Send the list of your workspaces, enclosed by actions
- tags, to xmobar. This enables you to switch to a workspace when you
- click on it in xmobar!
+ - Sample usage: Send the list of your workspaces, enclosed by actions
+ tags, to xmobar. This enables you to switch to a workspace when you
+ click on it in xmobar!
- #+begin_src shell
- <action=`xdotool key alt+1`>ws1</action> <action=`xdotool key alt+1`>ws2</action>
- #+end_src
+ #+begin_src shell
+ <action=`xdotool key alt+1`>ws1</action> <action=`xdotool key alt+1`>ws2</action>
+ #+end_src
- - If you use xmonad, It is advised that you still use =xmobarStrip= for
- the =ppTitle= in your logHook:
+ - If you use xmonad, It is advised that you still use =xmobarStrip= for
+ the =ppTitle= in your logHook:
- #+begin_src haskell
- myPP = defaultPP { ppTitle = xmobarStrip }
- main = xmonad $ def
- { logHook = dynamicLogString myPP >>= xmonadPropLog
- }
- #+end_src
+ #+begin_src haskell
+ myPP = defaultPP { ppTitle = xmobarStrip }
+ main = xmonad $ def
+ { logHook = dynamicLogString myPP >>= xmonadPropLog
+ }
+ #+end_src
-***** =XPropertyLog PropName=
+** =XPropertyLog PropName=
- - Aliases to =PropName=
- - Reads the X property named by =PropName= (a string) and displays its
- value. The [[../examples/xmonadpropwrite.hs][examples/xmonadpropwrite.hs script]] in xmobar's distribution
- can be used to set the given property from the output of any other
- program or script.
+ - Aliases to =PropName=
+ - Reads the X property named by =PropName= (a string) and displays its
+ value. The [[../examples/xmonadpropwrite.hs][examples/xmonadpropwrite.hs script]] in xmobar's distribution
+ can be used to set the given property from the output of any other
+ program or script.
-***** =UnsafeXPropertyLog PropName=
+** =UnsafeXPropertyLog PropName=
- - Aliases to =PropName=
- - Same as =XPropertyLog= but the input is not filtered to avoid
- injection of actions (cf. =UnsafeXMonadLog=). The program writing the
- value of the read property is responsible of performing any needed
- cleanups.
+ - Aliases to =PropName=
+ - Same as =XPropertyLog= but the input is not filtered to avoid
+ injection of actions (cf. =UnsafeXMonadLog=). The program writing the
+ value of the read property is responsible of performing any needed
+ cleanups.
-***** =NamedXPropertyLog PropName Alias=
+** =NamedXPropertyLog PropName Alias=
- - Aliases to =Alias=
- - Same as =XPropertyLog= but a custom alias can be specified.
+ - Aliases to =Alias=
+ - Same as =XPropertyLog= but a custom alias can be specified.
-***** =UnsafeNamedXPropertyLog PropName Alias=
+** =UnsafeNamedXPropertyLog PropName Alias=
- - Aliases to =Alias=
- - Same as =UnsafeXPropertyLog=, but a custom alias can be specified.
+ - Aliases to =Alias=
+ - Same as =UnsafeXPropertyLog=, but a custom alias can be specified.
-*** Logging via Stdin
-***** =StdinReader=
+* Logging via Stdin
+** =StdinReader=
- - Aliases to StdinReader
- - Displays any text received by xmobar on its standard input.
- - Strips actions from the text received. This means you can't pass
- dynamic actions via stdin. This is safer than =UnsafeStdinReader=
- because there is no need to escape the content before passing it to
- xmobar's standard input.
+ - Aliases to StdinReader
+ - Displays any text received by xmobar on its standard input.
+ - Strips actions from the text received. This means you can't pass
+ dynamic actions via stdin. This is safer than =UnsafeStdinReader=
+ because there is no need to escape the content before passing it to
+ xmobar's standard input.
-***** =UnsafeStdinReader=
+** =UnsafeStdinReader=
- - Aliases to UnsafeStdinReader
- - Displays any text received by xmobar on its standard input.
- - Similar to [[=UnsafeXMonadLog=][UnsafeXMonadLog]], in the sense that it does not strip any
- actions from the received text, only using =stdin= and not a property
- atom of the root window. Please be equally carefully when using this
- as when using =UnsafeXMonadLog=!
+ - Aliases to UnsafeStdinReader
+ - Displays any text received by xmobar on its standard input.
+ - Similar to [[=UnsafeXMonadLog=][UnsafeXMonadLog]], in the sense that it does not strip any
+ actions from the received text, only using =stdin= and not a property
+ atom of the root window. Please be equally carefully when using this
+ as when using =UnsafeXMonadLog=!
-*** Pipe-based Logging
-***** =PipeReader "default text:/path/to/pipe" Alias=
+* Pipe-based Logging
+** =PipeReader "default text:/path/to/pipe" Alias=
- - Reads its displayed output from the given pipe.
- - Prefix an optional default text separated by a colon
- - Expands environment variables in the first argument of syntax =${VAR}=
- or =$VAR=
+ - Reads its displayed output from the given pipe.
+ - Prefix an optional default text separated by a colon
+ - Expands environment variables in the first argument of syntax =${VAR}=
+ or =$VAR=
-***** =MarqueePipeReader "default text:/path/to/pipe" (length, rate, sep) Alias=
+** =MarqueePipeReader "default text:/path/to/pipe" (length, rate, sep) Alias=
- - Generally equivalent to PipeReader
+ - Generally equivalent to PipeReader
- - Text is displayed as marquee with the specified length, rate in 10th
- seconds and separator when it wraps around
+ - Text is displayed as marquee with the specified length, rate in 10th
+ seconds and separator when it wraps around
- #+begin_src haskell
- Run MarqueePipeReader "/tmp/testpipe" (10, 7, "+") "mpipe"
- #+end_src
+ #+begin_src haskell
+ Run MarqueePipeReader "/tmp/testpipe" (10, 7, "+") "mpipe"
+ #+end_src
- - Expands environment variables in the first argument
+ - Expands environment variables in the first argument
-***** =BufferedPipeReader Alias [(Timeout, Bool, "/path/to/pipe1"), ..]=
+** =BufferedPipeReader Alias [(Timeout, Bool, "/path/to/pipe1"), ..]=
- - Display data from multiple pipes.
+ - Display data from multiple pipes.
- - Timeout (in tenth of seconds) is the value after which the
- previous content is restored i.e. if there was already
- something from a previous pipe it will be put on display
- again, overwriting the current status.
+ - Timeout (in tenth of seconds) is the value after which the
+ previous content is restored i.e. if there was already
+ something from a previous pipe it will be put on display
+ again, overwriting the current status.
- - A pipe with Timeout of 0 will be displayed permanently, just
- like =PipeReader=
+ - A pipe with Timeout of 0 will be displayed permanently, just
+ like =PipeReader=
- - The boolean option indicates whether new data for this pipe
- should make xmobar appear (unhide, reveal). In this case, the
- Timeout additionally specifies when the window should be
- hidden again. The output is restored in any case.
+ - The boolean option indicates whether new data for this pipe
+ should make xmobar appear (unhide, reveal). In this case, the
+ Timeout additionally specifies when the window should be
+ hidden again. The output is restored in any case.
- - Use it for OSD-like status bars e.g. for setting the volume or
- brightness:
+ - Use it for OSD-like status bars e.g. for setting the volume or
+ brightness:
- #+begin_src haskell
- Run BufferedPipeReader "bpr"
- [ ( 0, False, "/tmp/xmobar_window" )
- , ( 15, True, "/tmp/xmobar_status" )
- ]
- #+end_src
+ #+begin_src haskell
+ Run BufferedPipeReader "bpr"
+ [ ( 0, False, "/tmp/xmobar_window" )
+ , ( 15, True, "/tmp/xmobar_status" )
+ ]
+ #+end_src
- Have your window manager send window titles to
- =/tmp/xmobar_window=. They will always be shown and not reveal
- your xmobar. Sending some status information to
- =/tmp/xmobar_status= will reveal xmonad for 1.5 seconds and
- temporarily overwrite the window titles.
+ Have your window manager send window titles to
+ =/tmp/xmobar_window=. They will always be shown and not reveal
+ your xmobar. Sending some status information to
+ =/tmp/xmobar_status= will reveal xmonad for 1.5 seconds and
+ temporarily overwrite the window titles.
- - Take a look at [[../examples/status.sh][examples/status.sh]]
+ - Take a look at [[../examples/status.sh][examples/status.sh]]
- - Expands environment variables for the pipe path
+ - Expands environment variables for the pipe path
-*** Handle-based Logging
-***** =HandleReader Handle Alias=
+* Handle-based Logging
+** =HandleReader Handle Alias=
- - Display data from a Haskell =Handle=
+ - Display data from a Haskell =Handle=
- - This plugin is only useful if you are running xmobar from another
- Haskell program like XMonad.
-
- - You can use =System.Process.createPipe= to create a pair of =read= &
- =write= Handles. Pass the =read= Handle to HandleReader and write your
- output to the =write= Handle:
-
- #+begin_src haskell
- (readHandle, writeHandle) <- createPipe
- xmobarProcess <- forkProcess $ xmobar myConfig
- { commands =
- Run (HandleReader readHandle "handle") : commands myConfig
- }
- hPutStr writeHandle "Hello World"
- #+end_src
-
-*** Software Transactional Memory
-
- When invoking xmobar from other Haskell code it can be easier and
- more performant to use shared memory. The following plugins
- leverage =Control.Concurrent.STM= to realize these gains for xmobar.
-
-***** =QueueReader (TQueue a) (a -> String) String=
-
- - Display data from a Haskell =TQueue a=.
-
- - This plugin is only useful if you are running xmobar from another
- haskell program like xmonad.
-
- - You should make an =IO= safe =TQueue a= with
- =Control.Concurrent.STM.newTQueueIO=. Write to it from the user
- code with =writeTQueue=, and read with =readTQueue=. A common use
- is to overwite =ppOutput= from =XMonad.Hooks.DynamicLog= as shown
- below.
-
- #+begin_src haskell
- main :: IO ()
- main = do
- initThreads
- q <- STM.newTQueueIO @String
- bar <- forkOS $ xmobar myConf
- { commands = Run (QueueReader q id "XMonadLog") : commands myConf }
- xmonad $ def { logHook = logWorkspacesToQueue q }
-
- logWorkspacesToQueue :: STM.TQueue String -> X ()
- logWorkspacesToQueue q =
- dynamicLogWithPP def { ppOutput = STM.atomically . STM.writeTQueue q }
- #+end_src
-
- Note that xmonad uses blocking Xlib calls in its event loop and isn't
- normally compiled with
- [[https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/using-concurrent.html][the threaded RTS]]
- so an xmobar thread running inside xmonad will suffer from delayed
- updates. It is thus necessary to enable =-threaded= when compiling
- xmonad configuration (=xmonad.hs=), e.g. by using a custom
- =~/.xmonad/build= script.
-
-*** Example of using the DBus IPC interface with XMonad
-
- Bind the key which should {,un}map xmobar to a dummy value. This is
- necessary for {,un}grabKey in xmonad.
-
- #+begin_src haskell
- ((0, xK_Alt_L), pure ())
- #+end_src
-
- Also, install =avoidStruts= layout modifier from
- =XMonad.Hooks.ManageDocks=
-
- Finally, install these two event hooks (=handleEventHook= in =XConfig=)
- =myDocksEventHook= is a replacement for =docksEventHook= which reacts
- on unmap events as well (which =docksEventHook= doesn't).
-
- #+begin_src haskell
- import qualified XMonad.Util.ExtensibleState as XS
-
- data DockToggleTime = DTT { lastTime :: Time } deriving (Eq, Show, Typeable)
-
- instance ExtensionClass DockToggleTime where
- initialValue = DTT 0
-
- toggleDocksHook :: Int -> KeySym -> Event -> X All
- toggleDocksHook to ks ( KeyEvent { ev_event_display = d
- , ev_event_type = et
- , ev_keycode = ekc
- , ev_time = etime
- } ) =
- io (keysymToKeycode d ks) >>= toggleDocks >> return (All True)
- where
- toggleDocks kc
- | ekc == kc && et == keyPress = do
- safeSendSignal ["Reveal 0", "TogglePersistent"]
- XS.put ( DTT etime )
- | ekc == kc && et == keyRelease = do
- gap <- XS.gets ( (-) etime . lastTime )
- safeSendSignal [ "TogglePersistent"
- , "Hide " ++ show (if gap < 400 then to else 0)
- ]
- | otherwise = return ()
-
- safeSendSignal s = catchX (io $ sendSignal s) (return ())
- sendSignal = withSession . callSignal
- withSession mc = connectSession >>= \c -> callNoReply c mc >> disconnect c
- callSignal :: [String] -> MethodCall
- callSignal s = ( methodCall
- ( objectPath_ "/org/Xmobar/Control" )
- ( interfaceName_ "org.Xmobar.Control" )
- ( memberName_ "SendSignal" )
- ) { methodCallDestination = Just $ busName_ "org.Xmobar.Control"
- , methodCallBody = map toVariant s
- }
-
- toggleDocksHook _ _ _ = return (All True)
-
- myDocksEventHook :: Event -> X All
- myDocksEventHook e = do
- when (et == mapNotify || et == unmapNotify) $
- whenX ((not `fmap` (isClient w)) <&&> runQuery checkDock w) refresh
- return (All True)
- where w = ev_window e
- et = ev_event_type e
- #+end_src
+ - This plugin is only useful if you are running xmobar from another
+ Haskell program like XMonad.
+
+ - You can use =System.Process.createPipe= to create a pair of =read= &
+ =write= Handles. Pass the =read= Handle to HandleReader and write your
+ output to the =write= Handle:
+
+ #+begin_src haskell
+ (readHandle, writeHandle) <- createPipe
+ xmobarProcess <- forkProcess $ xmobar myConfig
+ { commands =
+ Run (HandleReader readHandle "handle") : commands myConfig
+ }
+ hPutStr writeHandle "Hello World"
+ #+end_src
+
+* Software Transactional Memory
+
+ When invoking xmobar from other Haskell code it can be easier and more
+ performant to use shared memory. The following plugins leverage
+ =Control.Concurrent.STM= to realize these gains for xmobar.
+
+** =QueueReader (TQueue a) (a -> String) String=
+
+ - Display data from a Haskell =TQueue a=.
+
+ - This plugin is only useful if you are running xmobar from another
+ haskell program like xmonad.
+
+ - You should make an =IO= safe =TQueue a= with
+ =Control.Concurrent.STM.newTQueueIO=. Write to it from the user
+ code with =writeTQueue=, and read with =readTQueue=. A common use
+ is to overwite =ppOutput= from =XMonad.Hooks.DynamicLog= as shown
+ below.
+
+ #+begin_src haskell
+ main :: IO ()
+ main = do
+ initThreads
+ q <- STM.newTQueueIO @String
+ bar <- forkOS $ xmobar myConf
+ { commands = Run (QueueReader q id "XMonadLog") : commands myConf }
+ xmonad $ def { logHook = logWorkspacesToQueue q }
+
+ logWorkspacesToQueue :: STM.TQueue String -> X ()
+ logWorkspacesToQueue q =
+ dynamicLogWithPP def { ppOutput = STM.atomically . STM.writeTQueue q }
+ #+end_src
+
+ Note that xmonad uses blocking Xlib calls in its event loop and isn't
+ normally compiled with
+ [[https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/using-concurrent.html][the threaded RTS]]
+ so an xmobar thread running inside xmonad will suffer from delayed
+ updates. It is thus necessary to enable =-threaded= when compiling
+ xmonad configuration (=xmonad.hs=), e.g. by using a custom
+ =~/.xmonad/build= script.
+
+* Example of using the DBus IPC interface with XMonad
+
+ Bind the key which should {,un}map xmobar to a dummy value. This is
+ necessary for {,un}grabKey in xmonad.
+
+ #+begin_src haskell
+ ((0, xK_Alt_L), pure ())
+ #+end_src
+
+ Also, install =avoidStruts= layout modifier from
+ =XMonad.Hooks.ManageDocks=
+
+ Finally, install these two event hooks (=handleEventHook= in =XConfig=)
+ =myDocksEventHook= is a replacement for =docksEventHook= which reacts
+ on unmap events as well (which =docksEventHook= doesn't).
+
+ #+begin_src haskell
+ import qualified XMonad.Util.ExtensibleState as XS
+
+ data DockToggleTime = DTT { lastTime :: Time } deriving (Eq, Show, Typeable)
+
+ instance ExtensionClass DockToggleTime where
+ initialValue = DTT 0
+
+ toggleDocksHook :: Int -> KeySym -> Event -> X All
+ toggleDocksHook to ks ( KeyEvent { ev_event_display = d
+ , ev_event_type = et
+ , ev_keycode = ekc
+ , ev_time = etime
+ } ) =
+ io (keysymToKeycode d ks) >>= toggleDocks >> return (All True)
+ where
+ toggleDocks kc
+ | ekc == kc && et == keyPress = do
+ safeSendSignal ["Reveal 0", "TogglePersistent"]
+ XS.put ( DTT etime )
+ | ekc == kc && et == keyRelease = do
+ gap <- XS.gets ( (-) etime . lastTime )
+ safeSendSignal [ "TogglePersistent"
+ , "Hide " ++ show (if gap < 400 then to else 0)
+ ]
+ | otherwise = return ()
+
+ safeSendSignal s = catchX (io $ sendSignal s) (return ())
+ sendSignal = withSession . callSignal
+ withSession mc = connectSession >>= \c -> callNoReply c mc >> disconnect c
+ callSignal :: [String] -> MethodCall
+ callSignal s = ( methodCall
+ ( objectPath_ "/org/Xmobar/Control" )
+ ( interfaceName_ "org.Xmobar.Control" )
+ ( memberName_ "SendSignal" )
+ ) { methodCallDestination = Just $ busName_ "org.Xmobar.Control"
+ , methodCallBody = map toVariant s
+ }
+
+ toggleDocksHook _ _ _ = return (All True)
+
+ myDocksEventHook :: Event -> X All
+ myDocksEventHook e = do
+ when (et == mapNotify || et == unmapNotify) $
+ whenX ((not `fmap` (isClient w)) <&&> runQuery checkDock w) refresh
+ return (All True)
+ where w = ev_window e
+ et = ev_event_type e
+ #+end_src