<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <!-- Generated by HsColour, http://www.cs.york.ac.uk/fp/darcs/hscolour/ --> <title>XMonad/Layout/SubLayouts.hs</title> <link type='text/css' rel='stylesheet' href='hscolour.css' /> </head> <body> <pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PatternGuards, ParallelListComp, DeriveDataTypeable, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, TypeSynonymInstances #-}</span> <a name="line-2"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span> <a name="line-3"></a><span class='hs-comment'>-- |</span> <a name="line-4"></a><span class='hs-comment'>-- Module : XMonad.Layout.SubLayouts</span> <a name="line-5"></a><span class='hs-comment'>-- Copyright : (c) 2009 Adam Vogt</span> <a name="line-6"></a><span class='hs-comment'>-- License : BSD-style (see xmonad/LICENSE)</span> <a name="line-7"></a><span class='hs-comment'>--</span> <a name="line-8"></a><span class='hs-comment'>-- Maintainer : vogt.adam@gmail.com</span> <a name="line-9"></a><span class='hs-comment'>-- Stability : unstable</span> <a name="line-10"></a><span class='hs-comment'>-- Portability : unportable</span> <a name="line-11"></a><span class='hs-comment'>--</span> <a name="line-12"></a><span class='hs-comment'>-- A layout combinator that allows layouts to be nested.</span> <a name="line-13"></a><span class='hs-comment'>--</span> <a name="line-14"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span> <a name="line-15"></a> <a name="line-16"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Layout</span><span class='hs-varop'>.</span><span class='hs-conid'>SubLayouts</span> <span class='hs-layout'>(</span> <a name="line-17"></a> <span class='hs-comment'>-- * Usage</span> <a name="line-18"></a> <span class='hs-comment'>-- $usage</span> <a name="line-19"></a> <span class='hs-varid'>subLayout</span><span class='hs-layout'>,</span> <a name="line-20"></a> <span class='hs-varid'>subTabbed</span><span class='hs-layout'>,</span> <a name="line-21"></a> <a name="line-22"></a> <span class='hs-varid'>pushGroup</span><span class='hs-layout'>,</span> <span class='hs-varid'>pullGroup</span><span class='hs-layout'>,</span> <a name="line-23"></a> <span class='hs-varid'>pushWindow</span><span class='hs-layout'>,</span> <span class='hs-varid'>pullWindow</span><span class='hs-layout'>,</span> <a name="line-24"></a> <span class='hs-varid'>onGroup</span><span class='hs-layout'>,</span> <span class='hs-varid'>toSubl</span><span class='hs-layout'>,</span> <span class='hs-varid'>mergeDir</span><span class='hs-layout'>,</span> <a name="line-25"></a> <a name="line-26"></a> <span class='hs-conid'>GroupMsg</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-27"></a> <span class='hs-conid'>Broadcast</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-28"></a> <a name="line-29"></a> <span class='hs-varid'>defaultSublMap</span><span class='hs-layout'>,</span> <a name="line-30"></a> <a name="line-31"></a> <span class='hs-comment'>-- * Screenshots</span> <a name="line-32"></a> <span class='hs-comment'>-- $screenshots</span> <a name="line-33"></a> <a name="line-34"></a> <span class='hs-comment'>-- * Todo</span> <a name="line-35"></a> <span class='hs-comment'>-- $todo</span> <a name="line-36"></a> <span class='hs-layout'>)</span> <a name="line-37"></a> <span class='hs-keyword'>where</span> <a name="line-38"></a> <a name="line-39"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Layout</span><span class='hs-varop'>.</span><span class='hs-conid'>Circle</span> <span class='hs-conid'>()</span> <span class='hs-comment'>-- so haddock can find the link</span> <a name="line-40"></a> <a name="line-41"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Layout</span><span class='hs-varop'>.</span><span class='hs-conid'>Decoration</span><span class='hs-layout'>(</span><span class='hs-conid'>Decoration</span><span class='hs-layout'>,</span> <span class='hs-conid'>DefaultShrinker</span><span class='hs-layout'>)</span> <a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Layout</span><span class='hs-varop'>.</span><span class='hs-conid'>LayoutModifier</span><span class='hs-layout'>(</span><span class='hs-conid'>LayoutModifier</span><span class='hs-layout'>(</span><span class='hs-varid'>handleMess</span><span class='hs-layout'>,</span> <span class='hs-varid'>modifyLayout</span><span class='hs-layout'>,</span> <a name="line-43"></a> <span class='hs-varid'>redoLayout</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-44"></a> <span class='hs-conid'>ModifiedLayout</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-45"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Layout</span><span class='hs-varop'>.</span><span class='hs-conid'>Simplest</span><span class='hs-layout'>(</span><span class='hs-conid'>Simplest</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-46"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Layout</span><span class='hs-varop'>.</span><span class='hs-conid'>Tabbed</span><span class='hs-layout'>(</span><span class='hs-varid'>defaultTheme</span><span class='hs-layout'>,</span> <span class='hs-varid'>shrinkText</span><span class='hs-layout'>,</span> <a name="line-47"></a> <span class='hs-conid'>TabbedDecoration</span><span class='hs-layout'>,</span> <span class='hs-varid'>addTabs</span><span class='hs-layout'>)</span> <a name="line-48"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Layout</span><span class='hs-varop'>.</span><span class='hs-conid'>WindowNavigation</span><span class='hs-layout'>(</span><span class='hs-conid'>Navigate</span><span class='hs-layout'>(</span><span class='hs-conid'>Apply</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-49"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Util</span><span class='hs-varop'>.</span><span class='hs-conid'>Invisible</span><span class='hs-layout'>(</span><span class='hs-conid'>Invisible</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-50"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Util</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span><span class='hs-layout'>(</span><span class='hs-conid'>Direction2D</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-51"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>XMonad</span> <a name="line-52"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Applicative</span><span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varop'><$></span><span class='hs-layout'>)</span><span class='hs-layout'>,</span><span class='hs-layout'>(</span><span class='hs-varop'><*</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-53"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Arrow</span><span class='hs-layout'>(</span><span class='hs-conid'>Arrow</span><span class='hs-layout'>(</span><span class='hs-varid'>second</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varop'>&&&</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-54"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-layout'>(</span><span class='hs-conid'>Monad</span><span class='hs-layout'>(</span><span class='hs-varid'>return</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>Functor</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-55"></a> <span class='hs-conid'>MonadPlus</span><span class='hs-layout'>(</span><span class='hs-varid'>mplus</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varop'>=<<</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>sequence</span><span class='hs-layout'>,</span> <span class='hs-varid'>foldM</span><span class='hs-layout'>,</span> <span class='hs-varid'>guard</span><span class='hs-layout'>,</span> <span class='hs-varid'>when</span><span class='hs-layout'>,</span> <span class='hs-varid'>join</span><span class='hs-layout'>)</span> <a name="line-56"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Function</span><span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varop'>.</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varop'>$</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>flip</span><span class='hs-layout'>,</span> <span class='hs-varid'>id</span><span class='hs-layout'>,</span> <span class='hs-varid'>on</span><span class='hs-layout'>)</span> <a name="line-57"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>List</span><span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varop'>++</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>foldr</span><span class='hs-layout'>,</span> <span class='hs-varid'>filter</span><span class='hs-layout'>,</span> <span class='hs-varid'>map</span><span class='hs-layout'>,</span> <span class='hs-varid'>concatMap</span><span class='hs-layout'>,</span> <span class='hs-varid'>elem</span><span class='hs-layout'>,</span> <a name="line-58"></a> <span class='hs-varid'>notElem</span><span class='hs-layout'>,</span> <span class='hs-varid'>null</span><span class='hs-layout'>,</span> <span class='hs-varid'>nubBy</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varop'>\\</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>find</span><span class='hs-layout'>)</span> <a name="line-59"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Maybe</span><span class='hs-layout'>(</span><span class='hs-conid'>Maybe</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>isNothing</span><span class='hs-layout'>,</span> <span class='hs-varid'>maybe</span><span class='hs-layout'>,</span> <span class='hs-varid'>fromMaybe</span><span class='hs-layout'>,</span> <span class='hs-varid'>listToMaybe</span><span class='hs-layout'>,</span> <a name="line-60"></a> <span class='hs-varid'>mapMaybe</span><span class='hs-layout'>)</span> <a name="line-61"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Traversable</span><span class='hs-layout'>(</span><span class='hs-varid'>sequenceA</span><span class='hs-layout'>)</span> <a name="line-62"></a> <a name="line-63"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>Layout</span><span class='hs-varop'>.</span><span class='hs-conid'>BoringWindows</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>B</span> <a name="line-64"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>StackSet</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>W</span> <a name="line-65"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Map</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>M</span> <a name="line-66"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Map</span><span class='hs-layout'>(</span><span class='hs-conid'>Map</span><span class='hs-layout'>)</span> <a name="line-67"></a> <a name="line-68"></a><span class='hs-comment'>-- $screenshots</span> <a name="line-69"></a><span class='hs-comment'>--</span> <a name="line-70"></a><span class='hs-comment'>-- <<<a href="http://haskell.org/sitewiki/images/thumb/8/8b/Xmonad-SubLayouts-xinerama.png/480px-Xmonad-SubLayouts-xinerama.png">http://haskell.org/sitewiki/images/thumb/8/8b/Xmonad-SubLayouts-xinerama.png/480px-Xmonad-SubLayouts-xinerama.png</a>>></span> <a name="line-71"></a><span class='hs-comment'>--</span> <a name="line-72"></a><span class='hs-comment'>-- Larger version: <<a href="http://haskell.org/sitewiki/images/8/8b/Xmonad-SubLayouts-xinerama.png">http://haskell.org/sitewiki/images/8/8b/Xmonad-SubLayouts-xinerama.png</a>></span> <a name="line-73"></a> <a name="line-74"></a><span class='hs-comment'>-- $todo</span> <a name="line-75"></a><span class='hs-comment'>-- /Issue 288/</span> <a name="line-76"></a><span class='hs-comment'>--</span> <a name="line-77"></a><span class='hs-comment'>-- "XMonad.Layout.ResizableTile" assumes that its environment</span> <a name="line-78"></a><span class='hs-comment'>-- contains only the windows it is running: sublayouts are currently run with</span> <a name="line-79"></a><span class='hs-comment'>-- the stack containing only the windows passed to it in its environment, but</span> <a name="line-80"></a><span class='hs-comment'>-- any changes that the layout makes are not merged back.</span> <a name="line-81"></a><span class='hs-comment'>--</span> <a name="line-82"></a><span class='hs-comment'>-- Should the behavior be made optional?</span> <a name="line-83"></a><span class='hs-comment'>--</span> <a name="line-84"></a><span class='hs-comment'>-- /Features/</span> <a name="line-85"></a><span class='hs-comment'>--</span> <a name="line-86"></a><span class='hs-comment'>-- * suggested managehooks for merging specific windows, or the apropriate</span> <a name="line-87"></a><span class='hs-comment'>-- layout based hack to find out the number of groups currently showed, but</span> <a name="line-88"></a><span class='hs-comment'>-- the size of current window groups is not available (outside of this</span> <a name="line-89"></a><span class='hs-comment'>-- growing module)</span> <a name="line-90"></a><span class='hs-comment'>--</span> <a name="line-91"></a><span class='hs-comment'>-- /SimpleTabbed as a SubLayout/</span> <a name="line-92"></a><span class='hs-comment'>--</span> <a name="line-93"></a><span class='hs-comment'>-- 'subTabbed' works well, but it would be more uniform to avoid the use of</span> <a name="line-94"></a><span class='hs-comment'>-- addTabs, with the sublayout being Simplest (but</span> <a name="line-95"></a><span class='hs-comment'>-- 'XMonad.Layout.Tabbed.simpleTabbed' is this...). The only thing to be</span> <a name="line-96"></a><span class='hs-comment'>-- gained by fixing this issue is the ability to mix and match decoration</span> <a name="line-97"></a><span class='hs-comment'>-- styles. Better compatibility with some other layouts of which I am not</span> <a name="line-98"></a><span class='hs-comment'>-- aware could be another benefit.</span> <a name="line-99"></a><span class='hs-comment'>--</span> <a name="line-100"></a><span class='hs-comment'>-- 'simpleTabbed' (and other decorated layouts) fail horribly when used as</span> <a name="line-101"></a><span class='hs-comment'>-- subLayouts:</span> <a name="line-102"></a><span class='hs-comment'>--</span> <a name="line-103"></a><span class='hs-comment'>-- * decorations stick around: layout is run after being told to Hide</span> <a name="line-104"></a><span class='hs-comment'>--</span> <a name="line-105"></a><span class='hs-comment'>-- * mouse events do not change focus: the group-ungroup does not respect</span> <a name="line-106"></a><span class='hs-comment'>-- the focus changes it wants?</span> <a name="line-107"></a><span class='hs-comment'>--</span> <a name="line-108"></a><span class='hs-comment'>-- * sending ReleaseResources before running it makes xmonad very slow, and</span> <a name="line-109"></a><span class='hs-comment'>-- still leaves borders sticking around</span> <a name="line-110"></a><span class='hs-comment'>--</span> <a name="line-111"></a> <a name="line-112"></a><span class='hs-comment'>-- $usage</span> <a name="line-113"></a><span class='hs-comment'>-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:</span> <a name="line-114"></a><span class='hs-comment'>--</span> <a name="line-115"></a><span class='hs-comment'>-- > import XMonad.Layout.SubLayouts</span> <a name="line-116"></a><span class='hs-comment'>-- > import XMonad.Layout.WindowNavigation</span> <a name="line-117"></a><span class='hs-comment'>--</span> <a name="line-118"></a><span class='hs-comment'>-- Using "XMonad.Layout.BoringWindows" is optional and it allows you to add a</span> <a name="line-119"></a><span class='hs-comment'>-- keybinding to skip over the non-visible windows.</span> <a name="line-120"></a><span class='hs-comment'>--</span> <a name="line-121"></a><span class='hs-comment'>-- > import XMonad.Layout.BoringWindows</span> <a name="line-122"></a><span class='hs-comment'>--</span> <a name="line-123"></a><span class='hs-comment'>-- Then edit your @layoutHook@ by adding the 'subTabbed' layout modifier:</span> <a name="line-124"></a><span class='hs-comment'>--</span> <a name="line-125"></a><span class='hs-comment'>-- > myLayout = windowNavigation $ subTabbed $ boringWindows $</span> <a name="line-126"></a><span class='hs-comment'>-- > Tall 1 (3/100) (1/2) ||| etc..</span> <a name="line-127"></a><span class='hs-comment'>-- > main = xmonad defaultConfig { layoutHook = myLayout }</span> <a name="line-128"></a><span class='hs-comment'>--</span> <a name="line-129"></a><span class='hs-comment'>-- "XMonad.Layout.WindowNavigation" is used to specify which windows to merge,</span> <a name="line-130"></a><span class='hs-comment'>-- and it is not integrated into the modifier because it can be configured, and</span> <a name="line-131"></a><span class='hs-comment'>-- works best as the outer modifier.</span> <a name="line-132"></a><span class='hs-comment'>--</span> <a name="line-133"></a><span class='hs-comment'>-- Then to your keybindings add:</span> <a name="line-134"></a><span class='hs-comment'>--</span> <a name="line-135"></a><span class='hs-comment'>-- > , ((modm .|. controlMask, xK_h), sendMessage $ pullGroup L)</span> <a name="line-136"></a><span class='hs-comment'>-- > , ((modm .|. controlMask, xK_l), sendMessage $ pullGroup R)</span> <a name="line-137"></a><span class='hs-comment'>-- > , ((modm .|. controlMask, xK_k), sendMessage $ pullGroup U)</span> <a name="line-138"></a><span class='hs-comment'>-- > , ((modm .|. controlMask, xK_j), sendMessage $ pullGroup D)</span> <a name="line-139"></a><span class='hs-comment'>-- ></span> <a name="line-140"></a><span class='hs-comment'>-- > , ((modm .|. controlMask, xK_m), withFocused (sendMessage . MergeAll))</span> <a name="line-141"></a><span class='hs-comment'>-- > , ((modm .|. controlMask, xK_u), withFocused (sendMessage . UnMerge))</span> <a name="line-142"></a><span class='hs-comment'>-- ></span> <a name="line-143"></a><span class='hs-comment'>-- > , ((modm .|. controlMask, xK_period), onGroup W.focusUp')</span> <a name="line-144"></a><span class='hs-comment'>-- > , ((modm .|. controlMask, xK_comma), onGroup W.focusDown')</span> <a name="line-145"></a><span class='hs-comment'>--</span> <a name="line-146"></a><span class='hs-comment'>-- These additional keybindings require the optional</span> <a name="line-147"></a><span class='hs-comment'>-- "XMonad.Layout.BoringWindows" layoutModifier. The focus will skip over the</span> <a name="line-148"></a><span class='hs-comment'>-- windows that are not focused in each sublayout.</span> <a name="line-149"></a><span class='hs-comment'>--</span> <a name="line-150"></a><span class='hs-comment'>-- > , ((modm, xK_j), focusDown)</span> <a name="line-151"></a><span class='hs-comment'>-- > , ((modm, xK_k), focusUp)</span> <a name="line-152"></a><span class='hs-comment'>--</span> <a name="line-153"></a><span class='hs-comment'>-- A 'submap' can be used to make modifying the sublayouts using 'onGroup' and</span> <a name="line-154"></a><span class='hs-comment'>-- 'toSubl' simpler:</span> <a name="line-155"></a><span class='hs-comment'>--</span> <a name="line-156"></a><span class='hs-comment'>-- > ,((modm, xK_s), submap $ defaultSublMap conf)</span> <a name="line-157"></a><span class='hs-comment'>--</span> <a name="line-158"></a><span class='hs-comment'>-- /NOTE:/ is there some reason that @asks config >>= submap . defaultSublMap@</span> <a name="line-159"></a><span class='hs-comment'>-- could not be used in the keybinding instead? It avoids having to explicitly</span> <a name="line-160"></a><span class='hs-comment'>-- pass the conf.</span> <a name="line-161"></a><span class='hs-comment'>--</span> <a name="line-162"></a><span class='hs-comment'>-- For more detailed instructions, see:</span> <a name="line-163"></a><span class='hs-comment'>--</span> <a name="line-164"></a><span class='hs-comment'>-- "XMonad.Doc.Extending#Editing_the_layout_hook"</span> <a name="line-165"></a><span class='hs-comment'>-- "XMonad.Doc.Extending#Adding_key_bindings"</span> <a name="line-166"></a> <a name="line-167"></a><a name="subLayout"></a><span class='hs-comment'>-- | The main layout modifier arguments:</span> <a name="line-168"></a><span class='hs-comment'>--</span> <a name="line-169"></a><span class='hs-comment'>-- @subLayout advanceInnerLayouts innerLayout outerLayout@</span> <a name="line-170"></a><span class='hs-comment'>--</span> <a name="line-171"></a><span class='hs-comment'>-- [@advanceInnerLayouts@] When a new group at index @n@ in the outer layout</span> <a name="line-172"></a><span class='hs-comment'>-- is created (even with one element), the @innerLayout@ is used as the</span> <a name="line-173"></a><span class='hs-comment'>-- layout within that group after being advanced with @advanceInnerLayouts !!</span> <a name="line-174"></a><span class='hs-comment'>-- n@ 'NextLayout' messages. If there is no corresponding element in the</span> <a name="line-175"></a><span class='hs-comment'>-- @advanceInnerLayouts@ list, then @innerLayout@ is not given any 'NextLayout'</span> <a name="line-176"></a><span class='hs-comment'>-- messages.</span> <a name="line-177"></a><span class='hs-comment'>--</span> <a name="line-178"></a><span class='hs-comment'>-- [@innerLayout@] The single layout given to be run as a sublayout.</span> <a name="line-179"></a><span class='hs-comment'>--</span> <a name="line-180"></a><span class='hs-comment'>-- [@outerLayout@] The layout that determines the rectangles given to each</span> <a name="line-181"></a><span class='hs-comment'>-- group.</span> <a name="line-182"></a><span class='hs-comment'>--</span> <a name="line-183"></a><span class='hs-comment'>-- Ex. The second group is 'Tall', the third is 'Circle', all others are tabbed</span> <a name="line-184"></a><span class='hs-comment'>-- with:</span> <a name="line-185"></a><span class='hs-comment'>--</span> <a name="line-186"></a><span class='hs-comment'>-- > myLayout = addTabs shrinkText defaultTheme</span> <a name="line-187"></a><span class='hs-comment'>-- > $ subLayout [0,1,2] (Simplest ||| Tall 1 0.2 0.5 ||| Circle)</span> <a name="line-188"></a><span class='hs-comment'>-- > $ Tall 1 0.2 0.5 ||| Full</span> <a name="line-189"></a><span class='hs-definition'>subLayout</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Int</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>subl</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>ModifiedLayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>Sublayout</span> <span class='hs-varid'>subl</span><span class='hs-layout'>)</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <a name="line-190"></a><span class='hs-definition'>subLayout</span> <span class='hs-varid'>nextLayout</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ModifiedLayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>Sublayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>I</span> <span class='hs-conid'>[]</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>nextLayout</span><span class='hs-layout'>,</span><span class='hs-varid'>sl</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span><span class='hs-layout'>)</span> <span class='hs-varid'>x</span> <a name="line-191"></a> <a name="line-192"></a><a name="subTabbed"></a><span class='hs-comment'>-- | @subTabbed@ is a use of 'subLayout' with 'addTabs' to show decorations.</span> <a name="line-193"></a><span class='hs-definition'>subTabbed</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>LayoutModifier</span> <span class='hs-layout'>(</span><span class='hs-conid'>Sublayout</span> <span class='hs-conid'>Simplest</span><span class='hs-layout'>)</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>LayoutClass</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <a name="line-194"></a> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>ModifiedLayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>Decoration</span> <span class='hs-conid'>TabbedDecoration</span> <span class='hs-conid'>DefaultShrinker</span><span class='hs-layout'>)</span> <a name="line-195"></a> <span class='hs-layout'>(</span><span class='hs-conid'>ModifiedLayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>Sublayout</span> <span class='hs-conid'>Simplest</span><span class='hs-layout'>)</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-varid'>a</span> <a name="line-196"></a><span class='hs-definition'>subTabbed</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>addTabs</span> <span class='hs-varid'>shrinkText</span> <span class='hs-varid'>defaultTheme</span> <span class='hs-varop'>$</span> <span class='hs-varid'>subLayout</span> <span class='hs-conid'>[]</span> <span class='hs-conid'>Simplest</span> <span class='hs-varid'>x</span> <a name="line-197"></a> <a name="line-198"></a><a name="defaultSublMap"></a><span class='hs-comment'>-- | @defaultSublMap@ is an attempt to create a set of keybindings like the</span> <a name="line-199"></a><span class='hs-comment'>-- defaults ones but to be used as a 'submap' for sending messages to the</span> <a name="line-200"></a><span class='hs-comment'>-- sublayout.</span> <a name="line-201"></a><span class='hs-definition'>defaultSublMap</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>XConfig</span> <span class='hs-varid'>l</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Map</span> <span class='hs-layout'>(</span><span class='hs-conid'>KeyMask</span><span class='hs-layout'>,</span> <span class='hs-conid'>KeySym</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>X</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <a name="line-202"></a><span class='hs-definition'>defaultSublMap</span> <span class='hs-layout'>(</span><span class='hs-conid'>XConfig</span> <span class='hs-layout'>{</span> <span class='hs-varid'>modMask</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modm</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>fromList</span> <a name="line-203"></a> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_space</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>toSubl</span> <span class='hs-conid'>NextLayout</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-204"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_j</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>onGroup</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focusDown'</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-205"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_k</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>onGroup</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focusUp'</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-206"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_h</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>toSubl</span> <span class='hs-conid'>Shrink</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-207"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_l</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>toSubl</span> <span class='hs-conid'>Expand</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-208"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_Tab</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>onGroup</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focusDown'</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-209"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span> <span class='hs-varop'>.|.</span> <span class='hs-varid'>shiftMask</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_Tab</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>onGroup</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focusUp'</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-210"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_m</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>onGroup</span> <span class='hs-varid'>focusMaster'</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-211"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_comma</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>toSubl</span> <span class='hs-varop'>$</span> <span class='hs-conid'>IncMasterN</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-212"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_period</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>toSubl</span> <span class='hs-varop'>$</span> <span class='hs-conid'>IncMasterN</span> <span class='hs-layout'>(</span><span class='hs-comment'>-</span><span class='hs-num'>1</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-213"></a> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>modm</span><span class='hs-layout'>,</span> <span class='hs-varid'>xK_Return</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>onGroup</span> <span class='hs-varid'>swapMaster'</span><span class='hs-layout'>)</span> <a name="line-214"></a> <span class='hs-keyglyph'>]</span> <a name="line-215"></a> <span class='hs-keyword'>where</span> <a name="line-216"></a> <span class='hs-comment'>-- should these go into XMonad.StackSet?</span> <a name="line-217"></a> <span class='hs-varid'>focusMaster'</span> <span class='hs-varid'>st</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span><span class='hs-conop'>:</span><span class='hs-varid'>fs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span> <span class='hs-varid'>st</span> <a name="line-218"></a> <span class='hs-keyword'>in</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>f</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>fs</span> <a name="line-219"></a> <span class='hs-varid'>swapMaster'</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>f</span> <span class='hs-varid'>u</span> <span class='hs-varid'>d</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>f</span> <span class='hs-conid'>[]</span> <span class='hs-varop'>$</span> <span class='hs-varid'>reverse</span> <span class='hs-varid'>u</span> <span class='hs-varop'>++</span> <span class='hs-varid'>d</span> <a name="line-220"></a> <a name="line-221"></a><a name="Sublayout"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Sublayout</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Sublayout</span> <a name="line-222"></a> <span class='hs-layout'>{</span> <span class='hs-varid'>delayMess</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Invisible</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-conid'>SomeMessage</span><span class='hs-layout'>,</span><span class='hs-varid'>a</span><span class='hs-layout'>)</span> <a name="line-223"></a> <span class='hs-comment'>-- ^ messages are handled when running the layout,</span> <a name="line-224"></a> <span class='hs-comment'>-- not in the handleMessage, I'm not sure that this</span> <a name="line-225"></a> <span class='hs-comment'>-- is necessary</span> <a name="line-226"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>def</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-conid'>Int</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-comment'>-- ^ how many NextLayout messages to send to newly</span> <a name="line-227"></a> <span class='hs-comment'>-- populated layouts. If there is no corresponding</span> <a name="line-228"></a> <span class='hs-comment'>-- index, then don't send any.</span> <a name="line-229"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>subls</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>l</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <a name="line-230"></a> <span class='hs-comment'>-- ^ The sublayouts and the stacks they manage</span> <a name="line-231"></a> <span class='hs-layout'>}</span> <a name="line-232"></a> <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Read</span><span class='hs-layout'>,</span><span class='hs-conid'>Show</span><span class='hs-layout'>)</span> <a name="line-233"></a> <a name="line-234"></a><a name="Groups"></a><span class='hs-comment'>-- | Groups assumes this invariant:</span> <a name="line-235"></a><a name="Groups"></a><span class='hs-comment'>-- M.keys gs == map W.focus (M.elems gs) (ignoring order)</span> <a name="line-236"></a><a name="Groups"></a><span class='hs-comment'>-- All windows in the workspace are in the Map</span> <a name="line-237"></a><a name="Groups"></a><span class='hs-comment'>--</span> <a name="line-238"></a><a name="Groups"></a><span class='hs-comment'>-- The keys are visible windows, the rest are hidden.</span> <a name="line-239"></a><a name="Groups"></a><span class='hs-comment'>--</span> <a name="line-240"></a><a name="Groups"></a><span class='hs-comment'>-- This representation probably simplifies the internals of the modifier.</span> <a name="line-241"></a><a name="Groups"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>Groups</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Map</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <a name="line-242"></a> <a name="line-243"></a><a name="GroupMsg"></a><span class='hs-comment'>-- | GroupMsg take window parameters to determine which group the action should</span> <a name="line-244"></a><a name="GroupMsg"></a><span class='hs-comment'>-- be applied to</span> <a name="line-245"></a><a name="GroupMsg"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>GroupMsg</span> <span class='hs-varid'>a</span> <a name="line-246"></a> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>UnMerge</span> <span class='hs-varid'>a</span> <span class='hs-comment'>-- ^ free the focused window from its tab stack</span> <a name="line-247"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>UnMergeAll</span> <span class='hs-varid'>a</span> <a name="line-248"></a> <span class='hs-comment'>-- ^ separate the focused group into singleton groups</span> <a name="line-249"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Merge</span> <span class='hs-varid'>a</span> <span class='hs-varid'>a</span> <span class='hs-comment'>-- ^ merge the first group into the second group</span> <a name="line-250"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>MergeAll</span> <span class='hs-varid'>a</span> <a name="line-251"></a> <span class='hs-comment'>-- ^ make one large group, keeping the parameter focused</span> <a name="line-252"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Migrate</span> <span class='hs-varid'>a</span> <span class='hs-varid'>a</span> <a name="line-253"></a> <span class='hs-comment'>-- ^ used to the window named in the first argument to the</span> <a name="line-254"></a> <span class='hs-comment'>-- second argument's group, this may be replaced by a</span> <a name="line-255"></a> <span class='hs-comment'>-- combination of 'UnMerge' and 'Merge'</span> <a name="line-256"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>WithGroup</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>X</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>a</span> <a name="line-257"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>SubMessage</span> <span class='hs-conid'>SomeMessage</span> <span class='hs-varid'>a</span> <a name="line-258"></a> <span class='hs-comment'>-- ^ the sublayout with the given window will get the message</span> <a name="line-259"></a> <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Typeable</span><span class='hs-layout'>)</span> <a name="line-260"></a> <a name="line-261"></a><a name="mergeDir"></a><span class='hs-comment'>-- | merge the window that would be focused by the function when applied to the</span> <a name="line-262"></a><span class='hs-comment'>-- W.Stack of all windows, with the current group removed. The given window</span> <a name="line-263"></a><span class='hs-comment'>-- should be focused by a sublayout. Example usage: @withFocused (sendMessage .</span> <a name="line-264"></a><span class='hs-comment'>-- mergeDir W.focusDown')@</span> <a name="line-265"></a><span class='hs-definition'>mergeDir</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-conid'>Window</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Window</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>GroupMsg</span> <span class='hs-conid'>Window</span> <a name="line-266"></a><span class='hs-definition'>mergeDir</span> <span class='hs-varid'>f</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>WithGroup</span> <span class='hs-varid'>g</span> <span class='hs-varid'>w</span> <a name="line-267"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>g</span> <span class='hs-varid'>cs</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-268"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>onlyOthers</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varop'>`notElem`</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span> <span class='hs-varid'>cs</span><span class='hs-layout'>)</span> <a name="line-269"></a> <span class='hs-varid'>flip</span> <span class='hs-varid'>whenJust</span> <span class='hs-layout'>(</span><span class='hs-varid'>sendMessage</span> <span class='hs-varop'>.</span> <span class='hs-conid'>Merge</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>cs</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <a name="line-270"></a> <span class='hs-varop'>=<<</span> <span class='hs-varid'>fmap</span> <span class='hs-layout'>(</span><span class='hs-varid'>onlyOthers</span> <span class='hs-varop'>=<<</span><span class='hs-layout'>)</span> <span class='hs-varid'>currentStack</span> <a name="line-271"></a> <span class='hs-varid'>return</span> <span class='hs-varid'>cs</span> <a name="line-272"></a> <a name="line-273"></a><a name="Broadcast"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Broadcast</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Broadcast</span> <span class='hs-conid'>SomeMessage</span> <span class='hs-comment'>-- ^ send a message to all sublayouts</span> <a name="line-274"></a> <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Typeable</span><span class='hs-layout'>)</span> <a name="line-275"></a> <a name="line-276"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Message</span> <span class='hs-conid'>Broadcast</span> <a name="line-277"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Typeable</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>Message</span> <span class='hs-layout'>(</span><span class='hs-conid'>GroupMsg</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <a name="line-278"></a> <a name="line-279"></a><a name="pullGroup"></a><span class='hs-comment'>-- | @pullGroup@, @pushGroup@ allow you to merge windows or groups inheriting</span> <a name="line-280"></a><span class='hs-comment'>-- the position of the current window (pull) or the other window (push).</span> <a name="line-281"></a><span class='hs-comment'>--</span> <a name="line-282"></a><span class='hs-comment'>-- @pushWindow@ and @pullWindow@ move individual windows between groups. They</span> <a name="line-283"></a><span class='hs-comment'>-- are less effective at preserving window positions.</span> <a name="line-284"></a><span class='hs-definition'>pullGroup</span><span class='hs-layout'>,</span><span class='hs-varid'>pushGroup</span><span class='hs-layout'>,</span><span class='hs-varid'>pullWindow</span><span class='hs-layout'>,</span><span class='hs-varid'>pushWindow</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Direction2D</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Navigate</span> <a name="line-285"></a><span class='hs-definition'>pullGroup</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mergeNav</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>o</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>sendMessage</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Merge</span> <span class='hs-varid'>o</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <a name="line-286"></a><a name="pushGroup"></a><span class='hs-definition'>pushGroup</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mergeNav</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>o</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>sendMessage</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Merge</span> <span class='hs-varid'>c</span> <span class='hs-varid'>o</span><span class='hs-layout'>)</span> <a name="line-287"></a><a name="pullWindow"></a><span class='hs-definition'>pullWindow</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mergeNav</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>o</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>sendMessage</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Migrate</span> <span class='hs-varid'>o</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <a name="line-288"></a><a name="pushWindow"></a><span class='hs-definition'>pushWindow</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mergeNav</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>o</span> <span class='hs-varid'>c</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>sendMessage</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Migrate</span> <span class='hs-varid'>c</span> <span class='hs-varid'>o</span><span class='hs-layout'>)</span> <a name="line-289"></a> <a name="line-290"></a><a name="mergeNav"></a><span class='hs-definition'>mergeNav</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Window</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Window</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>X</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Direction2D</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Navigate</span> <a name="line-291"></a><span class='hs-definition'>mergeNav</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Apply</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>o</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>withFocused</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-varid'>o</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-292"></a> <a name="line-293"></a><a name="onGroup"></a><span class='hs-comment'>-- | Apply a function on the stack belonging to the currently focused group. It</span> <a name="line-294"></a><span class='hs-comment'>-- works for rearranging windows and for changing focus.</span> <a name="line-295"></a><span class='hs-definition'>onGroup</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-conid'>Window</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>X</span> <span class='hs-conid'>()</span> <a name="line-296"></a><span class='hs-definition'>onGroup</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withFocused</span> <span class='hs-layout'>(</span><span class='hs-varid'>sendMessage</span> <span class='hs-varop'>.</span> <span class='hs-conid'>WithGroup</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-297"></a> <a name="line-298"></a><a name="toSubl"></a><span class='hs-comment'>-- | Send a message to the currently focused sublayout.</span> <a name="line-299"></a><span class='hs-definition'>toSubl</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Message</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>X</span> <span class='hs-conid'>()</span> <a name="line-300"></a><span class='hs-definition'>toSubl</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>withFocused</span> <span class='hs-layout'>(</span><span class='hs-varid'>sendMessage</span> <span class='hs-varop'>.</span> <span class='hs-conid'>SubMessage</span> <span class='hs-layout'>(</span><span class='hs-conid'>SomeMessage</span> <span class='hs-varid'>m</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-301"></a> <a name="line-302"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>Read</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>Show</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>LayoutClass</span> <span class='hs-varid'>l</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>LayoutModifier</span> <span class='hs-layout'>(</span><span class='hs-conid'>Sublayout</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-conid'>Window</span> <span class='hs-keyword'>where</span> <a name="line-303"></a> <span class='hs-varid'>modifyLayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>Sublayout</span> <span class='hs-layout'>{</span> <span class='hs-varid'>subls</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>osls</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>la</span> <span class='hs-varid'>st</span><span class='hs-layout'>)</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-304"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>gs'</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>updateGroup</span> <span class='hs-varid'>st</span> <span class='hs-varop'>$</span> <span class='hs-varid'>toGroups</span> <span class='hs-varid'>osls</span> <a name="line-305"></a> <span class='hs-varid'>st'</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varop'>`elem`</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>keys</span> <span class='hs-varid'>gs'</span><span class='hs-layout'>)</span> <span class='hs-varop'>=<<</span> <span class='hs-varid'>st</span> <a name="line-306"></a> <span class='hs-varid'>updateWs</span> <span class='hs-varid'>gs'</span> <a name="line-307"></a> <span class='hs-varid'>oldStack</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>gets</span> <span class='hs-varop'>$</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>stack</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>workspace</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>current</span> <span class='hs-varop'>.</span> <span class='hs-varid'>windowset</span> <a name="line-308"></a> <span class='hs-varid'>setStack</span> <span class='hs-varid'>st'</span> <a name="line-309"></a> <span class='hs-varid'>runLayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>la</span> <span class='hs-varid'>st'</span><span class='hs-layout'>)</span> <span class='hs-varid'>r</span> <span class='hs-varop'><*</span> <span class='hs-varid'>setStack</span> <span class='hs-varid'>oldStack</span> <a name="line-310"></a> <span class='hs-comment'>-- FIXME: merge back reordering, deletions?</span> <a name="line-311"></a> <a name="line-312"></a> <span class='hs-varid'>redoLayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>Sublayout</span> <span class='hs-layout'>{</span> <span class='hs-varid'>delayMess</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>I</span> <span class='hs-varid'>ms</span><span class='hs-layout'>,</span> <span class='hs-varid'>def</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>defl</span><span class='hs-layout'>,</span> <span class='hs-varid'>subls</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>osls</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-sel'>_r</span> <span class='hs-varid'>st</span> <span class='hs-varid'>arrs</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-313"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>gs'</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>updateGroup</span> <span class='hs-varid'>st</span> <span class='hs-varop'>$</span> <span class='hs-varid'>toGroups</span> <span class='hs-varid'>osls</span> <a name="line-314"></a> <span class='hs-varid'>sls</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromGroups</span> <span class='hs-varid'>defl</span> <span class='hs-varid'>st</span> <span class='hs-varid'>gs'</span> <span class='hs-varid'>osls</span> <a name="line-315"></a> <a name="line-316"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>newL</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LayoutClass</span> <span class='hs-varid'>l</span> <span class='hs-conid'>Window</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>Rectangle</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>WorkspaceId</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span> <a name="line-317"></a> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>X</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>Window</span><span class='hs-layout'>,</span> <span class='hs-conid'>Rectangle</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-varid'>l</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span> <a name="line-318"></a> <span class='hs-varid'>newL</span> <span class='hs-varid'>rect</span> <span class='hs-varid'>n</span> <span class='hs-varid'>ol</span> <span class='hs-varid'>isNew</span> <span class='hs-varid'>sst</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-319"></a> <span class='hs-varid'>orgStack</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>currentStack</span> <a name="line-320"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>handle</span> <span class='hs-varid'>l</span> <span class='hs-layout'>(</span><span class='hs-varid'>y</span><span class='hs-layout'>,</span><span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <a name="line-321"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>not</span> <span class='hs-varid'>isNew</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromMaybe</span> <span class='hs-varid'>l</span> <span class='hs-varop'><$></span> <span class='hs-varid'>handleMessage</span> <span class='hs-varid'>l</span> <span class='hs-varid'>y</span> <a name="line-322"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-varid'>l</span> <a name="line-323"></a> <span class='hs-varid'>kms</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varop'>`elem`</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>keys</span> <span class='hs-varid'>gs'</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>snd</span><span class='hs-layout'>)</span> <span class='hs-varid'>ms</span> <a name="line-324"></a> <span class='hs-varid'>setStack</span> <span class='hs-varid'>sst</span> <a name="line-325"></a> <span class='hs-varid'>nl</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>foldM</span> <span class='hs-varid'>handle</span> <span class='hs-varid'>ol</span> <span class='hs-varop'>$</span> <span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varop'>`elem`</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate'</span> <span class='hs-varid'>sst</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>snd</span><span class='hs-layout'>)</span> <span class='hs-varid'>kms</span> <a name="line-326"></a> <span class='hs-varid'>result</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>runLayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Workspace</span> <span class='hs-varid'>n</span> <span class='hs-varid'>nl</span> <span class='hs-varid'>sst</span><span class='hs-layout'>)</span> <span class='hs-varid'>rect</span> <a name="line-327"></a> <span class='hs-varid'>setStack</span> <span class='hs-varid'>orgStack</span> <span class='hs-comment'>-- FIXME: merge back reordering, deletions?</span> <a name="line-328"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>fromMaybe</span> <span class='hs-varid'>nl</span> <span class='hs-varop'>`second`</span> <span class='hs-varid'>result</span> <a name="line-329"></a> <a name="line-330"></a> <span class='hs-layout'>(</span><span class='hs-varid'>urls</span><span class='hs-layout'>,</span><span class='hs-varid'>ssts</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unzip</span> <span class='hs-keyglyph'>[</span> <span class='hs-layout'>(</span><span class='hs-varid'>newL</span> <span class='hs-varid'>gr</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>isNew</span> <span class='hs-varid'>sst</span><span class='hs-layout'>,</span> <span class='hs-varid'>sst</span><span class='hs-layout'>)</span> <a name="line-331"></a> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>isNew</span><span class='hs-layout'>,</span><span class='hs-layout'>(</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span><span class='hs-sel'>_st</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>sls</span> <a name="line-332"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>map</span> <span class='hs-varid'>show</span> <span class='hs-keyglyph'>[</span> <span class='hs-num'>0</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>..</span> <span class='hs-keyglyph'>]</span> <a name="line-333"></a> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span><span class='hs-layout'>,</span><span class='hs-varid'>gr</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>arrs</span><span class='hs-layout'>,</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>sst</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>lookup</span> <span class='hs-varid'>k</span> <span class='hs-varid'>gs'</span> <span class='hs-keyglyph'>]</span> <a name="line-334"></a> <a name="line-335"></a> <span class='hs-varid'>arrs'</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>sequence</span> <span class='hs-varid'>urls</span> <a name="line-336"></a> <span class='hs-varid'>sls'</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>return</span> <span class='hs-varop'>.</span> <span class='hs-conid'>Sublayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>I</span> <span class='hs-conid'>[]</span><span class='hs-layout'>)</span> <span class='hs-varid'>defl</span> <span class='hs-varop'>.</span> <span class='hs-varid'>map</span> <span class='hs-varid'>snd</span> <span class='hs-varop'><$></span> <span class='hs-varid'>fromGroups</span> <span class='hs-varid'>defl</span> <span class='hs-varid'>st</span> <span class='hs-varid'>gs'</span> <a name="line-337"></a> <span class='hs-keyglyph'>[</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span><span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span><span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>arrs'</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>ssts</span> <span class='hs-keyglyph'>]</span> <a name="line-338"></a> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>concatMap</span> <span class='hs-varid'>fst</span> <span class='hs-varid'>arrs'</span><span class='hs-layout'>,</span> <span class='hs-varid'>sls'</span><span class='hs-layout'>)</span> <a name="line-339"></a> <a name="line-340"></a> <span class='hs-varid'>handleMess</span> <span class='hs-layout'>(</span><span class='hs-conid'>Sublayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>I</span> <span class='hs-varid'>ms</span><span class='hs-layout'>)</span> <span class='hs-varid'>defl</span> <span class='hs-varid'>sls</span><span class='hs-layout'>)</span> <span class='hs-varid'>m</span> <a name="line-341"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>SubMessage</span> <span class='hs-varid'>sm</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <a name="line-342"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Sublayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>I</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>sm</span><span class='hs-layout'>,</span><span class='hs-varid'>w</span><span class='hs-layout'>)</span><span class='hs-conop'>:</span><span class='hs-varid'>ms</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>defl</span> <span class='hs-varid'>sls</span> <a name="line-343"></a> <a name="line-344"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>Broadcast</span> <span class='hs-varid'>sm</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-345"></a> <span class='hs-varid'>ms'</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fmap</span> <span class='hs-layout'>(</span><span class='hs-varid'>zip</span> <span class='hs-layout'>(</span><span class='hs-varid'>repeat</span> <span class='hs-varid'>sm</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate'</span><span class='hs-layout'>)</span> <span class='hs-varid'>currentStack</span> <a name="line-346"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>null</span> <span class='hs-varid'>ms'</span> <span class='hs-keyword'>then</span> <span class='hs-conid'>Nothing</span> <a name="line-347"></a> <span class='hs-keyword'>else</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Sublayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>I</span> <span class='hs-varop'>$</span> <span class='hs-varid'>ms'</span> <span class='hs-varop'>++</span> <span class='hs-varid'>ms</span><span class='hs-layout'>)</span> <span class='hs-varid'>defl</span> <span class='hs-varid'>sls</span> <a name="line-348"></a> <a name="line-349"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>UpdateBoring</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-350"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>bs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>concatMap</span> <span class='hs-varid'>unfocused</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>elems</span> <span class='hs-varid'>gs</span> <a name="line-351"></a> <span class='hs-varid'>ws</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>gets</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>workspace</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>current</span> <span class='hs-varop'>.</span> <span class='hs-varid'>windowset</span><span class='hs-layout'>)</span> <a name="line-352"></a> <span class='hs-varid'>flip</span> <span class='hs-varid'>sendMessageWithNoRefresh</span> <span class='hs-varid'>ws</span> <span class='hs-varop'>$</span> <span class='hs-conid'>B</span><span class='hs-varop'>.</span><span class='hs-conid'>Replace</span> <span class='hs-str'>"Sublayouts"</span> <span class='hs-varid'>bs</span> <a name="line-353"></a> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span> <a name="line-354"></a> <a name="line-355"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>WithGroup</span> <span class='hs-varid'>f</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <a name="line-356"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'><-</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>lookup</span> <span class='hs-varid'>w</span> <span class='hs-varid'>gs</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-357"></a> <span class='hs-varid'>g'</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>f</span> <span class='hs-varid'>g</span> <a name="line-358"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>gs'</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>insert</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <span class='hs-varid'>g'</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>delete</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <span class='hs-varid'>gs</span> <a name="line-359"></a> <span class='hs-varid'>when</span> <span class='hs-layout'>(</span><span class='hs-varid'>gs'</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>gs</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>updateWs</span> <span class='hs-varid'>gs'</span> <a name="line-360"></a> <span class='hs-varid'>when</span> <span class='hs-layout'>(</span><span class='hs-varid'>w</span> <span class='hs-varop'>/=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>windows</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focusWindow</span> <span class='hs-varop'>$</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <a name="line-361"></a> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span> <a name="line-362"></a> <a name="line-363"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>MergeAll</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <a name="line-364"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>gs'</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fmap</span> <span class='hs-layout'>(</span><span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>singleton</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span> <a name="line-365"></a> <span class='hs-varop'>$</span> <span class='hs-layout'>(</span><span class='hs-varid'>focusWindow'</span> <span class='hs-varid'>w</span> <span class='hs-varop'>=<<</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>differentiate</span> <a name="line-366"></a> <span class='hs-varop'>$</span> <span class='hs-varid'>concatMap</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>elems</span> <span class='hs-varid'>gs</span> <a name="line-367"></a> <span class='hs-keyword'>in</span> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-varid'>fgs</span> <span class='hs-varid'>gs'</span> <a name="line-368"></a> <a name="line-369"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>UnMergeAll</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <a name="line-370"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>ws</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>concatMap</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>elems</span> <span class='hs-varid'>gs</span> <a name="line-371"></a> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Window</span> <a name="line-372"></a> <span class='hs-varid'>mkSingleton</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>singleton</span> <span class='hs-varid'>f</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>f</span> <span class='hs-conid'>[]</span> <span class='hs-conid'>[]</span><span class='hs-layout'>)</span> <a name="line-373"></a> <span class='hs-keyword'>in</span> <span class='hs-varid'>fgs</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>unions</span> <span class='hs-varop'>$</span> <span class='hs-varid'>map</span> <span class='hs-varid'>mkSingleton</span> <span class='hs-varid'>ws</span> <a name="line-374"></a> <a name="line-375"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>Merge</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <a name="line-376"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>xb</span> <span class='hs-varid'>xn</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>findGroup</span> <span class='hs-varid'>x</span> <a name="line-377"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>yst</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>findGroup</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <a name="line-378"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>zs</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xb</span> <span class='hs-layout'>(</span><span class='hs-varid'>xn</span> <span class='hs-varop'>++</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span> <span class='hs-varid'>yst</span><span class='hs-layout'>)</span> <a name="line-379"></a> <span class='hs-keyword'>in</span> <span class='hs-varid'>fgs</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>insert</span> <span class='hs-varid'>x</span> <span class='hs-varid'>zs</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>delete</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>yst</span><span class='hs-layout'>)</span> <span class='hs-varid'>gs</span> <a name="line-380"></a> <a name="line-381"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>UnMerge</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>=</span> <a name="line-382"></a> <span class='hs-varid'>fgs</span> <span class='hs-varop'>.</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>fromList</span> <span class='hs-varop'>.</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varop'>&&&</span> <span class='hs-varid'>id</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>elems</span> <a name="line-383"></a> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>mapMaybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-varop'>/=</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>gs</span> <a name="line-384"></a> <a name="line-385"></a> <span class='hs-comment'>-- XXX sometimes this migrates an incorrect window, why?</span> <a name="line-386"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>Migrate</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <a name="line-387"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>xst</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>findGroup</span> <span class='hs-varid'>x</span> <a name="line-388"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>yf</span> <span class='hs-varid'>yu</span> <span class='hs-varid'>yd</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>findGroup</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <a name="line-389"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>zs</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>x</span> <span class='hs-layout'>(</span><span class='hs-varid'>yf</span><span class='hs-conop'>:</span><span class='hs-varid'>yu</span><span class='hs-layout'>)</span> <span class='hs-varid'>yd</span> <a name="line-390"></a> <span class='hs-varid'>nxsAdd</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>maybe</span> <span class='hs-varid'>id</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>e</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>insert</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-varop'>/=</span><span class='hs-layout'>)</span> <span class='hs-varid'>xst</span> <a name="line-391"></a> <span class='hs-keyword'>in</span> <span class='hs-varid'>fgs</span> <span class='hs-varop'>$</span> <span class='hs-varid'>nxsAdd</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>insert</span> <span class='hs-varid'>x</span> <span class='hs-varid'>zs</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>delete</span> <span class='hs-varid'>yf</span> <span class='hs-varid'>gs</span> <a name="line-392"></a> <a name="line-393"></a> <a name="line-394"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fmap</span> <span class='hs-varid'>join</span> <span class='hs-varop'>$</span> <span class='hs-varid'>sequenceA</span> <span class='hs-varop'>$</span> <span class='hs-varid'>catchLayoutMess</span> <span class='hs-varop'><$></span> <span class='hs-varid'>fromMessage</span> <span class='hs-varid'>m</span> <a name="line-395"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>gs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>toGroups</span> <span class='hs-varid'>sls</span> <a name="line-396"></a> <span class='hs-varid'>fgs</span> <span class='hs-varid'>gs'</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-397"></a> <span class='hs-varid'>st</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>currentStack</span> <a name="line-398"></a> <span class='hs-conid'>Just</span> <span class='hs-varop'>.</span> <span class='hs-conid'>Sublayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>I</span> <span class='hs-varid'>ms</span><span class='hs-layout'>)</span> <span class='hs-varid'>defl</span> <span class='hs-varop'>.</span> <span class='hs-varid'>map</span> <span class='hs-varid'>snd</span> <span class='hs-varop'><$></span> <span class='hs-varid'>fromGroups</span> <span class='hs-varid'>defl</span> <span class='hs-varid'>st</span> <span class='hs-varid'>gs'</span> <span class='hs-varid'>sls</span> <a name="line-399"></a> <a name="line-400"></a> <span class='hs-varid'>findGroup</span> <span class='hs-varid'>z</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mplus</span> <span class='hs-layout'>(</span><span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>lookup</span> <span class='hs-varid'>z</span> <span class='hs-varid'>gs</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>listToMaybe</span> <a name="line-401"></a> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>elems</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>z</span> <span class='hs-varop'>`elem`</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span><span class='hs-layout'>)</span> <span class='hs-varid'>gs</span> <a name="line-402"></a> <span class='hs-comment'>-- catchLayoutMess :: LayoutMessages -> X (Maybe (Sublayout l Window))</span> <a name="line-403"></a> <span class='hs-comment'>-- This l must be the same as from the instance head,</span> <a name="line-404"></a> <span class='hs-comment'>-- -XScopedTypeVariables should bring it into scope, but we are</span> <a name="line-405"></a> <span class='hs-comment'>-- trying to avoid warnings with ghc-6.8.2 and avoid CPP</span> <a name="line-406"></a> <span class='hs-varid'>catchLayoutMess</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-407"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>m'</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x</span> <span class='hs-varop'>`asTypeOf`</span> <span class='hs-layout'>(</span><span class='hs-varid'>undefined</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LayoutMessages</span><span class='hs-layout'>)</span> <a name="line-408"></a> <span class='hs-varid'>ms'</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>zip</span> <span class='hs-layout'>(</span><span class='hs-varid'>repeat</span> <span class='hs-varop'>$</span> <span class='hs-conid'>SomeMessage</span> <span class='hs-varid'>m'</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate'</span> <a name="line-409"></a> <span class='hs-varop'><$></span> <span class='hs-varid'>currentStack</span> <a name="line-410"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>guard</span> <span class='hs-varop'>$</span> <span class='hs-varid'>not</span> <span class='hs-varop'>$</span> <span class='hs-varid'>null</span> <span class='hs-varid'>ms'</span> <a name="line-411"></a> <span class='hs-conid'>Just</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Sublayout</span> <span class='hs-layout'>(</span><span class='hs-conid'>I</span> <span class='hs-varop'>$</span> <span class='hs-varid'>ms'</span> <span class='hs-varop'>++</span> <span class='hs-varid'>ms</span><span class='hs-layout'>)</span> <span class='hs-varid'>defl</span> <span class='hs-varid'>sls</span> <a name="line-412"></a> <a name="line-413"></a><a name="currentStack"></a><span class='hs-definition'>currentStack</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>X</span> <span class='hs-layout'>(</span><span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-414"></a><span class='hs-definition'>currentStack</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>gets</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>stack</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>workspace</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>current</span> <span class='hs-varop'>.</span> <span class='hs-varid'>windowset</span><span class='hs-layout'>)</span> <a name="line-415"></a> <a name="line-416"></a><a name="updateGroup"></a><span class='hs-comment'>-- | update Group to follow changes in the workspace</span> <a name="line-417"></a><span class='hs-definition'>updateGroup</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=></span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Groups</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Groups</span> <span class='hs-varid'>a</span> <a name="line-418"></a><span class='hs-definition'>updateGroup</span> <span class='hs-varid'>mst</span> <span class='hs-varid'>gs</span> <span class='hs-keyglyph'>=</span> <a name="line-419"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>flatten</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>concatMap</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span> <span class='hs-varop'>.</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>elems</span> <a name="line-420"></a> <span class='hs-varid'>news</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate'</span> <span class='hs-varid'>mst</span> <span class='hs-varop'>\\</span> <span class='hs-varid'>flatten</span> <span class='hs-varid'>gs</span> <a name="line-421"></a> <span class='hs-varid'>deads</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>flatten</span> <span class='hs-varid'>gs</span> <span class='hs-varop'>\\</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate'</span> <span class='hs-varid'>mst</span> <a name="line-422"></a> <a name="line-423"></a> <span class='hs-varid'>uniNew</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>union</span> <span class='hs-layout'>(</span><span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>fromList</span> <span class='hs-varop'>$</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>n</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>n</span><span class='hs-layout'>,</span><span class='hs-varid'>single</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>news</span><span class='hs-layout'>)</span> <a name="line-424"></a> <span class='hs-varid'>single</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>x</span> <span class='hs-conid'>[]</span> <span class='hs-conid'>[]</span> <a name="line-425"></a> <a name="line-426"></a> <span class='hs-comment'>-- pass through a list to update/remove keys</span> <a name="line-427"></a> <span class='hs-varid'>remDead</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>fromList</span> <span class='hs-varop'>.</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>w</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>w</span><span class='hs-layout'>,</span><span class='hs-varid'>w</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-428"></a> <span class='hs-varop'>.</span> <span class='hs-varid'>mapMaybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varop'>`notElem`</span> <span class='hs-varid'>deads</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>elems</span> <a name="line-429"></a> <a name="line-430"></a> <span class='hs-comment'>-- update the current tab group's order and focus</span> <a name="line-431"></a> <span class='hs-varid'>followFocus</span> <span class='hs-varid'>hs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromMaybe</span> <span class='hs-varid'>hs</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span> <a name="line-432"></a> <span class='hs-varid'>f'</span> <span class='hs-keyglyph'><-</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varop'>`fmap`</span> <span class='hs-varid'>mst</span> <a name="line-433"></a> <span class='hs-varid'>xs</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>find</span> <span class='hs-layout'>(</span><span class='hs-varid'>elem</span> <span class='hs-varid'>f'</span> <span class='hs-varop'>.</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>elems</span> <span class='hs-varid'>hs</span> <a name="line-434"></a> <span class='hs-varid'>xs'</span> <span class='hs-keyglyph'><-</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varop'>`elem`</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-varop'>=<<</span> <span class='hs-varid'>mst</span> <a name="line-435"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>insert</span> <span class='hs-varid'>f'</span> <span class='hs-varid'>xs'</span> <span class='hs-varop'>$</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>delete</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-varid'>hs</span> <a name="line-436"></a> <a name="line-437"></a> <span class='hs-keyword'>in</span> <span class='hs-varid'>remDead</span> <span class='hs-varop'>$</span> <span class='hs-varid'>uniNew</span> <span class='hs-varop'>$</span> <span class='hs-varid'>followFocus</span> <span class='hs-varid'>gs</span> <a name="line-438"></a> <a name="line-439"></a><a name="updateWs"></a><span class='hs-comment'>-- | rearrange the windowset to put the groups of tabs next to eachother, so</span> <a name="line-440"></a><span class='hs-comment'>-- that the stack of tabs stays put.</span> <a name="line-441"></a><span class='hs-definition'>updateWs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Groups</span> <span class='hs-conid'>Window</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>X</span> <span class='hs-conid'>()</span> <a name="line-442"></a><span class='hs-definition'>updateWs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>windowsMaybe</span> <span class='hs-varop'>.</span> <span class='hs-varid'>updateWs'</span> <a name="line-443"></a> <a name="line-444"></a><a name="updateWs'"></a><span class='hs-definition'>updateWs'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Groups</span> <span class='hs-conid'>Window</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>WindowSet</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>WindowSet</span> <a name="line-445"></a><span class='hs-definition'>updateWs'</span> <span class='hs-varid'>gs</span> <span class='hs-varid'>ws</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-446"></a> <span class='hs-varid'>f</span> <span class='hs-keyglyph'><-</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>peek</span> <span class='hs-varid'>ws</span> <a name="line-447"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>index</span> <span class='hs-varid'>ws</span> <a name="line-448"></a> <span class='hs-varid'>nes</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>concatMap</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mapMaybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>flip</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>lookup</span> <span class='hs-varid'>gs</span><span class='hs-layout'>)</span> <span class='hs-varid'>w</span> <a name="line-449"></a> <span class='hs-varid'>ws'</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focusWindow</span> <span class='hs-varid'>f</span> <span class='hs-varop'>$</span> <span class='hs-varid'>foldr</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>insertUp</span> <span class='hs-layout'>(</span><span class='hs-varid'>foldr</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>delete'</span> <span class='hs-varid'>ws</span> <span class='hs-varid'>nes</span><span class='hs-layout'>)</span> <span class='hs-varid'>nes</span> <a name="line-450"></a> <span class='hs-varid'>guard</span> <span class='hs-varop'>$</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>index</span> <span class='hs-varid'>ws'</span> <span class='hs-varop'>/=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>index</span> <span class='hs-varid'>ws</span> <a name="line-451"></a> <span class='hs-varid'>return</span> <span class='hs-varid'>ws'</span> <a name="line-452"></a> <a name="line-453"></a><a name="focusWindow'"></a><span class='hs-comment'>-- | focusWindow'. focus an element of a stack, is Nothing if that element is</span> <a name="line-454"></a><span class='hs-comment'>-- absent. See also 'W.focusWindow'</span> <a name="line-455"></a><span class='hs-definition'>focusWindow'</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <a name="line-456"></a><span class='hs-definition'>focusWindow'</span> <span class='hs-varid'>w</span> <span class='hs-varid'>st</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-457"></a> <span class='hs-varid'>guard</span> <span class='hs-varop'>$</span> <span class='hs-varid'>not</span> <span class='hs-varop'>$</span> <span class='hs-varid'>null</span> <span class='hs-varop'>$</span> <span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varid'>w</span><span class='hs-varop'>==</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate</span> <span class='hs-varid'>st</span> <a name="line-458"></a> <span class='hs-keyword'>if</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varid'>st</span> <span class='hs-varop'>==</span> <span class='hs-varid'>w</span> <span class='hs-keyword'>then</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>st</span> <a name="line-459"></a> <span class='hs-keyword'>else</span> <span class='hs-varid'>focusWindow'</span> <span class='hs-varid'>w</span> <span class='hs-varop'>$</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focusDown'</span> <span class='hs-varid'>st</span> <a name="line-460"></a> <a name="line-461"></a><a name="windowsMaybe"></a><span class='hs-comment'>-- update only when Just</span> <a name="line-462"></a><span class='hs-definition'>windowsMaybe</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>WindowSet</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>WindowSet</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>X</span> <span class='hs-conid'>()</span> <a name="line-463"></a><span class='hs-definition'>windowsMaybe</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-464"></a> <span class='hs-varid'>xst</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>get</span> <a name="line-465"></a> <span class='hs-varid'>ws</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>gets</span> <span class='hs-varid'>windowset</span> <a name="line-466"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>up</span> <span class='hs-varid'>fws</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>put</span> <span class='hs-varid'>xst</span> <span class='hs-layout'>{</span> <span class='hs-varid'>windowset</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fws</span> <span class='hs-layout'>}</span> <a name="line-467"></a> <span class='hs-varid'>maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-conid'>()</span><span class='hs-layout'>)</span> <span class='hs-varid'>up</span> <span class='hs-varop'>$</span> <span class='hs-varid'>f</span> <span class='hs-varid'>ws</span> <a name="line-468"></a> <a name="line-469"></a><a name="unfocused"></a><span class='hs-definition'>unfocused</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <a name="line-470"></a><span class='hs-definition'>unfocused</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>up</span> <span class='hs-varid'>x</span> <span class='hs-varop'>++</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>down</span> <span class='hs-varid'>x</span> <a name="line-471"></a> <a name="line-472"></a><a name="toGroups"></a><span class='hs-definition'>toGroups</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>a1</span><span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Map</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <a name="line-473"></a><span class='hs-definition'>toGroups</span> <span class='hs-varid'>ws</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>fromList</span> <span class='hs-varop'>.</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span> <span class='hs-varop'>&&&</span> <span class='hs-varid'>id</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>nubBy</span> <span class='hs-layout'>(</span><span class='hs-varid'>on</span> <span class='hs-layout'>(</span><span class='hs-varop'>==</span><span class='hs-layout'>)</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>focus</span><span class='hs-layout'>)</span> <a name="line-474"></a> <span class='hs-varop'>$</span> <span class='hs-varid'>map</span> <span class='hs-varid'>snd</span> <span class='hs-varid'>ws</span> <a name="line-475"></a> <a name="line-476"></a><a name="fromGroups"></a><span class='hs-comment'>-- | restore the default layout for each group. It needs the X monad to switch</span> <a name="line-477"></a><span class='hs-comment'>-- the default layout to a specific one (handleMessage NextLayout)</span> <a name="line-478"></a><span class='hs-definition'>fromGroups</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>LayoutClass</span> <span class='hs-varid'>layout</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <a name="line-479"></a> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-conid'>Int</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-varid'>layout</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <a name="line-480"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span> <a name="line-481"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Groups</span> <span class='hs-varid'>k</span> <a name="line-482"></a> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>layout</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <a name="line-483"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>X</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>Bool</span><span class='hs-layout'>,</span><span class='hs-layout'>(</span><span class='hs-varid'>layout</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <a name="line-484"></a><span class='hs-definition'>fromGroups</span> <span class='hs-layout'>(</span><span class='hs-varid'>skips</span><span class='hs-layout'>,</span><span class='hs-varid'>defl</span><span class='hs-layout'>)</span> <span class='hs-varid'>st</span> <span class='hs-varid'>gs</span> <span class='hs-varid'>sls</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-485"></a> <span class='hs-varid'>defls</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>mapM</span> <span class='hs-layout'>(</span><span class='hs-varid'>iterateM</span> <span class='hs-varid'>nextL</span> <span class='hs-varid'>defl</span> <span class='hs-varop'>!!</span><span class='hs-layout'>)</span> <span class='hs-varid'>skips</span> <a name="line-486"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>fromGroups'</span> <span class='hs-varid'>defl</span> <span class='hs-varid'>defls</span> <span class='hs-varid'>st</span> <span class='hs-varid'>gs</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>fst</span> <span class='hs-varid'>sls</span><span class='hs-layout'>)</span> <a name="line-487"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>nextL</span> <span class='hs-varid'>l</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromMaybe</span> <span class='hs-varid'>l</span> <span class='hs-varop'><$></span> <span class='hs-varid'>handleMessage</span> <span class='hs-varid'>l</span> <span class='hs-layout'>(</span><span class='hs-conid'>SomeMessage</span> <span class='hs-conid'>NextLayout</span><span class='hs-layout'>)</span> <a name="line-488"></a> <span class='hs-varid'>iterateM</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>iterate</span> <span class='hs-layout'>(</span><span class='hs-varop'>>>=</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>return</span> <a name="line-489"></a> <a name="line-490"></a><a name="fromGroups'"></a><span class='hs-definition'>fromGroups'</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Ord</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Groups</span> <span class='hs-varid'>k</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <a name="line-491"></a> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>Bool</span><span class='hs-layout'>,</span><span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <a name="line-492"></a><span class='hs-definition'>fromGroups'</span> <span class='hs-varid'>defl</span> <span class='hs-varid'>defls</span> <span class='hs-varid'>st</span> <span class='hs-varid'>gs</span> <span class='hs-varid'>sls</span> <span class='hs-keyglyph'>=</span> <a name="line-493"></a> <span class='hs-keyglyph'>[</span> <span class='hs-layout'>(</span><span class='hs-varid'>isNew</span><span class='hs-layout'>,</span><span class='hs-varid'>fromMaybe2</span> <span class='hs-layout'>(</span><span class='hs-varid'>dl</span><span class='hs-layout'>,</span> <span class='hs-varid'>single</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>lookup</span> <span class='hs-varid'>w</span> <span class='hs-varid'>gs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-494"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>l</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>map</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>sls</span> <span class='hs-varop'>++</span> <span class='hs-varid'>repeat</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>,</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>isNew</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isNothing</span> <span class='hs-varid'>l</span> <a name="line-495"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>dl</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>defls</span> <span class='hs-varop'>++</span> <span class='hs-varid'>repeat</span> <span class='hs-varid'>defl</span> <a name="line-496"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'><-</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>integrate'</span> <span class='hs-varop'>$</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varop'>`notElem`</span> <span class='hs-varid'>unfocs</span><span class='hs-layout'>)</span> <span class='hs-varop'>=<<</span> <span class='hs-varid'>st</span> <span class='hs-keyglyph'>]</span> <a name="line-497"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>unfocs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unfocused</span> <span class='hs-varop'>=<<</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>elems</span> <span class='hs-varid'>gs</span> <a name="line-498"></a> <span class='hs-varid'>single</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>w</span> <span class='hs-conid'>[]</span> <span class='hs-conid'>[]</span> <a name="line-499"></a> <span class='hs-varid'>fromMaybe2</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-layout'>,</span><span class='hs-varid'>y</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromMaybe</span> <span class='hs-varid'>a</span> <span class='hs-varid'>x</span><span class='hs-layout'>,</span> <span class='hs-varid'>fromMaybe</span> <span class='hs-varid'>b</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span> <a name="line-500"></a> <a name="line-501"></a> <a name="line-502"></a><a name="setStack"></a><span class='hs-comment'>-- this would be much cleaner with some kind of data-accessor</span> <a name="line-503"></a><span class='hs-definition'>setStack</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-conid'>Stack</span> <span class='hs-conid'>Window</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>X</span> <span class='hs-conid'>()</span> <a name="line-504"></a><span class='hs-definition'>setStack</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>s</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>s</span> <span class='hs-layout'>{</span> <span class='hs-varid'>windowset</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>windowset</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <a name="line-505"></a> <span class='hs-layout'>{</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>current</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>current</span> <span class='hs-varop'>$</span> <span class='hs-varid'>windowset</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <a name="line-506"></a> <span class='hs-layout'>{</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>workspace</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>workspace</span> <span class='hs-varop'>$</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>current</span> <span class='hs-varop'>$</span> <span class='hs-varid'>windowset</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>{</span> <span class='hs-conid'>W</span><span class='hs-varop'>.</span><span class='hs-varid'>stack</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x</span> <span class='hs-layout'>}</span><span class='hs-layout'>}</span><span class='hs-layout'>}</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span> </pre></body> </html>