mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-03 13:41:53 -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
121 lines
5.7 KiB
Haskell
121 lines
5.7 KiB
Haskell
----------------------------------------------------------------------------
|
|
-- |
|
|
-- Module : XMonad.Layout.DecorationAddons
|
|
-- Description : Various stuff that can be added to the decoration.
|
|
-- Copyright : (c) Jan Vornberger 2009
|
|
-- License : BSD3-style (see LICENSE)
|
|
--
|
|
-- Maintainer : jan.vornberger@informatik.uni-oldenburg.de
|
|
-- Stability : unstable
|
|
-- Portability : not portable
|
|
--
|
|
-- Various stuff that can be added to the decoration. Most of it
|
|
-- is intended to be used by other modules. See
|
|
-- "XMonad.Layout.ButtonDecoration" for a module that makes use of this.
|
|
--
|
|
-----------------------------------------------------------------------------
|
|
|
|
module XMonad.Layout.DecorationAddons (
|
|
titleBarButtonHandler
|
|
,defaultThemeWithButtons
|
|
,handleScreenCrossing
|
|
) where
|
|
|
|
import XMonad
|
|
import qualified XMonad.StackSet as W
|
|
import XMonad.Layout.Decoration
|
|
import XMonad.Actions.WindowMenu
|
|
import XMonad.Actions.Minimize
|
|
import XMonad.Layout.Maximize
|
|
import XMonad.Hooks.ManageDocks
|
|
import XMonad.Util.Font
|
|
import XMonad.Util.PositionStore
|
|
|
|
import XMonad.Prelude
|
|
import qualified Data.Set as S
|
|
|
|
minimizeButtonOffset :: Int
|
|
minimizeButtonOffset = 48
|
|
|
|
maximizeButtonOffset :: Int
|
|
maximizeButtonOffset = 25
|
|
|
|
closeButtonOffset :: Int
|
|
closeButtonOffset = 10
|
|
|
|
buttonSize :: Int
|
|
buttonSize = 10
|
|
|
|
-- | A function intended to be plugged into the 'decorationCatchClicksHook' of a decoration.
|
|
-- It will intercept clicks on the buttons of the decoration and invoke the associated action.
|
|
-- To actually see the buttons, you will need to use a theme that includes them.
|
|
-- See 'defaultThemeWithButtons' below.
|
|
titleBarButtonHandler :: Window -> Int -> Int -> X Bool
|
|
titleBarButtonHandler mainw distFromLeft distFromRight = do
|
|
let action
|
|
| fi distFromLeft <= 3 * buttonSize = focus mainw >> windowMenu >> return True
|
|
| fi distFromRight >= closeButtonOffset &&
|
|
fi distFromRight <= closeButtonOffset + buttonSize = focus mainw >> kill >> return True
|
|
| fi distFromRight >= maximizeButtonOffset &&
|
|
fi distFromRight <= maximizeButtonOffset + (2 * buttonSize) = focus mainw >> sendMessage (maximizeRestore mainw) >> return True
|
|
| fi distFromRight >= minimizeButtonOffset &&
|
|
fi distFromRight <= minimizeButtonOffset + buttonSize = focus mainw >> minimizeWindow mainw >> return True
|
|
| otherwise = return False
|
|
action
|
|
|
|
-- | Intended to be used together with 'titleBarButtonHandler'. See above.
|
|
defaultThemeWithButtons :: Theme
|
|
defaultThemeWithButtons = def {
|
|
windowTitleAddons = [ (" (M)", AlignLeft)
|
|
, ("_" , AlignRightOffset minimizeButtonOffset)
|
|
, ("[]" , AlignRightOffset maximizeButtonOffset)
|
|
, ("X" , AlignRightOffset closeButtonOffset)
|
|
]
|
|
}
|
|
|
|
-- | A function intended to be plugged into the 'decorationAfterDraggingHook' of a decoration.
|
|
-- It will check if the window has been dragged onto another screen and shift it there.
|
|
-- The PositionStore is also updated accordingly, as this is designed to be used together
|
|
-- with "XMonad.Layout.PositionStoreFloat".
|
|
handleScreenCrossing :: Window -> Window -> X Bool
|
|
handleScreenCrossing w decoWin = withDisplay $ \d -> do
|
|
root <- asks theRoot
|
|
(_, _, _, px, py, _, _, _) <- io $ queryPointer d root
|
|
ws <- gets windowset
|
|
sc <- fromMaybe (W.current ws) <$> pointScreen (fi px) (fi py)
|
|
maybeWksp <- screenWorkspace $ W.screen sc
|
|
let targetWksp = maybeWksp >>= \wksp ->
|
|
W.findTag w ws >>= \currentWksp ->
|
|
if currentWksp /= wksp
|
|
then Just wksp
|
|
else Nothing
|
|
case targetWksp of
|
|
Just wksp -> do
|
|
-- find out window under cursor on target workspace
|
|
-- apparently we have to switch to the workspace first
|
|
-- to make this work, which unforunately introduces some flicker
|
|
windows $ \ws' -> W.view wksp ws'
|
|
(_, _, selWin, _, _, _, _, _) <- io $ queryPointer d root
|
|
|
|
-- adjust PositionStore
|
|
let oldScreenRect = screenRect . W.screenDetail $ W.current ws
|
|
newScreenRect = screenRect . W.screenDetail $ sc
|
|
{-- somewhat ugly hack to get proper ScreenRect,
|
|
creates unwanted inter-dependencies
|
|
TODO: get ScreenRects in a proper way --}
|
|
oldScreenRect' <- fmap ($ oldScreenRect) (calcGap $ S.fromList [minBound .. maxBound])
|
|
newScreenRect' <- fmap ($ newScreenRect) (calcGap $ S.fromList [minBound .. maxBound])
|
|
wa <- io $ getWindowAttributes d decoWin
|
|
modifyPosStore (\ps ->
|
|
posStoreMove ps w (fi $ wa_x wa) (fi $ wa_y wa)
|
|
oldScreenRect' newScreenRect')
|
|
|
|
-- set focus correctly so the window will be inserted
|
|
-- at the correct position on the target workspace
|
|
-- and then shift the window
|
|
windows $ \ws' -> W.shiftWin wksp w . W.focusWindow selWin $ ws'
|
|
|
|
-- return True to signal that screen crossing has taken place
|
|
return True
|
|
Nothing -> return False
|