mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-07-28 18:51:51 -07:00
Thanks for liskni_si for pressing the matter: without this change it is very broken, with the patch it is still not perfect but still useful.
117 lines
3.4 KiB
Haskell
117 lines
3.4 KiB
Haskell
{-# LANGUAGE MultiParamTypeClasses, PatternGuards, TypeSynonymInstances #-}
|
|
{- |
|
|
|
|
Module : XMonad.Layout.TrackFloating
|
|
Copyright : (c) 2010 Adam Vogt
|
|
License : BSD-style (see xmonad/LICENSE)
|
|
|
|
Maintainer : vogt.adam@gmail.com
|
|
Stability : unstable
|
|
Portability : unportable
|
|
|
|
Layout modifier that tracks focus in the tiled layer while the floating layer
|
|
is in use. This is particularly helpful for tiled layouts where the focus
|
|
determines what is visible.
|
|
|
|
The relevant bug is Issue 4
|
|
<http://code.google.com/p/xmonad/issues/detail?id=4>.
|
|
-}
|
|
module XMonad.Layout.TrackFloating
|
|
(-- * Usage
|
|
-- $usage
|
|
|
|
-- ** For other layout modifiers
|
|
-- $layoutModifier
|
|
trackFloating,
|
|
TrackFloating,
|
|
) where
|
|
|
|
import Control.Monad
|
|
import Data.Function
|
|
import Data.List
|
|
import Data.Maybe
|
|
import qualified Data.Map as M
|
|
import qualified Data.Set as S
|
|
|
|
import XMonad
|
|
import XMonad.Layout.LayoutModifier
|
|
import qualified XMonad.StackSet as W
|
|
|
|
|
|
data TrackFloating a = TrackFloating
|
|
{ _wasFloating :: Bool,
|
|
_tiledFocus :: Maybe Window }
|
|
deriving (Read,Show,Eq)
|
|
|
|
|
|
instance LayoutModifier TrackFloating Window where
|
|
modifyLayoutWithUpdate os@(TrackFloating _wasF mw) ws@(W.Workspace{ W.stack = ms }) r
|
|
= do
|
|
winset <- gets windowset
|
|
let xCur = fmap W.focus xStack
|
|
xStack = W.stack $ W.workspace $ W.current winset
|
|
isF = fmap (\x -> x `M.member` W.floating winset ||
|
|
(let (\\\) = (S.\\) `on` (S.fromList . W.integrate')
|
|
in x `S.member` (xStack \\\ ms)))
|
|
xCur
|
|
newStack
|
|
-- focus is floating, so use the remembered focus point
|
|
| Just isF' <- isF,
|
|
isF',
|
|
Just w <- mw,
|
|
Just s <- ms,
|
|
Just ns <- find ((==) w . W.focus)
|
|
$ zipWith const (iterate W.focusDown' s) (W.integrate s)
|
|
= Just ns
|
|
| otherwise
|
|
= ms
|
|
newState = case isF of
|
|
Just True -> mw
|
|
Just False | Just f <- xCur -> Just f
|
|
_ -> Nothing
|
|
ran <- runLayout ws{ W.stack = newStack } r
|
|
return (ran,
|
|
let n = TrackFloating (fromMaybe False isF) newState
|
|
in guard (n /= os) >> Just n)
|
|
|
|
|
|
{- $usage
|
|
|
|
Apply to your layout in a config like:
|
|
|
|
> main = xmonad (defaultConfig{
|
|
> layoutHook = trackFloating
|
|
> (noBorders Full ||| Tall 1 0.3 0.5),
|
|
> ...
|
|
> })
|
|
|
|
-}
|
|
|
|
{- | Runs another layout with a remembered focus, provided:
|
|
|
|
* the subset of windows doesn't include the focus in XState
|
|
|
|
* it was previously run with a subset that included the XState focus
|
|
|
|
* the remembered focus hasn't since been killed
|
|
|
|
-}
|
|
trackFloating :: l a -> ModifiedLayout TrackFloating l a
|
|
trackFloating layout = ModifiedLayout (TrackFloating False Nothing) layout
|
|
|
|
{- $layoutModifier
|
|
It also corrects focus issues for full-like layouts inside other layout
|
|
modifiers:
|
|
|
|
> import XMonad.Layout.IM
|
|
> import XMonad.Layout.Tabbed
|
|
> import XMonad.Layout.TrackFloating
|
|
> import XMonad.Layout.Reflect
|
|
|
|
> gimpLayout = withIM 0.11 (Role "gimp-toolbox") $ reflectHoriz
|
|
> $ withIM 0.15 (Role "gimp-dock") (trackFloating simpleTabbed)
|
|
|
|
Interactions with some layout modifiers (ex. decorations, minimizing) are
|
|
unknown but likely unpleasant.
|
|
-}
|