Sophie

Sophie

distrib > Fedora > 18 > x86_64 > by-pkgid > e7e0a402b8e59e62843ee0e8d17757b3 > files > 97

ghc-xmonad-devel-0.11-1.fc18.x86_64.rpm

<?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://code.haskell.org/~malcolm/hscolour/ -->
<title>XMonad/StackSet.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 #-}</span>
<a name="line-2"></a>
<a name="line-3"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-4"></a><span class='hs-comment'>-- |</span>
<a name="line-5"></a><span class='hs-comment'>-- Module      :  XMonad.StackSet</span>
<a name="line-6"></a><span class='hs-comment'>-- Copyright   :  (c) Don Stewart 2007</span>
<a name="line-7"></a><span class='hs-comment'>-- License     :  BSD3-style (see LICENSE)</span>
<a name="line-8"></a><span class='hs-comment'>--</span>
<a name="line-9"></a><span class='hs-comment'>-- Maintainer  :  dons@galois.com</span>
<a name="line-10"></a><span class='hs-comment'>-- Stability   :  experimental</span>
<a name="line-11"></a><span class='hs-comment'>-- Portability :  portable, Haskell 98</span>
<a name="line-12"></a><span class='hs-comment'>--</span>
<a name="line-13"></a>
<a name="line-14"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>XMonad</span><span class='hs-varop'>.</span><span class='hs-conid'>StackSet</span> <span class='hs-layout'>(</span>
<a name="line-15"></a>        <span class='hs-comment'>-- * Introduction</span>
<a name="line-16"></a>        <span class='hs-comment'>-- $intro</span>
<a name="line-17"></a>
<a name="line-18"></a>        <span class='hs-comment'>-- ** The Zipper</span>
<a name="line-19"></a>        <span class='hs-comment'>-- $zipper</span>
<a name="line-20"></a>
<a name="line-21"></a>        <span class='hs-comment'>-- ** Xinerama support</span>
<a name="line-22"></a>        <span class='hs-comment'>-- $xinerama</span>
<a name="line-23"></a>
<a name="line-24"></a>        <span class='hs-comment'>-- ** Master and Focus</span>
<a name="line-25"></a>        <span class='hs-comment'>-- $focus</span>
<a name="line-26"></a>
<a name="line-27"></a>        <span class='hs-conid'>StackSet</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>Workspace</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>Screen</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>Stack</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>RationalRect</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>        <span class='hs-comment'>-- *  Construction</span>
<a name="line-29"></a>        <span class='hs-comment'>-- $construction</span>
<a name="line-30"></a>        <span class='hs-varid'>new</span><span class='hs-layout'>,</span> <span class='hs-varid'>view</span><span class='hs-layout'>,</span> <span class='hs-varid'>greedyView</span><span class='hs-layout'>,</span>
<a name="line-31"></a>        <span class='hs-comment'>-- * Xinerama operations</span>
<a name="line-32"></a>        <span class='hs-comment'>-- $xinerama</span>
<a name="line-33"></a>        <span class='hs-varid'>lookupWorkspace</span><span class='hs-layout'>,</span>
<a name="line-34"></a>        <span class='hs-varid'>screens</span><span class='hs-layout'>,</span> <span class='hs-varid'>workspaces</span><span class='hs-layout'>,</span> <span class='hs-varid'>allWindows</span><span class='hs-layout'>,</span> <span class='hs-varid'>currentTag</span><span class='hs-layout'>,</span>
<a name="line-35"></a>        <span class='hs-comment'>-- *  Operations on the current stack</span>
<a name="line-36"></a>        <span class='hs-comment'>-- $stackOperations</span>
<a name="line-37"></a>        <span class='hs-varid'>peek</span><span class='hs-layout'>,</span> <span class='hs-varid'>index</span><span class='hs-layout'>,</span> <span class='hs-varid'>integrate</span><span class='hs-layout'>,</span> <span class='hs-varid'>integrate'</span><span class='hs-layout'>,</span> <span class='hs-varid'>differentiate</span><span class='hs-layout'>,</span>
<a name="line-38"></a>        <span class='hs-varid'>focusUp</span><span class='hs-layout'>,</span> <span class='hs-varid'>focusDown</span><span class='hs-layout'>,</span> <span class='hs-varid'>focusUp'</span><span class='hs-layout'>,</span> <span class='hs-varid'>focusDown'</span><span class='hs-layout'>,</span> <span class='hs-varid'>focusMaster</span><span class='hs-layout'>,</span> <span class='hs-varid'>focusWindow</span><span class='hs-layout'>,</span>
<a name="line-39"></a>        <span class='hs-varid'>tagMember</span><span class='hs-layout'>,</span> <span class='hs-varid'>renameTag</span><span class='hs-layout'>,</span> <span class='hs-varid'>ensureTags</span><span class='hs-layout'>,</span> <span class='hs-varid'>member</span><span class='hs-layout'>,</span> <span class='hs-varid'>findTag</span><span class='hs-layout'>,</span> <span class='hs-varid'>mapWorkspace</span><span class='hs-layout'>,</span> <span class='hs-varid'>mapLayout</span><span class='hs-layout'>,</span>
<a name="line-40"></a>        <span class='hs-comment'>-- * Modifying the stackset</span>
<a name="line-41"></a>        <span class='hs-comment'>-- $modifyStackset</span>
<a name="line-42"></a>        <span class='hs-varid'>insertUp</span><span class='hs-layout'>,</span> <span class='hs-varid'>delete</span><span class='hs-layout'>,</span> <span class='hs-varid'>delete'</span><span class='hs-layout'>,</span> <span class='hs-varid'>filter</span><span class='hs-layout'>,</span>
<a name="line-43"></a>        <span class='hs-comment'>-- * Setting the master window</span>
<a name="line-44"></a>        <span class='hs-comment'>-- $settingMW</span>
<a name="line-45"></a>        <span class='hs-varid'>swapUp</span><span class='hs-layout'>,</span> <span class='hs-varid'>swapDown</span><span class='hs-layout'>,</span> <span class='hs-varid'>swapMaster</span><span class='hs-layout'>,</span> <span class='hs-varid'>shiftMaster</span><span class='hs-layout'>,</span> <span class='hs-varid'>modify</span><span class='hs-layout'>,</span> <span class='hs-varid'>modify'</span><span class='hs-layout'>,</span> <span class='hs-varid'>float</span><span class='hs-layout'>,</span> <span class='hs-varid'>sink</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- needed by users</span>
<a name="line-46"></a>        <span class='hs-comment'>-- * Composite operations</span>
<a name="line-47"></a>        <span class='hs-comment'>-- $composite</span>
<a name="line-48"></a>        <span class='hs-varid'>shift</span><span class='hs-layout'>,</span> <span class='hs-varid'>shiftWin</span><span class='hs-layout'>,</span>
<a name="line-49"></a>
<a name="line-50"></a>        <span class='hs-comment'>-- for testing</span>
<a name="line-51"></a>        <span class='hs-varid'>abort</span>
<a name="line-52"></a>    <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-53"></a>
<a name="line-54"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-varid'>filter</span><span class='hs-layout'>)</span>
<a name="line-55"></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-varid'>listToMaybe</span><span class='hs-layout'>,</span><span class='hs-varid'>isJust</span><span class='hs-layout'>,</span><span class='hs-varid'>fromMaybe</span><span class='hs-layout'>)</span>
<a name="line-56"></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'>List</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>L</span> <span class='hs-layout'>(</span><span class='hs-varid'>deleteBy</span><span class='hs-layout'>,</span><span class='hs-varid'>find</span><span class='hs-layout'>,</span><span class='hs-varid'>splitAt</span><span class='hs-layout'>,</span><span class='hs-varid'>filter</span><span class='hs-layout'>,</span><span class='hs-varid'>nub</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>
<a name="line-58"></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> <span class='hs-layout'>(</span><span class='hs-conid'>Map</span><span class='hs-layout'>,</span><span class='hs-varid'>insert</span><span class='hs-layout'>,</span><span class='hs-varid'>delete</span><span class='hs-layout'>,</span><span class='hs-varid'>empty</span><span class='hs-layout'>)</span>
<a name="line-59"></a>
<a name="line-60"></a><span class='hs-comment'>-- $intro</span>
<a name="line-61"></a><span class='hs-comment'>--</span>
<a name="line-62"></a><span class='hs-comment'>-- The 'StackSet' data type encodes a window manager abstraction. The</span>
<a name="line-63"></a><span class='hs-comment'>-- window manager is a set of virtual workspaces. On each workspace is a</span>
<a name="line-64"></a><span class='hs-comment'>-- stack of windows. A given workspace is always current, and a given</span>
<a name="line-65"></a><span class='hs-comment'>-- window on each workspace has focus. The focused window on the current</span>
<a name="line-66"></a><span class='hs-comment'>-- workspace is the one which will take user input. It can be visualised</span>
<a name="line-67"></a><span class='hs-comment'>-- as follows:</span>
<a name="line-68"></a><span class='hs-comment'>--</span>
<a name="line-69"></a><span class='hs-comment'>-- &gt; Workspace  { 0*}   { 1 }   { 2 }   { 3 }   { 4 }</span>
<a name="line-70"></a><span class='hs-comment'>-- &gt;</span>
<a name="line-71"></a><span class='hs-comment'>-- &gt; Windows    [1      []      [3*     [6*]    []</span>
<a name="line-72"></a><span class='hs-comment'>-- &gt;            ,2*]            ,4</span>
<a name="line-73"></a><span class='hs-comment'>-- &gt;                            ,5]</span>
<a name="line-74"></a><span class='hs-comment'>--</span>
<a name="line-75"></a><span class='hs-comment'>-- Note that workspaces are indexed from 0, windows are numbered</span>
<a name="line-76"></a><span class='hs-comment'>-- uniquely. A '*' indicates the window on each workspace that has</span>
<a name="line-77"></a><span class='hs-comment'>-- focus, and which workspace is current.</span>
<a name="line-78"></a>
<a name="line-79"></a><span class='hs-comment'>-- $zipper</span>
<a name="line-80"></a><span class='hs-comment'>--</span>
<a name="line-81"></a><span class='hs-comment'>-- We encode all the focus tracking directly in the data structure, with a 'zipper':</span>
<a name="line-82"></a><span class='hs-comment'>--</span>
<a name="line-83"></a><span class='hs-comment'>--    A Zipper is essentially an `updateable' and yet pure functional</span>
<a name="line-84"></a><span class='hs-comment'>--    cursor into a data structure. Zipper is also a delimited</span>
<a name="line-85"></a><span class='hs-comment'>--    continuation reified as a data structure.</span>
<a name="line-86"></a><span class='hs-comment'>--</span>
<a name="line-87"></a><span class='hs-comment'>--    The Zipper lets us replace an item deep in a complex data</span>
<a name="line-88"></a><span class='hs-comment'>--    structure, e.g., a tree or a term, without an  mutation.  The</span>
<a name="line-89"></a><span class='hs-comment'>--    resulting data structure will share as much of its components with</span>
<a name="line-90"></a><span class='hs-comment'>--    the old structure as possible.</span>
<a name="line-91"></a><span class='hs-comment'>--</span>
<a name="line-92"></a><span class='hs-comment'>--      Oleg Kiselyov, 27 Apr 2005, haskell\@, "Zipper as a delimited continuation"</span>
<a name="line-93"></a><span class='hs-comment'>--</span>
<a name="line-94"></a><span class='hs-comment'>-- We use the zipper to keep track of the focused workspace and the</span>
<a name="line-95"></a><span class='hs-comment'>-- focused window on each workspace, allowing us to have correct focus</span>
<a name="line-96"></a><span class='hs-comment'>-- by construction. We closely follow Huet's original implementation:</span>
<a name="line-97"></a><span class='hs-comment'>--</span>
<a name="line-98"></a><span class='hs-comment'>--      G. Huet, /Functional Pearl: The Zipper/,</span>
<a name="line-99"></a><span class='hs-comment'>--      1997, J. Functional Programming 75(5):549-554.</span>
<a name="line-100"></a><span class='hs-comment'>-- and:</span>
<a name="line-101"></a><span class='hs-comment'>--      R. Hinze and J. Jeuring, /Functional Pearl: The Web/.</span>
<a name="line-102"></a><span class='hs-comment'>--</span>
<a name="line-103"></a><span class='hs-comment'>-- and Conor McBride's zipper differentiation paper.</span>
<a name="line-104"></a><span class='hs-comment'>-- Another good reference is:</span>
<a name="line-105"></a><span class='hs-comment'>--</span>
<a name="line-106"></a><span class='hs-comment'>--      The Zipper, Haskell wikibook</span>
<a name="line-107"></a>
<a name="line-108"></a><span class='hs-comment'>-- $xinerama</span>
<a name="line-109"></a><span class='hs-comment'>-- Xinerama in X11 lets us view multiple virtual workspaces</span>
<a name="line-110"></a><span class='hs-comment'>-- simultaneously. While only one will ever be in focus (i.e. will</span>
<a name="line-111"></a><span class='hs-comment'>-- receive keyboard events), other workspaces may be passively</span>
<a name="line-112"></a><span class='hs-comment'>-- viewable.  We thus need to track which virtual workspaces are</span>
<a name="line-113"></a><span class='hs-comment'>-- associated (viewed) on which physical screens.  To keep track of</span>
<a name="line-114"></a><span class='hs-comment'>-- this, 'StackSet' keeps separate lists of visible but non-focused</span>
<a name="line-115"></a><span class='hs-comment'>-- workspaces, and non-visible workspaces.</span>
<a name="line-116"></a>
<a name="line-117"></a><span class='hs-comment'>-- $focus</span>
<a name="line-118"></a><span class='hs-comment'>--</span>
<a name="line-119"></a><span class='hs-comment'>-- Each stack tracks a focused item, and for tiling purposes also tracks</span>
<a name="line-120"></a><span class='hs-comment'>-- a 'master' position. The connection between 'master' and 'focus'</span>
<a name="line-121"></a><span class='hs-comment'>-- needs to be well defined, particularly in relation to 'insert' and</span>
<a name="line-122"></a><span class='hs-comment'>-- 'delete'.</span>
<a name="line-123"></a><span class='hs-comment'>--</span>
<a name="line-124"></a>
<a name="line-125"></a><span class='hs-comment'>------------------------------------------------------------------------</span>
<a name="line-126"></a><span class='hs-comment'>-- |</span>
<a name="line-127"></a><span class='hs-comment'>-- A cursor into a non-empty list of workspaces.</span>
<a name="line-128"></a><span class='hs-comment'>--</span>
<a name="line-129"></a><span class='hs-comment'>-- We puncture the workspace list, producing a hole in the structure</span>
<a name="line-130"></a><span class='hs-comment'>-- used to track the currently focused workspace. The two other lists</span>
<a name="line-131"></a><span class='hs-comment'>-- that are produced are used to track those workspaces visible as</span>
<a name="line-132"></a><span class='hs-comment'>-- Xinerama screens, and those workspaces not visible anywhere.</span>
<a name="line-133"></a>
<a name="line-134"></a><a name="StackSet"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>sid</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>=</span>
<a name="line-135"></a>    <span class='hs-conid'>StackSet</span> <span class='hs-layout'>{</span> <span class='hs-varid'>current</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-layout'>(</span><span class='hs-conid'>Screen</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>sid</span> <span class='hs-varid'>sd</span><span class='hs-layout'>)</span>    <span class='hs-comment'>-- ^ currently focused workspace</span>
<a name="line-136"></a>             <span class='hs-layout'>,</span> <span class='hs-varid'>visible</span>  <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Screen</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>sid</span> <span class='hs-varid'>sd</span><span class='hs-keyglyph'>]</span>     <span class='hs-comment'>-- ^ non-focused workspaces, visible in xinerama</span>
<a name="line-137"></a>             <span class='hs-layout'>,</span> <span class='hs-varid'>hidden</span>   <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>         <span class='hs-comment'>-- ^ workspaces not visible anywhere</span>
<a name="line-138"></a>             <span class='hs-layout'>,</span> <span class='hs-varid'>floating</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-conid'>Map</span> <span class='hs-varid'>a</span> <span class='hs-conid'>RationalRect</span>      <span class='hs-comment'>-- ^ floating windows</span>
<a name="line-139"></a>             <span class='hs-layout'>}</span> <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Show</span><span class='hs-layout'>,</span> <span class='hs-conid'>Read</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span><span class='hs-layout'>)</span>
<a name="line-140"></a>
<a name="line-141"></a><a name="Screen"></a><span class='hs-comment'>-- | Visible workspaces, and their Xinerama screens.</span>
<a name="line-142"></a><a name="Screen"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Screen</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>sid</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Screen</span> <span class='hs-layout'>{</span> <span class='hs-varid'>workspace</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-layout'>(</span><span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-143"></a>                                  <span class='hs-layout'>,</span> <span class='hs-varid'>screen</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-varid'>sid</span>
<a name="line-144"></a>                                  <span class='hs-layout'>,</span> <span class='hs-varid'>screenDetail</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-varid'>sd</span> <span class='hs-layout'>}</span>
<a name="line-145"></a>    <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Show</span><span class='hs-layout'>,</span> <span class='hs-conid'>Read</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span><span class='hs-layout'>)</span>
<a name="line-146"></a>
<a name="line-147"></a><a name="Workspace"></a><span class='hs-comment'>-- |</span>
<a name="line-148"></a><a name="Workspace"></a><span class='hs-comment'>-- A workspace is just a tag, a layout, and a stack.</span>
<a name="line-149"></a><a name="Workspace"></a><span class='hs-comment'>--</span>
<a name="line-150"></a><a name="Workspace"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Workspace</span>  <span class='hs-layout'>{</span> <span class='hs-varid'>tag</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-varid'>i</span><span class='hs-layout'>,</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>l</span><span class='hs-layout'>,</span> <span class='hs-varid'>stack</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-151"></a>    <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Show</span><span class='hs-layout'>,</span> <span class='hs-conid'>Read</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span><span class='hs-layout'>)</span>
<a name="line-152"></a>
<a name="line-153"></a><a name="RationalRect"></a><span class='hs-comment'>-- | A structure for window geometries</span>
<a name="line-154"></a><a name="RationalRect"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>RationalRect</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RationalRect</span> <span class='hs-conid'>Rational</span> <span class='hs-conid'>Rational</span> <span class='hs-conid'>Rational</span> <span class='hs-conid'>Rational</span>
<a name="line-155"></a>    <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Show</span><span class='hs-layout'>,</span> <span class='hs-conid'>Read</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span><span class='hs-layout'>)</span>
<a name="line-156"></a>
<a name="line-157"></a><a name="Stack"></a><span class='hs-comment'>-- |</span>
<a name="line-158"></a><a name="Stack"></a><span class='hs-comment'>-- A stack is a cursor onto a window list.</span>
<a name="line-159"></a><a name="Stack"></a><span class='hs-comment'>-- The data structure tracks focus by construction, and</span>
<a name="line-160"></a><a name="Stack"></a><span class='hs-comment'>-- the master window is by convention the top-most item.</span>
<a name="line-161"></a><a name="Stack"></a><span class='hs-comment'>-- Focus operations will not reorder the list that results from</span>
<a name="line-162"></a><a name="Stack"></a><span class='hs-comment'>-- flattening the cursor. The structure can be envisaged as:</span>
<a name="line-163"></a><a name="Stack"></a><span class='hs-comment'>--</span>
<a name="line-164"></a><a name="Stack"></a><span class='hs-comment'>-- &gt;    +-- master:  &lt; '7' &gt;</span>
<a name="line-165"></a><a name="Stack"></a><span class='hs-comment'>-- &gt; up |            [ '2' ]</span>
<a name="line-166"></a><a name="Stack"></a><span class='hs-comment'>-- &gt;    +---------   [ '3' ]</span>
<a name="line-167"></a><a name="Stack"></a><span class='hs-comment'>-- &gt; focus:          &lt; '4' &gt;</span>
<a name="line-168"></a><a name="Stack"></a><span class='hs-comment'>-- &gt; dn +----------- [ '8' ]</span>
<a name="line-169"></a><a name="Stack"></a><span class='hs-comment'>--</span>
<a name="line-170"></a><a name="Stack"></a><span class='hs-comment'>-- A 'Stack' can be viewed as a list with a hole punched in it to make</span>
<a name="line-171"></a><a name="Stack"></a><span class='hs-comment'>-- the focused position. Under the zipper\/calculus view of such</span>
<a name="line-172"></a><a name="Stack"></a><span class='hs-comment'>-- structures, it is the differentiation of a [a], and integrating it</span>
<a name="line-173"></a><a name="Stack"></a><span class='hs-comment'>-- back has a natural implementation used in 'index'.</span>
<a name="line-174"></a><a name="Stack"></a><span class='hs-comment'>--</span>
<a name="line-175"></a><a name="Stack"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stack</span> <span class='hs-layout'>{</span> <span class='hs-varid'>focus</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-varid'>a</span>        <span class='hs-comment'>-- focused thing in this set</span>
<a name="line-176"></a>                     <span class='hs-layout'>,</span> <span class='hs-varid'>up</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-comment'>-- clowns to the left</span>
<a name="line-177"></a>                     <span class='hs-layout'>,</span> <span class='hs-varid'>down</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-layout'>}</span>     <span class='hs-comment'>-- jokers to the right</span>
<a name="line-178"></a>    <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Show</span><span class='hs-layout'>,</span> <span class='hs-conid'>Read</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span><span class='hs-layout'>)</span>
<a name="line-179"></a>
<a name="line-180"></a>
<a name="line-181"></a><a name="abort"></a><span class='hs-comment'>-- | this function indicates to catch that an error is expected</span>
<a name="line-182"></a><span class='hs-definition'>abort</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span>
<a name="line-183"></a><span class='hs-definition'>abort</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>error</span> <span class='hs-varop'>$</span> <span class='hs-str'>"xmonad: StackSet: "</span> <span class='hs-varop'>++</span> <span class='hs-varid'>x</span>
<a name="line-184"></a>
<a name="line-185"></a><span class='hs-comment'>-- ---------------------------------------------------------------------</span>
<a name="line-186"></a><span class='hs-comment'>-- $construction</span>
<a name="line-187"></a>
<a name="line-188"></a><a name="new"></a><span class='hs-comment'>-- | /O(n)/. Create a new stackset, of empty stacks, with given tags,</span>
<a name="line-189"></a><span class='hs-comment'>-- with physical screens whose descriptions are given by 'm'. The</span>
<a name="line-190"></a><span class='hs-comment'>-- number of physical screens (@length 'm'@) should be less than or</span>
<a name="line-191"></a><span class='hs-comment'>-- equal to the number of workspace tags.  The first workspace in the</span>
<a name="line-192"></a><span class='hs-comment'>-- list will be current.</span>
<a name="line-193"></a><span class='hs-comment'>--</span>
<a name="line-194"></a><span class='hs-comment'>-- Xinerama: Virtual workspaces are assigned to physical screens, starting at 0.</span>
<a name="line-195"></a><span class='hs-comment'>--</span>
<a name="line-196"></a><span class='hs-definition'>new</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Integral</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>l</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>i</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>sd</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-197"></a><span class='hs-definition'>new</span> <span class='hs-varid'>l</span> <span class='hs-varid'>wids</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>null</span> <span class='hs-varid'>wids</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>length</span> <span class='hs-varid'>m</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>length</span> <span class='hs-varid'>wids</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>null</span> <span class='hs-varid'>m</span><span class='hs-layout'>)</span>
<a name="line-198"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>cur</span> <span class='hs-varid'>visi</span> <span class='hs-varid'>unseen</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>empty</span>
<a name="line-199"></a>  <span class='hs-keyword'>where</span> <span class='hs-layout'>(</span><span class='hs-varid'>seen</span><span class='hs-layout'>,</span><span class='hs-varid'>unseen</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>splitAt</span> <span class='hs-layout'>(</span><span class='hs-varid'>length</span> <span class='hs-varid'>m</span><span class='hs-layout'>)</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'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-varid'>wids</span>
<a name="line-200"></a>        <span class='hs-layout'>(</span><span class='hs-varid'>cur</span><span class='hs-conop'>:</span><span class='hs-varid'>visi</span><span class='hs-layout'>)</span>    <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span> <span class='hs-conid'>Screen</span> <span class='hs-varid'>i</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>|</span>  <span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-layout'>,</span> <span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-varid'>sd</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>zip3</span> <span class='hs-varid'>seen</span> <span class='hs-keyglyph'>[</span><span class='hs-num'>0</span><span class='hs-keyglyph'>..</span><span class='hs-keyglyph'>]</span> <span class='hs-varid'>m</span> <span class='hs-keyglyph'>]</span>
<a name="line-201"></a>                <span class='hs-comment'>-- now zip up visibles with their screen id</span>
<a name="line-202"></a><span class='hs-definition'>new</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>abort</span> <span class='hs-str'>"non-positive argument to StackSet.new"</span>
<a name="line-203"></a>
<a name="line-204"></a><span class='hs-comment'>-- |</span>
<a name="line-205"></a><span class='hs-comment'>-- /O(w)/. Set focus to the workspace with index \'i\'.</span>
<a name="line-206"></a><span class='hs-comment'>-- If the index is out of range, return the original 'StackSet'.</span>
<a name="line-207"></a><span class='hs-comment'>--</span>
<a name="line-208"></a><span class='hs-comment'>-- Xinerama: If the workspace is not visible on any Xinerama screen, it</span>
<a name="line-209"></a><span class='hs-comment'>-- becomes the current screen. If it is in the visible list, it becomes</span>
<a name="line-210"></a><span class='hs-comment'>-- current.</span>
<a name="line-211"></a>
<a name="line-212"></a><a name="view"></a><span class='hs-definition'>view</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span> <span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>i</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-213"></a><span class='hs-definition'>view</span> <span class='hs-varid'>i</span> <span class='hs-varid'>s</span>
<a name="line-214"></a>    <span class='hs-keyglyph'>|</span> <span class='hs-varid'>i</span> <span class='hs-varop'>==</span> <span class='hs-varid'>currentTag</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span>  <span class='hs-comment'>-- current</span>
<a name="line-215"></a>
<a name="line-216"></a>    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>find</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-varop'>==</span><span class='hs-layout'>)</span><span class='hs-varop'>.</span><span class='hs-varid'>tag</span><span class='hs-varop'>.</span><span class='hs-varid'>workspace</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>visible</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-217"></a>    <span class='hs-comment'>-- if it is visible, it is just raised</span>
<a name="line-218"></a>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-layout'>{</span> <span class='hs-varid'>current</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x</span><span class='hs-layout'>,</span> <span class='hs-varid'>visible</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>current</span> <span class='hs-varid'>s</span> <span class='hs-conop'>:</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>deleteBy</span> <span class='hs-layout'>(</span><span class='hs-varid'>equating</span> <span class='hs-varid'>screen</span><span class='hs-layout'>)</span> <span class='hs-varid'>x</span> <span class='hs-layout'>(</span><span class='hs-varid'>visible</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-219"></a>
<a name="line-220"></a>    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>find</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-varop'>==</span><span class='hs-layout'>)</span><span class='hs-varop'>.</span><span class='hs-varid'>tag</span><span class='hs-layout'>)</span>           <span class='hs-layout'>(</span><span class='hs-varid'>hidden</span>  <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-comment'>-- must be hidden then</span>
<a name="line-221"></a>    <span class='hs-comment'>-- if it was hidden, it is raised on the xine screen currently used</span>
<a name="line-222"></a>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-layout'>{</span> <span class='hs-varid'>current</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>current</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>{</span> <span class='hs-varid'>workspace</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x</span> <span class='hs-layout'>}</span>
<a name="line-223"></a>        <span class='hs-layout'>,</span> <span class='hs-varid'>hidden</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>workspace</span> <span class='hs-layout'>(</span><span class='hs-varid'>current</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-conop'>:</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>deleteBy</span> <span class='hs-layout'>(</span><span class='hs-varid'>equating</span> <span class='hs-varid'>tag</span><span class='hs-layout'>)</span> <span class='hs-varid'>x</span> <span class='hs-layout'>(</span><span class='hs-varid'>hidden</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-224"></a>
<a name="line-225"></a>    <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-comment'>-- not a member of the stackset</span>
<a name="line-226"></a>
<a name="line-227"></a>  <span class='hs-keyword'>where</span> <span class='hs-varid'>equating</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>f</span> <span class='hs-varid'>x</span> <span class='hs-varop'>==</span> <span class='hs-varid'>f</span> <span class='hs-varid'>y</span>
<a name="line-228"></a>
<a name="line-229"></a>    <span class='hs-comment'>-- 'Catch'ing this might be hard. Relies on monotonically increasing</span>
<a name="line-230"></a>    <span class='hs-comment'>-- workspace tags defined in 'new'</span>
<a name="line-231"></a>    <span class='hs-comment'>--</span>
<a name="line-232"></a>    <span class='hs-comment'>-- and now tags are not monotonic, what happens here?</span>
<a name="line-233"></a>
<a name="line-234"></a><span class='hs-comment'>-- |</span>
<a name="line-235"></a><span class='hs-comment'>-- Set focus to the given workspace.  If that workspace does not exist</span>
<a name="line-236"></a><span class='hs-comment'>-- in the stackset, the original workspace is returned.  If that workspace is</span>
<a name="line-237"></a><span class='hs-comment'>-- 'hidden', then display that workspace on the current screen, and move the</span>
<a name="line-238"></a><span class='hs-comment'>-- current workspace to 'hidden'.  If that workspace is 'visible' on another</span>
<a name="line-239"></a><span class='hs-comment'>-- screen, the workspaces of the current screen and the other screen are</span>
<a name="line-240"></a><span class='hs-comment'>-- swapped.</span>
<a name="line-241"></a>
<a name="line-242"></a><a name="greedyView"></a><span class='hs-definition'>greedyView</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span> <span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>i</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-243"></a><span class='hs-definition'>greedyView</span> <span class='hs-varid'>w</span> <span class='hs-varid'>ws</span>
<a name="line-244"></a>     <span class='hs-keyglyph'>|</span> <span class='hs-varid'>any</span> <span class='hs-varid'>wTag</span> <span class='hs-layout'>(</span><span class='hs-varid'>hidden</span> <span class='hs-varid'>ws</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>view</span> <span class='hs-varid'>w</span> <span class='hs-varid'>ws</span>
<a name="line-245"></a>     <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'>&lt;-</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>find</span> <span class='hs-layout'>(</span><span class='hs-varid'>wTag</span> <span class='hs-varop'>.</span> <span class='hs-varid'>workspace</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>visible</span> <span class='hs-varid'>ws</span><span class='hs-layout'>)</span>
<a name="line-246"></a>                            <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ws</span> <span class='hs-layout'>{</span> <span class='hs-varid'>current</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>current</span> <span class='hs-varid'>ws</span><span class='hs-layout'>)</span> <span class='hs-layout'>{</span> <span class='hs-varid'>workspace</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>workspace</span> <span class='hs-varid'>s</span> <span class='hs-layout'>}</span>
<a name="line-247"></a>                                 <span class='hs-layout'>,</span> <span class='hs-varid'>visible</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-layout'>{</span> <span class='hs-varid'>workspace</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>workspace</span> <span class='hs-layout'>(</span><span class='hs-varid'>current</span> <span class='hs-varid'>ws</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-248"></a>                                           <span class='hs-conop'>:</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varid'>not</span> <span class='hs-varop'>.</span> <span class='hs-varid'>wTag</span> <span class='hs-varop'>.</span> <span class='hs-varid'>workspace</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>visible</span> <span class='hs-varid'>ws</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-249"></a>     <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ws</span>
<a name="line-250"></a>   <span class='hs-keyword'>where</span> <span class='hs-varid'>wTag</span> <span class='hs-keyglyph'>=</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-varid'>tag</span>
<a name="line-251"></a>
<a name="line-252"></a><span class='hs-comment'>-- ---------------------------------------------------------------------</span>
<a name="line-253"></a><span class='hs-comment'>-- $xinerama</span>
<a name="line-254"></a>
<a name="line-255"></a><a name="lookupWorkspace"></a><span class='hs-comment'>-- | Find the tag of the workspace visible on Xinerama screen 'sc'.</span>
<a name="line-256"></a><span class='hs-comment'>-- 'Nothing' if screen is out of bounds.</span>
<a name="line-257"></a><span class='hs-definition'>lookupWorkspace</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>i</span>
<a name="line-258"></a><span class='hs-definition'>lookupWorkspace</span> <span class='hs-varid'>sc</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>listToMaybe</span> <span class='hs-keyglyph'>[</span> <span class='hs-varid'>tag</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Screen</span> <span class='hs-varid'>i</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>current</span> <span class='hs-varid'>w</span> <span class='hs-conop'>:</span> <span class='hs-varid'>visible</span> <span class='hs-varid'>w</span><span class='hs-layout'>,</span> <span class='hs-varid'>s</span> <span class='hs-varop'>==</span> <span class='hs-varid'>sc</span> <span class='hs-keyglyph'>]</span>
<a name="line-259"></a>
<a name="line-260"></a><span class='hs-comment'>-- ---------------------------------------------------------------------</span>
<a name="line-261"></a><span class='hs-comment'>-- $stackOperations</span>
<a name="line-262"></a>
<a name="line-263"></a><a name="with"></a><span class='hs-comment'>-- |</span>
<a name="line-264"></a><span class='hs-comment'>-- The 'with' function takes a default value, a function, and a</span>
<a name="line-265"></a><span class='hs-comment'>-- StackSet. If the current stack is Nothing, 'with' returns the</span>
<a name="line-266"></a><span class='hs-comment'>-- default value. Otherwise, it applies the function to the stack,</span>
<a name="line-267"></a><span class='hs-comment'>-- returning the result. It is like 'maybe' for the focused workspace.</span>
<a name="line-268"></a><span class='hs-comment'>--</span>
<a name="line-269"></a><span class='hs-definition'>with</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>b</span>
<a name="line-270"></a><span class='hs-definition'>with</span> <span class='hs-varid'>dflt</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>maybe</span> <span class='hs-varid'>dflt</span> <span class='hs-varid'>f</span> <span class='hs-varop'>.</span> <span class='hs-varid'>stack</span> <span class='hs-varop'>.</span> <span class='hs-varid'>workspace</span> <span class='hs-varop'>.</span> <span class='hs-varid'>current</span>
<a name="line-271"></a>
<a name="line-272"></a><a name="modify"></a><span class='hs-comment'>-- |</span>
<a name="line-273"></a><span class='hs-comment'>-- Apply a function, and a default value for 'Nothing', to modify the current stack.</span>
<a name="line-274"></a><span class='hs-comment'>--</span>
<a name="line-275"></a><span class='hs-definition'>modify</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</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-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-276"></a><span class='hs-definition'>modify</span> <span class='hs-varid'>d</span> <span class='hs-varid'>f</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'>current</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>current</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-277"></a>                        <span class='hs-layout'>{</span> <span class='hs-varid'>workspace</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>workspace</span> <span class='hs-layout'>(</span><span class='hs-varid'>current</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>{</span> <span class='hs-varid'>stack</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>with</span> <span class='hs-varid'>d</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-layout'>}</span><span class='hs-layout'>}</span><span class='hs-layout'>}</span>
<a name="line-278"></a>
<a name="line-279"></a><a name="modify'"></a><span class='hs-comment'>-- |</span>
<a name="line-280"></a><span class='hs-comment'>-- Apply a function to modify the current stack if it isn't empty, and we don't</span>
<a name="line-281"></a><span class='hs-comment'>--  want to empty it.</span>
<a name="line-282"></a><span class='hs-comment'>--</span>
<a name="line-283"></a><span class='hs-definition'>modify'</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-284"></a><span class='hs-definition'>modify'</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify</span> <span class='hs-conid'>Nothing</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span>
<a name="line-285"></a>
<a name="line-286"></a><a name="peek"></a><span class='hs-comment'>-- |</span>
<a name="line-287"></a><span class='hs-comment'>-- /O(1)/. Extract the focused element of the current stack.</span>
<a name="line-288"></a><span class='hs-comment'>-- Return 'Just' that element, or 'Nothing' for an empty stack.</span>
<a name="line-289"></a><span class='hs-comment'>--</span>
<a name="line-290"></a><span class='hs-definition'>peek</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span>
<a name="line-291"></a><span class='hs-definition'>peek</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>with</span> <span class='hs-conid'>Nothing</span> <span class='hs-layout'>(</span><span class='hs-varid'>return</span> <span class='hs-varop'>.</span> <span class='hs-varid'>focus</span><span class='hs-layout'>)</span>
<a name="line-292"></a>
<a name="line-293"></a><a name="integrate"></a><span class='hs-comment'>-- |</span>
<a name="line-294"></a><span class='hs-comment'>-- /O(n)/. Flatten a 'Stack' into a list.</span>
<a name="line-295"></a><span class='hs-comment'>--</span>
<a name="line-296"></a><span class='hs-definition'>integrate</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>
<a name="line-297"></a><span class='hs-definition'>integrate</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>x</span> <span class='hs-varid'>l</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>reverse</span> <span class='hs-varid'>l</span> <span class='hs-varop'>++</span> <span class='hs-varid'>x</span> <span class='hs-conop'>:</span> <span class='hs-varid'>r</span>
<a name="line-298"></a>
<a name="line-299"></a><a name="integrate'"></a><span class='hs-comment'>-- |</span>
<a name="line-300"></a><span class='hs-comment'>-- /O(n)/ Flatten a possibly empty stack into a list.</span>
<a name="line-301"></a><span class='hs-definition'>integrate'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>
<a name="line-302"></a><span class='hs-definition'>integrate'</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>maybe</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>integrate</span>
<a name="line-303"></a>
<a name="line-304"></a><a name="differentiate"></a><span class='hs-comment'>-- |</span>
<a name="line-305"></a><span class='hs-comment'>-- /O(n)/. Turn a list into a possibly empty stack (i.e., a zipper):</span>
<a name="line-306"></a><span class='hs-comment'>-- the first element of the list is current, and the rest of the list</span>
<a name="line-307"></a><span class='hs-comment'>-- is down.</span>
<a name="line-308"></a><span class='hs-definition'>differentiate</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'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-309"></a><span class='hs-definition'>differentiate</span> <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-310"></a><span class='hs-definition'>differentiate</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</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-varid'>xs</span>
<a name="line-311"></a>
<a name="line-312"></a><a name="filter"></a><span class='hs-comment'>-- |</span>
<a name="line-313"></a><span class='hs-comment'>-- /O(n)/. 'filter p s' returns the elements of 's' such that 'p' evaluates to</span>
<a name="line-314"></a><span class='hs-comment'>-- 'True'.  Order is preserved, and focus moves as described for 'delete'.</span>
<a name="line-315"></a><span class='hs-comment'>--</span>
<a name="line-316"></a><span class='hs-definition'>filter</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-317"></a><span class='hs-definition'>filter</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>f</span> <span class='hs-varid'>ls</span> <span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span><span class='hs-conop'>:</span><span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span>
<a name="line-318"></a>    <span class='hs-varid'>f'</span><span class='hs-conop'>:</span><span class='hs-varid'>rs'</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>f'</span> <span class='hs-layout'>(</span><span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ls</span><span class='hs-layout'>)</span> <span class='hs-varid'>rs'</span>    <span class='hs-comment'>-- maybe move focus down</span>
<a name="line-319"></a>    <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>case</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>filter</span> <span class='hs-varid'>p</span> <span class='hs-varid'>ls</span> <span class='hs-keyword'>of</span>                  <span class='hs-comment'>-- filter back up</span>
<a name="line-320"></a>                    <span class='hs-varid'>f'</span><span class='hs-conop'>:</span><span class='hs-varid'>ls'</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>f'</span> <span class='hs-varid'>ls'</span> <span class='hs-conid'>[]</span> <span class='hs-comment'>-- else up</span>
<a name="line-321"></a>                    <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nothing</span>
<a name="line-322"></a>
<a name="line-323"></a><a name="index"></a><span class='hs-comment'>-- |</span>
<a name="line-324"></a><span class='hs-comment'>-- /O(s)/. Extract the stack on the current workspace, as a list.</span>
<a name="line-325"></a><span class='hs-comment'>-- The order of the stack is determined by the master window -- it will be</span>
<a name="line-326"></a><span class='hs-comment'>-- the head of the list. The implementation is given by the natural</span>
<a name="line-327"></a><span class='hs-comment'>-- integration of a one-hole list cursor, back to a list.</span>
<a name="line-328"></a><span class='hs-comment'>--</span>
<a name="line-329"></a><span class='hs-definition'>index</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>
<a name="line-330"></a><span class='hs-definition'>index</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>with</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>integrate</span>
<a name="line-331"></a>
<a name="line-332"></a><a name="focusUp"></a><span class='hs-comment'>-- |</span>
<a name="line-333"></a><span class='hs-comment'>-- /O(1), O(w) on the wrapping case/.</span>
<a name="line-334"></a><span class='hs-comment'>--</span>
<a name="line-335"></a><span class='hs-comment'>-- focusUp, focusDown. Move the window focus up or down the stack,</span>
<a name="line-336"></a><span class='hs-comment'>-- wrapping if we reach the end. The wrapping should model a 'cycle'</span>
<a name="line-337"></a><span class='hs-comment'>-- on the current stack. The 'master' window, and window order,</span>
<a name="line-338"></a><span class='hs-comment'>-- are unaffected by movement of focus.</span>
<a name="line-339"></a><span class='hs-comment'>--</span>
<a name="line-340"></a><span class='hs-comment'>-- swapUp, swapDown, swap the neighbour in the stack ordering, wrapping</span>
<a name="line-341"></a><span class='hs-comment'>-- if we reach the end. Again the wrapping model should 'cycle' on</span>
<a name="line-342"></a><span class='hs-comment'>-- the current stack.</span>
<a name="line-343"></a><span class='hs-comment'>--</span>
<a name="line-344"></a><span class='hs-definition'>focusUp</span><span class='hs-layout'>,</span> <span class='hs-varid'>focusDown</span><span class='hs-layout'>,</span> <span class='hs-varid'>swapUp</span><span class='hs-layout'>,</span> <span class='hs-varid'>swapDown</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-345"></a><span class='hs-definition'>focusUp</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify'</span> <span class='hs-varid'>focusUp'</span>
<a name="line-346"></a><a name="focusDown"></a><span class='hs-definition'>focusDown</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify'</span> <span class='hs-varid'>focusDown'</span>
<a name="line-347"></a>
<a name="line-348"></a><a name="swapUp"></a><span class='hs-definition'>swapUp</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify'</span> <span class='hs-varid'>swapUp'</span>
<a name="line-349"></a><a name="swapDown"></a><span class='hs-definition'>swapDown</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify'</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverseStack</span> <span class='hs-varop'>.</span> <span class='hs-varid'>swapUp'</span> <span class='hs-varop'>.</span> <span class='hs-varid'>reverseStack</span><span class='hs-layout'>)</span>
<a name="line-350"></a>
<a name="line-351"></a><a name="focusUp'"></a><span class='hs-comment'>-- | Variants of 'focusUp' and 'focusDown' that work on a</span>
<a name="line-352"></a><span class='hs-comment'>-- 'Stack' rather than an entire 'StackSet'.</span>
<a name="line-353"></a><span class='hs-definition'>focusUp'</span><span class='hs-layout'>,</span> <span class='hs-varid'>focusDown'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span>
<a name="line-354"></a><span class='hs-definition'>focusUp'</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span><span class='hs-conop'>:</span><span class='hs-varid'>ls</span><span class='hs-layout'>)</span> <span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>l</span> <span class='hs-varid'>ls</span> <span class='hs-layout'>(</span><span class='hs-varid'>t</span><span class='hs-conop'>:</span><span class='hs-varid'>rs</span><span class='hs-layout'>)</span>
<a name="line-355"></a><span class='hs-definition'>focusUp'</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-conid'>[]</span>     <span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>x</span> <span class='hs-varid'>xs</span> <span class='hs-conid'>[]</span> <span class='hs-keyword'>where</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>reverse</span> <span class='hs-layout'>(</span><span class='hs-varid'>t</span><span class='hs-conop'>:</span><span class='hs-varid'>rs</span><span class='hs-layout'>)</span>
<a name="line-356"></a><a name="focusDown'"></a><span class='hs-definition'>focusDown'</span>                   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>reverseStack</span> <span class='hs-varop'>.</span> <span class='hs-varid'>focusUp'</span> <span class='hs-varop'>.</span> <span class='hs-varid'>reverseStack</span>
<a name="line-357"></a>
<a name="line-358"></a><a name="swapUp'"></a><span class='hs-definition'>swapUp'</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span>
<a name="line-359"></a><span class='hs-definition'>swapUp'</span>  <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span><span class='hs-conop'>:</span><span class='hs-varid'>ls</span><span class='hs-layout'>)</span> <span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-varid'>ls</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span><span class='hs-conop'>:</span><span class='hs-varid'>rs</span><span class='hs-layout'>)</span>
<a name="line-360"></a><span class='hs-definition'>swapUp'</span>  <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-conid'>[]</span>     <span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverse</span> <span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span>
<a name="line-361"></a>
<a name="line-362"></a><a name="reverseStack"></a><span class='hs-comment'>-- | reverse a stack: up becomes down and down becomes up.</span>
<a name="line-363"></a><span class='hs-definition'>reverseStack</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span>
<a name="line-364"></a><span class='hs-definition'>reverseStack</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-varid'>ls</span> <span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-varid'>rs</span> <span class='hs-varid'>ls</span>
<a name="line-365"></a>
<a name="line-366"></a><a name="focusWindow"></a><span class='hs-comment'>--</span>
<a name="line-367"></a><span class='hs-comment'>-- | /O(1) on current window, O(n) in general/. Focus the window 'w',</span>
<a name="line-368"></a><span class='hs-comment'>-- and set its workspace as current.</span>
<a name="line-369"></a><span class='hs-comment'>--</span>
<a name="line-370"></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'>s</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'>Eq</span> <span class='hs-varid'>i</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-371"></a><span class='hs-definition'>focusWindow</span> <span class='hs-varid'>w</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>w</span> <span class='hs-varop'>==</span> <span class='hs-varid'>peek</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span>
<a name="line-372"></a>                <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromMaybe</span> <span class='hs-varid'>s</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span>
<a name="line-373"></a>                    <span class='hs-varid'>n</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>findTag</span> <span class='hs-varid'>w</span> <span class='hs-varid'>s</span>
<a name="line-374"></a>                    <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>until</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-conid'>Just</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-varid'>peek</span><span class='hs-layout'>)</span> <span class='hs-varid'>focusUp</span> <span class='hs-layout'>(</span><span class='hs-varid'>view</span> <span class='hs-varid'>n</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-375"></a>
<a name="line-376"></a><a name="screens"></a><span class='hs-comment'>-- | Get a list of all screens in the 'StackSet'.</span>
<a name="line-377"></a><span class='hs-definition'>screens</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Screen</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span><span class='hs-keyglyph'>]</span>
<a name="line-378"></a><span class='hs-definition'>screens</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>current</span> <span class='hs-varid'>s</span> <span class='hs-conop'>:</span> <span class='hs-varid'>visible</span> <span class='hs-varid'>s</span>
<a name="line-379"></a>
<a name="line-380"></a><a name="workspaces"></a><span class='hs-comment'>-- | Get a list of all workspaces in the 'StackSet'.</span>
<a name="line-381"></a><span class='hs-definition'>workspaces</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>
<a name="line-382"></a><span class='hs-definition'>workspaces</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>workspace</span> <span class='hs-layout'>(</span><span class='hs-varid'>current</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-conop'>:</span> <span class='hs-varid'>map</span> <span class='hs-varid'>workspace</span> <span class='hs-layout'>(</span><span class='hs-varid'>visible</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-varop'>++</span> <span class='hs-varid'>hidden</span> <span class='hs-varid'>s</span>
<a name="line-383"></a>
<a name="line-384"></a><a name="allWindows"></a><span class='hs-comment'>-- | Get a list of all windows in the 'StackSet' in no particular order</span>
<a name="line-385"></a><span class='hs-definition'>allWindows</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span>
<a name="line-386"></a><span class='hs-definition'>allWindows</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>nub</span> <span class='hs-varop'>.</span> <span class='hs-varid'>concatMap</span> <span class='hs-layout'>(</span><span class='hs-varid'>integrate'</span> <span class='hs-varop'>.</span> <span class='hs-varid'>stack</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>workspaces</span>
<a name="line-387"></a>
<a name="line-388"></a><a name="currentTag"></a><span class='hs-comment'>-- | Get the tag of the currently focused workspace.</span>
<a name="line-389"></a><span class='hs-definition'>currentTag</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>i</span>
<a name="line-390"></a><span class='hs-definition'>currentTag</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tag</span> <span class='hs-varop'>.</span> <span class='hs-varid'>workspace</span> <span class='hs-varop'>.</span> <span class='hs-varid'>current</span>
<a name="line-391"></a>
<a name="line-392"></a><a name="tagMember"></a><span class='hs-comment'>-- | Is the given tag present in the 'StackSet'?</span>
<a name="line-393"></a><span class='hs-definition'>tagMember</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-394"></a><span class='hs-definition'>tagMember</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>elem</span> <span class='hs-varid'>t</span> <span class='hs-varop'>.</span> <span class='hs-varid'>map</span> <span class='hs-varid'>tag</span> <span class='hs-varop'>.</span> <span class='hs-varid'>workspaces</span>
<a name="line-395"></a>
<a name="line-396"></a><a name="renameTag"></a><span class='hs-comment'>-- | Rename a given tag if present in the 'StackSet'.</span>
<a name="line-397"></a><span class='hs-definition'>renameTag</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-398"></a><span class='hs-definition'>renameTag</span> <span class='hs-varid'>o</span> <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mapWorkspace</span> <span class='hs-varid'>rename</span>
<a name="line-399"></a>    <span class='hs-keyword'>where</span> <span class='hs-varid'>rename</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>tag</span> <span class='hs-varid'>w</span> <span class='hs-varop'>==</span> <span class='hs-varid'>o</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>w</span> <span class='hs-layout'>{</span> <span class='hs-varid'>tag</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>n</span> <span class='hs-layout'>}</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>w</span>
<a name="line-400"></a>
<a name="line-401"></a><a name="ensureTags"></a><span class='hs-comment'>-- | Ensure that a given set of workspace tags is present by renaming</span>
<a name="line-402"></a><span class='hs-comment'>-- existing workspaces and\/or creating new hidden workspaces as</span>
<a name="line-403"></a><span class='hs-comment'>-- necessary.</span>
<a name="line-404"></a><span class='hs-definition'>ensureTags</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>l</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>i</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-405"></a><span class='hs-definition'>ensureTags</span> <span class='hs-varid'>l</span> <span class='hs-varid'>allt</span> <span class='hs-varid'>st</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>et</span> <span class='hs-varid'>allt</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>tag</span> <span class='hs-layout'>(</span><span class='hs-varid'>workspaces</span> <span class='hs-varid'>st</span><span class='hs-layout'>)</span> <span class='hs-varop'>\\</span> <span class='hs-varid'>allt</span><span class='hs-layout'>)</span> <span class='hs-varid'>st</span>
<a name="line-406"></a>    <span class='hs-keyword'>where</span> <span class='hs-varid'>et</span> <span class='hs-conid'>[]</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span>
<a name="line-407"></a>          <span class='hs-varid'>et</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-conop'>:</span><span class='hs-varid'>is</span><span class='hs-layout'>)</span> <span class='hs-varid'>rn</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>i</span> <span class='hs-varop'>`tagMember`</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>et</span> <span class='hs-varid'>is</span> <span class='hs-varid'>rn</span> <span class='hs-varid'>s</span>
<a name="line-408"></a>          <span class='hs-varid'>et</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-conop'>:</span><span class='hs-varid'>is</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>et</span> <span class='hs-varid'>is</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>s</span> <span class='hs-layout'>{</span> <span class='hs-varid'>hidden</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-conid'>Nothing</span> <span class='hs-conop'>:</span> <span class='hs-varid'>hidden</span> <span class='hs-varid'>s</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-409"></a>          <span class='hs-varid'>et</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span><span class='hs-conop'>:</span><span class='hs-varid'>is</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>r</span><span class='hs-conop'>:</span><span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>et</span> <span class='hs-varid'>is</span> <span class='hs-varid'>rs</span> <span class='hs-varop'>$</span> <span class='hs-varid'>renameTag</span> <span class='hs-varid'>r</span> <span class='hs-varid'>i</span> <span class='hs-varid'>s</span>
<a name="line-410"></a>
<a name="line-411"></a><a name="mapWorkspace"></a><span class='hs-comment'>-- | Map a function on all the workspaces in the 'StackSet'.</span>
<a name="line-412"></a><span class='hs-definition'>mapWorkspace</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Workspace</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-413"></a><span class='hs-definition'>mapWorkspace</span> <span class='hs-varid'>f</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'>current</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>updScr</span> <span class='hs-layout'>(</span><span class='hs-varid'>current</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-414"></a>                     <span class='hs-layout'>,</span> <span class='hs-varid'>visible</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-varid'>updScr</span> <span class='hs-layout'>(</span><span class='hs-varid'>visible</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-415"></a>                     <span class='hs-layout'>,</span> <span class='hs-varid'>hidden</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-varid'>f</span> <span class='hs-layout'>(</span><span class='hs-varid'>hidden</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-416"></a>    <span class='hs-keyword'>where</span> <span class='hs-varid'>updScr</span> <span class='hs-varid'>scr</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>scr</span> <span class='hs-layout'>{</span> <span class='hs-varid'>workspace</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>f</span> <span class='hs-layout'>(</span><span class='hs-varid'>workspace</span> <span class='hs-varid'>scr</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-417"></a>
<a name="line-418"></a><a name="mapLayout"></a><span class='hs-comment'>-- | Map a function on all the layouts in the 'StackSet'.</span>
<a name="line-419"></a><span class='hs-definition'>mapLayout</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>l'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l'</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-420"></a><span class='hs-definition'>mapLayout</span> <span class='hs-varid'>f</span> <span class='hs-layout'>(</span><span class='hs-conid'>StackSet</span> <span class='hs-varid'>v</span> <span class='hs-varid'>vs</span> <span class='hs-varid'>hs</span> <span class='hs-varid'>m</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>StackSet</span> <span class='hs-layout'>(</span><span class='hs-varid'>fScreen</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>fScreen</span> <span class='hs-varid'>vs</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>fWorkspace</span> <span class='hs-varid'>hs</span><span class='hs-layout'>)</span> <span class='hs-varid'>m</span>
<a name="line-421"></a> <span class='hs-keyword'>where</span>
<a name="line-422"></a>    <span class='hs-varid'>fScreen</span> <span class='hs-layout'>(</span><span class='hs-conid'>Screen</span> <span class='hs-varid'>ws</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Screen</span> <span class='hs-layout'>(</span><span class='hs-varid'>fWorkspace</span> <span class='hs-varid'>ws</span><span class='hs-layout'>)</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-423"></a>    <span class='hs-varid'>fWorkspace</span> <span class='hs-layout'>(</span><span class='hs-conid'>Workspace</span> <span class='hs-varid'>t</span> <span class='hs-varid'>l</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Workspace</span> <span class='hs-varid'>t</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-varid'>s</span>
<a name="line-424"></a>
<a name="line-425"></a><a name="member"></a><span class='hs-comment'>-- | /O(n)/. Is a window in the 'StackSet'?</span>
<a name="line-426"></a><span class='hs-definition'>member</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-427"></a><span class='hs-definition'>member</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isJust</span> <span class='hs-layout'>(</span><span class='hs-varid'>findTag</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-428"></a>
<a name="line-429"></a><a name="findTag"></a><span class='hs-comment'>-- | /O(1) on current window, O(n) in general/.</span>
<a name="line-430"></a><span class='hs-comment'>-- Return 'Just' the workspace tag of the given window, or 'Nothing'</span>
<a name="line-431"></a><span class='hs-comment'>-- if the window is not in the 'StackSet'.</span>
<a name="line-432"></a><span class='hs-definition'>findTag</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>i</span>
<a name="line-433"></a><span class='hs-definition'>findTag</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>listToMaybe</span>
<a name="line-434"></a>    <span class='hs-keyglyph'>[</span> <span class='hs-varid'>tag</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>workspaces</span> <span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-varid'>has</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-varid'>stack</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>]</span>
<a name="line-435"></a>    <span class='hs-keyword'>where</span> <span class='hs-varid'>has</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Nothing</span>         <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-436"></a>          <span class='hs-varid'>has</span> <span class='hs-varid'>x</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-varid'>l</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x</span> <span class='hs-varop'>`elem`</span> <span class='hs-layout'>(</span><span class='hs-varid'>t</span> <span class='hs-conop'>:</span> <span class='hs-varid'>l</span> <span class='hs-varop'>++</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span>
<a name="line-437"></a>
<a name="line-438"></a><span class='hs-comment'>-- ---------------------------------------------------------------------</span>
<a name="line-439"></a><span class='hs-comment'>-- $modifyStackset</span>
<a name="line-440"></a>
<a name="line-441"></a><a name="insertUp"></a><span class='hs-comment'>-- |</span>
<a name="line-442"></a><span class='hs-comment'>-- /O(n)/. (Complexity due to duplicate check). Insert a new element</span>
<a name="line-443"></a><span class='hs-comment'>-- into the stack, above the currently focused element. The new</span>
<a name="line-444"></a><span class='hs-comment'>-- element is given focus; the previously focused element is moved</span>
<a name="line-445"></a><span class='hs-comment'>-- down.</span>
<a name="line-446"></a><span class='hs-comment'>--</span>
<a name="line-447"></a><span class='hs-comment'>-- If the element is already in the stackset, the original stackset is</span>
<a name="line-448"></a><span class='hs-comment'>-- returned unmodified.</span>
<a name="line-449"></a><span class='hs-comment'>--</span>
<a name="line-450"></a><span class='hs-comment'>-- Semantics in Huet's paper is that insert doesn't move the cursor.</span>
<a name="line-451"></a><span class='hs-comment'>-- However, we choose to insert above, and move the focus.</span>
<a name="line-452"></a><span class='hs-comment'>--</span>
<a name="line-453"></a><span class='hs-definition'>insertUp</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-454"></a><span class='hs-definition'>insertUp</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>member</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>insert</span>
<a name="line-455"></a>  <span class='hs-keyword'>where</span> <span class='hs-varid'>insert</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-conid'>[]</span> <span class='hs-conid'>[]</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-layout'>(</span><span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-varid'>l</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>a</span> <span class='hs-varid'>l</span> <span class='hs-layout'>(</span><span class='hs-varid'>t</span><span class='hs-conop'>:</span><span class='hs-varid'>r</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>s</span>
<a name="line-456"></a>
<a name="line-457"></a><span class='hs-comment'>-- insertDown :: a -&gt; StackSet i l a s sd -&gt; StackSet i l a s sd</span>
<a name="line-458"></a><span class='hs-comment'>-- insertDown a = modify (Stack a [] []) $ \(Stack t l r) -&gt; Stack a (t:l) r</span>
<a name="line-459"></a><span class='hs-comment'>-- Old semantics, from Huet.</span>
<a name="line-460"></a><span class='hs-comment'>-- &gt;    w { down = a : down w }</span>
<a name="line-461"></a>
<a name="line-462"></a><a name="delete"></a><span class='hs-comment'>-- |</span>
<a name="line-463"></a><span class='hs-comment'>-- /O(1) on current window, O(n) in general/. Delete window 'w' if it exists.</span>
<a name="line-464"></a><span class='hs-comment'>-- There are 4 cases to consider:</span>
<a name="line-465"></a><span class='hs-comment'>--</span>
<a name="line-466"></a><span class='hs-comment'>--   * delete on an 'Nothing' workspace leaves it Nothing</span>
<a name="line-467"></a><span class='hs-comment'>--</span>
<a name="line-468"></a><span class='hs-comment'>--   * otherwise, try to move focus to the down</span>
<a name="line-469"></a><span class='hs-comment'>--</span>
<a name="line-470"></a><span class='hs-comment'>--   * otherwise, try to move focus to the up</span>
<a name="line-471"></a><span class='hs-comment'>--</span>
<a name="line-472"></a><span class='hs-comment'>--   * otherwise, you've got an empty workspace, becomes 'Nothing'</span>
<a name="line-473"></a><span class='hs-comment'>--</span>
<a name="line-474"></a><span class='hs-comment'>-- Behaviour with respect to the master:</span>
<a name="line-475"></a><span class='hs-comment'>--</span>
<a name="line-476"></a><span class='hs-comment'>--   * deleting the master window resets it to the newly focused window</span>
<a name="line-477"></a><span class='hs-comment'>--</span>
<a name="line-478"></a><span class='hs-comment'>--   * otherwise, delete doesn't affect the master.</span>
<a name="line-479"></a><span class='hs-comment'>--</span>
<a name="line-480"></a><span class='hs-definition'>delete</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-conid'>Eq</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-481"></a><span class='hs-definition'>delete</span> <span class='hs-varid'>w</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sink</span> <span class='hs-varid'>w</span> <span class='hs-varop'>.</span> <span class='hs-varid'>delete'</span> <span class='hs-varid'>w</span>
<a name="line-482"></a>
<a name="line-483"></a><a name="delete'"></a><span class='hs-comment'>-- | Only temporarily remove the window from the stack, thereby not destroying special</span>
<a name="line-484"></a><span class='hs-comment'>-- information saved in the 'Stackset'</span>
<a name="line-485"></a><span class='hs-definition'>delete'</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'>Eq</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-486"></a><span class='hs-definition'>delete'</span> <span class='hs-varid'>w</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'>current</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>removeFromScreen</span>        <span class='hs-layout'>(</span><span class='hs-varid'>current</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-487"></a>                <span class='hs-layout'>,</span> <span class='hs-varid'>visible</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-varid'>removeFromScreen</span>    <span class='hs-layout'>(</span><span class='hs-varid'>visible</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-488"></a>                <span class='hs-layout'>,</span> <span class='hs-varid'>hidden</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-varid'>removeFromWorkspace</span> <span class='hs-layout'>(</span><span class='hs-varid'>hidden</span>  <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-489"></a>    <span class='hs-keyword'>where</span> <span class='hs-varid'>removeFromWorkspace</span> <span class='hs-varid'>ws</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ws</span> <span class='hs-layout'>{</span> <span class='hs-varid'>stack</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>stack</span> <span class='hs-varid'>ws</span> <span class='hs-varop'>&gt;&gt;=</span> <span class='hs-varid'>filter</span> <span class='hs-layout'>(</span><span class='hs-varop'>/=</span><span class='hs-varid'>w</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-490"></a>          <span class='hs-varid'>removeFromScreen</span> <span class='hs-varid'>scr</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>scr</span> <span class='hs-layout'>{</span> <span class='hs-varid'>workspace</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>removeFromWorkspace</span> <span class='hs-layout'>(</span><span class='hs-varid'>workspace</span> <span class='hs-varid'>scr</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-491"></a>
<a name="line-492"></a><span class='hs-comment'>------------------------------------------------------------------------</span>
<a name="line-493"></a>
<a name="line-494"></a><a name="float"></a><span class='hs-comment'>-- | Given a window, and its preferred rectangle, set it as floating</span>
<a name="line-495"></a><span class='hs-comment'>-- A floating window should already be managed by the 'StackSet'.</span>
<a name="line-496"></a><span class='hs-definition'>float</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RationalRect</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-497"></a><span class='hs-definition'>float</span> <span class='hs-varid'>w</span> <span class='hs-varid'>r</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'>floating</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-varid'>w</span> <span class='hs-varid'>r</span> <span class='hs-layout'>(</span><span class='hs-varid'>floating</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-498"></a>
<a name="line-499"></a><a name="sink"></a><span class='hs-comment'>-- | Clear the floating status of a window</span>
<a name="line-500"></a><span class='hs-definition'>sink</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ord</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-501"></a><span class='hs-definition'>sink</span> <span class='hs-varid'>w</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'>floating</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>M</span><span class='hs-varop'>.</span><span class='hs-varid'>delete</span> <span class='hs-varid'>w</span> <span class='hs-layout'>(</span><span class='hs-varid'>floating</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-502"></a>
<a name="line-503"></a><span class='hs-comment'>------------------------------------------------------------------------</span>
<a name="line-504"></a><span class='hs-comment'>-- $settingMW</span>
<a name="line-505"></a>
<a name="line-506"></a><a name="swapMaster"></a><span class='hs-comment'>-- | /O(s)/. Set the master window to the focused window.</span>
<a name="line-507"></a><span class='hs-comment'>-- The old master window is swapped in the tiling order with the focused window.</span>
<a name="line-508"></a><span class='hs-comment'>-- Focus stays with the item moved.</span>
<a name="line-509"></a><span class='hs-definition'>swapMaster</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-510"></a><span class='hs-definition'>swapMaster</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify'</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>c</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>c</span> <span class='hs-keyword'>of</span>
<a name="line-511"></a>    <span class='hs-conid'>Stack</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>[]</span> <span class='hs-keyword'>_</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>c</span>    <span class='hs-comment'>-- already master.</span>
<a name="line-512"></a>    <span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-varid'>ls</span> <span class='hs-varid'>rs</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>xs</span> <span class='hs-varop'>++</span> <span class='hs-varid'>x</span> <span class='hs-conop'>:</span> <span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>reverse</span> <span class='hs-varid'>ls</span>
<a name="line-513"></a>
<a name="line-514"></a><span class='hs-comment'>-- natural! keep focus, move current to the top, move top to current.</span>
<a name="line-515"></a>
<a name="line-516"></a><a name="shiftMaster"></a><span class='hs-comment'>-- | /O(s)/. Set the master window to the focused window.</span>
<a name="line-517"></a><span class='hs-comment'>-- The other windows are kept in order and shifted down on the stack, as if you</span>
<a name="line-518"></a><span class='hs-comment'>-- just hit mod-shift-k a bunch of times.</span>
<a name="line-519"></a><span class='hs-comment'>-- Focus stays with the item moved.</span>
<a name="line-520"></a><span class='hs-definition'>shiftMaster</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-521"></a><span class='hs-definition'>shiftMaster</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify'</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>c</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>c</span> <span class='hs-keyword'>of</span>
<a name="line-522"></a>    <span class='hs-conid'>Stack</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>[]</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>c</span>     <span class='hs-comment'>-- already master.</span>
<a name="line-523"></a>    <span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-varid'>ls</span> <span class='hs-varid'>rs</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>reverse</span> <span class='hs-varid'>ls</span> <span class='hs-varop'>++</span> <span class='hs-varid'>rs</span><span class='hs-layout'>)</span>
<a name="line-524"></a>
<a name="line-525"></a><a name="focusMaster"></a><span class='hs-comment'>-- | /O(s)/. Set focus to the master window.</span>
<a name="line-526"></a><span class='hs-definition'>focusMaster</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-527"></a><span class='hs-definition'>focusMaster</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>modify'</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>c</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>c</span> <span class='hs-keyword'>of</span>
<a name="line-528"></a>    <span class='hs-conid'>Stack</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>[]</span> <span class='hs-keyword'>_</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>c</span>
<a name="line-529"></a>    <span class='hs-conid'>Stack</span> <span class='hs-varid'>t</span> <span class='hs-varid'>ls</span> <span class='hs-varid'>rs</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stack</span> <span class='hs-varid'>x</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>xs</span> <span class='hs-varop'>++</span> <span class='hs-varid'>t</span> <span class='hs-conop'>:</span> <span class='hs-varid'>rs</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-conop'>:</span><span class='hs-varid'>xs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>reverse</span> <span class='hs-varid'>ls</span>
<a name="line-530"></a>
<a name="line-531"></a><span class='hs-comment'>--</span>
<a name="line-532"></a><span class='hs-comment'>-- ---------------------------------------------------------------------</span>
<a name="line-533"></a><span class='hs-comment'>-- $composite</span>
<a name="line-534"></a>
<a name="line-535"></a><a name="shift"></a><span class='hs-comment'>-- | /O(w)/. shift. Move the focused element of the current stack to stack</span>
<a name="line-536"></a><span class='hs-comment'>-- 'n', leaving it as the focused element on that stack. The item is</span>
<a name="line-537"></a><span class='hs-comment'>-- inserted above the currently focused element on that workspace.</span>
<a name="line-538"></a><span class='hs-comment'>-- The actual focused workspace doesn't change. If there is no</span>
<a name="line-539"></a><span class='hs-comment'>-- element on the current stack, the original stackSet is returned.</span>
<a name="line-540"></a><span class='hs-comment'>--</span>
<a name="line-541"></a><span class='hs-definition'>shift</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-conid'>Eq</span> <span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>i</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-542"></a><span class='hs-definition'>shift</span> <span class='hs-varid'>n</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>maybe</span> <span class='hs-varid'>s</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>w</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>shiftWin</span> <span class='hs-varid'>n</span> <span class='hs-varid'>w</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>peek</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
<a name="line-543"></a>
<a name="line-544"></a><a name="shiftWin"></a><span class='hs-comment'>-- | /O(n)/. shiftWin. Searches for the specified window 'w' on all workspaces</span>
<a name="line-545"></a><span class='hs-comment'>-- of the stackSet and moves it to stack 'n', leaving it as the focused</span>
<a name="line-546"></a><span class='hs-comment'>-- element on that stack. The item is inserted above the currently</span>
<a name="line-547"></a><span class='hs-comment'>-- focused element on that workspace.</span>
<a name="line-548"></a><span class='hs-comment'>-- The actual focused workspace doesn't change. If the window is not</span>
<a name="line-549"></a><span class='hs-comment'>-- found in the stackSet, the original stackSet is returned.</span>
<a name="line-550"></a><span class='hs-definition'>shiftWin</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-conid'>Eq</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>i</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span>
<a name="line-551"></a><span class='hs-definition'>shiftWin</span> <span class='hs-varid'>n</span> <span class='hs-varid'>w</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>findTag</span> <span class='hs-varid'>w</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>of</span>
<a name="line-552"></a>                    <span class='hs-conid'>Just</span> <span class='hs-varid'>from</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n</span> <span class='hs-varop'>`tagMember`</span> <span class='hs-varid'>s</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>n</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>from</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>go</span> <span class='hs-varid'>from</span> <span class='hs-varid'>s</span>
<a name="line-553"></a>                    <span class='hs-keyword'>_</span>                                        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>s</span>
<a name="line-554"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>go</span> <span class='hs-varid'>from</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>onWorkspace</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-varid'>insertUp</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>onWorkspace</span> <span class='hs-varid'>from</span> <span class='hs-layout'>(</span><span class='hs-varid'>delete'</span> <span class='hs-varid'>w</span><span class='hs-layout'>)</span>
<a name="line-555"></a>
<a name="line-556"></a><a name="onWorkspace"></a><span class='hs-definition'>onWorkspace</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span> <span class='hs-varid'>i</span><span class='hs-layout'>,</span> <span class='hs-conid'>Eq</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span><span class='hs-layout'>)</span>
<a name="line-557"></a>            <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StackSet</span> <span class='hs-varid'>i</span> <span class='hs-varid'>l</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sd</span><span class='hs-layout'>)</span>
<a name="line-558"></a><span class='hs-definition'>onWorkspace</span> <span class='hs-varid'>n</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>view</span> <span class='hs-layout'>(</span><span class='hs-varid'>currentTag</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span> <span class='hs-varop'>.</span> <span class='hs-varid'>view</span> <span class='hs-varid'>n</span> <span class='hs-varop'>$</span> <span class='hs-varid'>s</span>
</pre></body>
</html>