mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 11:30:22 -07:00
X.A.CycleRecentWS: Simplify/fix unView
To make this more "obviously correct", make it resemble the `view` implementation, just do the exact reverse. Now the only complex bit is the "undelete" operation. This also fixes another issue: state was only preserved in the focused workspace, but it may have changed in another visible workspace as well. The property test is updated to test this.
This commit is contained in:
parent
24786c6d04
commit
12b30c393c
@ -38,8 +38,7 @@ import XMonad hiding (workspaces)
|
|||||||
import XMonad.StackSet hiding (filter)
|
import XMonad.StackSet hiding (filter)
|
||||||
|
|
||||||
import Control.Arrow ((&&&))
|
import Control.Arrow ((&&&))
|
||||||
import Data.List (find)
|
import Data.Function (on)
|
||||||
import Data.Maybe (fromJust)
|
|
||||||
|
|
||||||
-- $usage
|
-- $usage
|
||||||
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:
|
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:
|
||||||
@ -140,38 +139,29 @@ cycleWindowSets genOptions mods keyNext keyPrev = do
|
|||||||
-- new 'WindowSet' may have accumulated.
|
-- new 'WindowSet' may have accumulated.
|
||||||
unView :: forall i l a s sd. Eq i
|
unView :: forall i l a s sd. Eq i
|
||||||
=> StackSet i l a s sd -> StackSet i l a s sd -> StackSet i l a s sd
|
=> StackSet i l a s sd -> StackSet i l a s sd -> StackSet i l a s sd
|
||||||
unView origW w
|
unView w0 w
|
||||||
| -- The focused screen changed; the old focus is on a visible screen
|
| currentTag w0 == currentTag w = w
|
||||||
newFocT `elem` visT =
|
|
||||||
w { current = (current origW){ workspace = findFoc (workspace <$> visible w) }
|
| v1 : vs <- visible w
|
||||||
, visible = zipWith (\v ws -> v{ workspace = ws }) vis (updateNewFoc visW)
|
, currentTag w0 == (tag . workspace) v1
|
||||||
}
|
= w { current = v1
|
||||||
| -- The focused screen didn't change; the old focus is hidden
|
, visible = insertAt (commonPrefixV (visible w0) vs) (current w) vs }
|
||||||
newFocT `elem` hidT =
|
|
||||||
w { current = (current origW){ workspace = findFoc (hidden w) }
|
| h1 : hs <- hidden w
|
||||||
, hidden = updateNewFoc hid
|
, currentTag w0 == tag h1
|
||||||
}
|
= w { current = (current w){ workspace = h1 }
|
||||||
|
, hidden = insertAt (commonPrefixH (hidden w0) hs) (workspace (current w)) hs }
|
||||||
|
|
||||||
| otherwise = w
|
| otherwise = w
|
||||||
where
|
where
|
||||||
-- Foci, old and new
|
commonPrefixV = commonPrefix `on` fmap (tag . workspace)
|
||||||
focT = tag . workspace . current $ origW
|
commonPrefixH = commonPrefix `on` fmap tag
|
||||||
(newFoc, newFocT) = id &&& tag $ workspace (current w)
|
|
||||||
|
|
||||||
-- Workspaces in the _original_ windowset
|
insertAt :: Int -> x -> [x] -> [x]
|
||||||
(hid, hidT) = id &&& map tag $ hidden origW
|
insertAt n x xs = let (l, r) = splitAt n xs in l ++ [x] ++ r
|
||||||
(vis, (visW, visT)) = id &&& map workspace &&& map (tag . workspace)
|
|
||||||
$ visible origW
|
|
||||||
|
|
||||||
-- | Given a list of new workspaces that contain the old focus,
|
commonPrefix :: Eq x => [x] -> [x] -> Int
|
||||||
-- return that workspace.
|
commonPrefix a b = length $ takeWhile id $ zipWith (==) a b
|
||||||
findFoc :: [Workspace i l a] -> Workspace i l a
|
|
||||||
findFoc ws = fromJust $ find ((== focT) . tag) ws
|
|
||||||
|
|
||||||
-- | Given a list of old workspaces that contain the new focus,
|
|
||||||
-- update the state of the focus.
|
|
||||||
updateNewFoc :: [Workspace i l a] -> [Workspace i l a]
|
|
||||||
updateNewFoc ws = before ++ newFoc : after
|
|
||||||
where (before, after) = drop 1 <$> break ((== newFocT) . tag) ws
|
|
||||||
|
|
||||||
-- | Given some function that generates a list of workspaces from a
|
-- | Given some function that generates a list of workspaces from a
|
||||||
-- given 'WindowSet', switch to the first generated workspace.
|
-- given 'WindowSet', switch to the first generated workspace.
|
||||||
|
@ -6,7 +6,7 @@ import Test.Hspec.QuickCheck
|
|||||||
import Test.QuickCheck
|
import Test.QuickCheck
|
||||||
|
|
||||||
import XMonad.Actions.CycleRecentWS (unView)
|
import XMonad.Actions.CycleRecentWS (unView)
|
||||||
import XMonad.StackSet (view)
|
import XMonad.StackSet (view, mapLayout)
|
||||||
|
|
||||||
import Instances
|
import Instances
|
||||||
import Utils (tags)
|
import Utils (tags)
|
||||||
@ -17,4 +17,7 @@ spec = do
|
|||||||
|
|
||||||
prop_unView :: T -> Property
|
prop_unView :: T -> Property
|
||||||
prop_unView ss = conjoin
|
prop_unView ss = conjoin
|
||||||
[ counterexample (show t) (unView ss (view t ss) === ss) | t <- tags ss ]
|
[ counterexample (show t) (unView ss (state (view t ss)) === state ss)
|
||||||
|
| t <- tags ss ]
|
||||||
|
where
|
||||||
|
state = mapLayout succ
|
||||||
|
Loading…
x
Reference in New Issue
Block a user