mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-02 21:21:51 -07:00
.github
XMonad
Actions
Config
Doc
Hooks
Layout
Groups
MultiToggle
Accordion.hs
AutoMaster.hs
AvoidFloats.hs
BinaryColumn.hs
BinarySpacePartition.hs
BorderResize.hs
BoringWindows.hs
ButtonDecoration.hs
CenteredIfSingle.hs
CenteredMaster.hs
Circle.hs
Column.hs
Combo.hs
ComboP.hs
Cross.hs
Decoration.hs
DecorationAddons.hs
DecorationMadness.hs
Dishes.hs
DragPane.hs
DraggingVisualizer.hs
Drawer.hs
Dwindle.hs
DwmStyle.hs
FixedAspectRatio.hs
FixedColumn.hs
Fullscreen.hs
Gaps.hs
Grid.hs
GridVariants.hs
Groups.hs
Hidden.hs
HintedGrid.hs
HintedTile.hs
IM.hs
IfMax.hs
ImageButtonDecoration.hs
IndependentScreens.hs
LayoutBuilder.hs
LayoutBuilderP.hs
LayoutCombinators.hs
LayoutHints.hs
LayoutModifier.hs
LayoutScreens.hs
LimitWindows.hs
MagicFocus.hs
Magnifier.hs
Master.hs
Maximize.hs
MessageControl.hs
Minimize.hs
Monitor.hs
Mosaic.hs
MosaicAlt.hs
MouseResizableTile.hs
MultiColumns.hs
MultiDishes.hs
MultiToggle.hs
Named.hs
NoBorders.hs
NoFrillsDecoration.hs
OnHost.hs
OneBig.hs
PerScreen.hs
PerWorkspace.hs
PositionStoreFloat.hs
Reflect.hs
Renamed.hs
ResizableThreeColumns.hs
ResizableTile.hs
ResizeScreen.hs
Roledex.hs
ShowWName.hs
SimpleDecoration.hs
SimpleFloat.hs
Simplest.hs
SimplestFloat.hs
SortedLayout.hs
Spacing.hs
Spiral.hs
Square.hs
StackTile.hs
StateFull.hs
Stoppable.hs
SubLayouts.hs
TabBarDecoration.hs
Tabbed.hs
TallMastersCombo.hs
ThreeColumns.hs
ToggleLayouts.hs
TrackFloating.hs
TwoPane.hs
TwoPanePersistent.hs
VoidBorders.hs
WindowArranger.hs
WindowNavigation.hs
WindowSwitcherDecoration.hs
WorkspaceDir.hs
ZoomRow.hs
Prompt
Util
Doc.hs
Prelude.hs
Prompt.hs
scripts
tests
.gitignore
.hlint.yaml
.mailmap
CHANGES.md
CONTRIBUTING.md
LICENSE
NIX.md
README.md
Setup.lhs
cabal.haskell-ci
cabal.project
flake.nix
stack-master.yaml
stack.yaml
xmonad-contrib.cabal
126 lines
4.8 KiB
Haskell
126 lines
4.8 KiB
Haskell
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- |
|
|
-- Module : XMonad.Layout.Spiral
|
|
-- Description : A spiral tiling layout.
|
|
-- Copyright : (c) Joe Thornber <joe.thornber@gmail.com>
|
|
-- License : BSD3-style (see LICENSE)
|
|
--
|
|
-- Maintainer : Joe Thornber <joe.thornber@gmail.com>
|
|
-- Stability : stable
|
|
-- Portability : portable
|
|
--
|
|
-- A spiral tiling layout.
|
|
--
|
|
-----------------------------------------------------------------------------
|
|
|
|
module XMonad.Layout.Spiral (
|
|
-- * Usage
|
|
-- $usage
|
|
spiral
|
|
, spiralWithDir
|
|
, Rotation (..)
|
|
, Direction (..)
|
|
|
|
, SpiralWithDir
|
|
) where
|
|
|
|
import Data.Ratio
|
|
import XMonad hiding ( Rotation )
|
|
import XMonad.StackSet ( integrate )
|
|
|
|
-- $usage
|
|
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
|
|
--
|
|
-- > import XMonad.Layout.Spiral
|
|
--
|
|
-- Then edit your @layoutHook@ by adding the Spiral layout:
|
|
--
|
|
-- > myLayout = spiral (6/7) ||| etc..
|
|
-- > main = xmonad def { layoutHook = myLayout }
|
|
--
|
|
-- For more detailed instructions on editing the layoutHook see:
|
|
--
|
|
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
|
|
|
|
fibs :: [Integer]
|
|
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
|
|
|
|
mkRatios :: [Integer] -> [Rational]
|
|
mkRatios (x1:x2:xs) = (x1 % x2) : mkRatios (x2:xs)
|
|
mkRatios _ = []
|
|
|
|
data Rotation = CW | CCW deriving (Read, Show)
|
|
data Direction = East | South | West | North deriving (Eq, Enum, Read, Show)
|
|
|
|
blend :: Rational -> [Rational] -> [Rational]
|
|
blend scale ratios = zipWith (+) ratios scaleFactors
|
|
where
|
|
len = length ratios
|
|
step = (scale - (1 % 1)) / fromIntegral len
|
|
scaleFactors = map (* step) . reverse . take len $ [0..]
|
|
|
|
-- | A spiral layout. The parameter controls the size ratio between
|
|
-- successive windows in the spiral. Sensible values range from 0
|
|
-- up to the aspect ratio of your monitor (often 4\/3).
|
|
--
|
|
-- By default, the spiral is counterclockwise, starting to the east.
|
|
-- See also 'spiralWithDir'.
|
|
spiral :: Rational -> SpiralWithDir a
|
|
spiral = spiralWithDir East CW
|
|
|
|
-- | Create a spiral layout, specifying the starting cardinal direction,
|
|
-- the spiral direction (clockwise or counterclockwise), and the
|
|
-- size ratio.
|
|
spiralWithDir :: Direction -> Rotation -> Rational -> SpiralWithDir a
|
|
spiralWithDir = SpiralWithDir
|
|
|
|
data SpiralWithDir a = SpiralWithDir Direction Rotation Rational
|
|
deriving ( Read, Show )
|
|
|
|
instance LayoutClass SpiralWithDir a where
|
|
pureLayout (SpiralWithDir dir rot scale) sc stack = zip ws rects
|
|
where ws = integrate stack
|
|
ratios = blend scale . reverse . take (length ws - 1) . mkRatios $ tail fibs
|
|
rects = divideRects (zip ratios dirs) sc
|
|
dirs = dropWhile (/= dir) $ case rot of
|
|
CW -> cycle [East .. North]
|
|
CCW -> cycle [North, West, South, East]
|
|
handleMessage (SpiralWithDir dir rot scale) = return . fmap resize . fromMessage
|
|
where resize Expand = spiralWithDir dir rot $ (21 % 20) * scale
|
|
resize Shrink = spiralWithDir dir rot $ (20 % 21) * scale
|
|
description _ = "Spiral"
|
|
|
|
-- This will produce one more rectangle than there are splits details
|
|
divideRects :: [(Rational, Direction)] -> Rectangle -> [Rectangle]
|
|
divideRects [] r = [r]
|
|
divideRects ((r,d):xs) rect = case divideRect r d rect of
|
|
(r1, r2) -> r1 : divideRects xs r2
|
|
|
|
-- It's much simpler if we work with all Integers and convert to
|
|
-- Rectangle at the end.
|
|
data Rect = Rect Integer Integer Integer Integer
|
|
|
|
fromRect :: Rect -> Rectangle
|
|
fromRect (Rect x y w h) = Rectangle (fromIntegral x) (fromIntegral y) (fromIntegral w) (fromIntegral h)
|
|
|
|
toRect :: Rectangle -> Rect
|
|
toRect (Rectangle x y w h) = Rect (fromIntegral x) (fromIntegral y) (fromIntegral w) (fromIntegral h)
|
|
|
|
divideRect :: Rational -> Direction -> Rectangle -> (Rectangle, Rectangle)
|
|
divideRect r d rect = let (r1, r2) = divideRect' r d $ toRect rect in
|
|
(fromRect r1, fromRect r2)
|
|
|
|
divideRect' :: Rational -> Direction -> Rect -> (Rect, Rect)
|
|
divideRect' ratio dir (Rect x y w h) =
|
|
case dir of
|
|
East -> let (w1, w2) = chop ratio w in (Rect x y w1 h, Rect (x + w1) y w2 h)
|
|
South -> let (h1, h2) = chop ratio h in (Rect x y w h1, Rect x (y + h1) w h2)
|
|
West -> let (w1, w2) = chop (1 - ratio) w in (Rect (x + w1) y w2 h, Rect x y w1 h)
|
|
North -> let (h1, h2) = chop (1 - ratio) h in (Rect x (y + h1) w h2, Rect x y w h1)
|
|
|
|
chop :: Rational -> Integer -> (Integer, Integer)
|
|
chop rat n = let f = (fromIntegral n * numerator rat) `div` denominator rat in
|
|
(f, n - f)
|