mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-01 12:41:52 -07:00
Rewrite minimization-related modules
* Use global state instead of per-layout - so now window is minimized on all workspaces (EWMH requires that windows with _NET_WM_STATE_HIDDEN set should be minimized on any workspace but previously they were not) * Use `windows` instead of `modify`. That should fix bugs related to actions that should be done by `windows` and not done by `modify` (fixes #46) * Mark module X.H.RestoreMinimized as deprecated
This commit is contained in:
132
XMonad/Actions/Minimize.hs
Normal file
132
XMonad/Actions/Minimize.hs
Normal file
@@ -0,0 +1,132 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : XMonad.Actions.Minimize
|
||||
-- Copyright : (c) Bogdan Sinitsyn (2016)
|
||||
-- License : BSD3-style (see LICENSE)
|
||||
--
|
||||
-- Maintainer : Bogdan Sinitsyn <bogdan.sinitsyn@gmail.com>
|
||||
-- Stability : unstable
|
||||
-- Portability : not portable
|
||||
--
|
||||
-- Adds actions for minimizing and maximizing windows
|
||||
--
|
||||
-- This module should be used with "XMonad.Layout.Minimize". Add 'minimize' to your
|
||||
-- layout modifiers as described in "XMonad.Layout.Minimized" and use actions from
|
||||
-- this module
|
||||
--
|
||||
-- Possible keybindings:
|
||||
--
|
||||
-- > , ((modm, xK_m ), withFocused minimizeWindow)
|
||||
-- > , ((modm .|. shiftMask, xK_m ), withLastMinimized maximizeWindowAndFocus)
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
module XMonad.Actions.Minimize
|
||||
( -- * Usage
|
||||
-- $usage
|
||||
minimizeWindow
|
||||
, maximizeWindow
|
||||
, maximizeWindowAndFocus
|
||||
, withLastMinimized
|
||||
, withLastMinimized'
|
||||
, withMinimized
|
||||
) where
|
||||
|
||||
import XMonad
|
||||
import qualified XMonad.StackSet as W
|
||||
|
||||
import qualified XMonad.Layout.BoringWindows as BW
|
||||
import qualified XMonad.Util.ExtensibleState as XS
|
||||
import XMonad.Util.Minimize
|
||||
import XMonad.Util.WindowProperties (getProp32)
|
||||
|
||||
import Foreign.C.Types (CLong)
|
||||
import Control.Applicative((<$>))
|
||||
import Control.Monad (join)
|
||||
import Data.Maybe (fromMaybe, listToMaybe)
|
||||
import qualified Data.List as L
|
||||
import qualified Data.Map as M
|
||||
|
||||
-- $usage
|
||||
-- Import this module with "XMonad.Layout.Minimize" and "XMonad.Layout.BoringWindows":
|
||||
-- > import XMonad.Actions.Minimize
|
||||
-- > import XMonad.Layout.Minimize
|
||||
-- > import qualified XMonad.Layout.BoringWindows as BW
|
||||
--
|
||||
-- Then apply 'minimize' and 'boringWindows' to your layout hook and use some
|
||||
-- actions from this module:
|
||||
-- > main = xmonad def { layoutHook = minimize . BW.boringWindows $ whatever }
|
||||
-- Example keybindings:
|
||||
-- > , ((modm, xK_m ), withFocused minimizeWindow )
|
||||
-- > , ((modm .|. shiftMask, xK_m ), withLastMinimized maximizeWindow)
|
||||
|
||||
setMinimizedState :: Window -> Int -> (CLong -> [CLong] -> [CLong]) -> X ()
|
||||
setMinimizedState win st f = do
|
||||
setWMState win st
|
||||
withDisplay $ \dpy -> do
|
||||
wm_state <- getAtom "_NET_WM_STATE"
|
||||
hidden <- fromIntegral <$> getAtom "_NET_WM_STATE_HIDDEN"
|
||||
wstate <- fromMaybe [] <$> getProp32 wm_state win
|
||||
io $ changeProperty32 dpy win wm_state aTOM propModeReplace (f hidden wstate)
|
||||
|
||||
setMinimized :: Window -> X ()
|
||||
setMinimized win = setMinimizedState win iconicState (:)
|
||||
|
||||
setNotMinimized :: Window -> X ()
|
||||
setNotMinimized win = setMinimizedState win normalState L.delete
|
||||
|
||||
-- It does not just set minimizedStack to newWindows because it should save
|
||||
-- order in which elements were added (newer first)
|
||||
modified :: (RectMap -> RectMap) -> X Bool
|
||||
modified f = XS.modified $
|
||||
\Minimized { rectMap = oldRectMap, minimizedStack = oldStack } ->
|
||||
let newRectMap = f oldRectMap
|
||||
newWindows = M.keys newRectMap
|
||||
in Minimized { rectMap = newRectMap
|
||||
, minimizedStack = (newWindows L.\\ oldStack)
|
||||
++
|
||||
(newWindows `L.intersect` oldStack)
|
||||
}
|
||||
|
||||
|
||||
-- | Minimize a window
|
||||
minimizeWindow :: Window -> X ()
|
||||
minimizeWindow w = withWindowSet $ \ws ->
|
||||
whenX (modified $ M.insert w (M.lookup w $ W.floating ws)) $ do
|
||||
setMinimized w
|
||||
windows $ W.sink w
|
||||
BW.focusDown
|
||||
|
||||
|
||||
-- | Maximize window and apply a function to maximized window and 'WindowSet'
|
||||
maximizeWindowAndChangeWSet :: (Window -> WindowSet -> WindowSet) -> Window -> X ()
|
||||
maximizeWindowAndChangeWSet f w = do
|
||||
mrect <- XS.gets (join . M.lookup w . rectMap)
|
||||
whenX (modified $ M.delete w) $ do
|
||||
setNotMinimized w
|
||||
broadcastMessage BW.UpdateBoring
|
||||
windows $ f w . maybe id (W.float w) mrect
|
||||
|
||||
-- | Just maximize a window without focusing
|
||||
maximizeWindow :: Window -> X ()
|
||||
maximizeWindow = maximizeWindowAndChangeWSet $ const id
|
||||
|
||||
-- | Maximize a window and then focus it
|
||||
maximizeWindowAndFocus :: Window -> X ()
|
||||
maximizeWindowAndFocus = maximizeWindowAndChangeWSet W.focusWindow
|
||||
|
||||
-- | Perform an action with last minimized window on current workspace
|
||||
-- or do nothing if there is no minimized windows on current workspace
|
||||
withLastMinimized :: (Window -> X ()) -> X ()
|
||||
withLastMinimized action = withLastMinimized' (flip whenJust action)
|
||||
|
||||
-- | Like withLastMinimized but the provided action is always invoked with a
|
||||
-- 'Maybe Window', that will be nothing if there is no last minimized window.
|
||||
withLastMinimized' :: (Maybe Window -> X ()) -> X ()
|
||||
withLastMinimized' action = withMinimized (action . listToMaybe)
|
||||
|
||||
withMinimized :: ([Window] -> X a) -> X a
|
||||
withMinimized action = do
|
||||
minimized <- XS.gets minimizedStack
|
||||
currentStack <- withWindowSet $ return . W.index
|
||||
action $ minimized `L.intersect` currentStack
|
@@ -28,7 +28,7 @@ import XMonad
|
||||
import qualified XMonad.StackSet as W
|
||||
import XMonad.Actions.GridSelect
|
||||
import XMonad.Layout.Maximize
|
||||
import XMonad.Layout.Minimize
|
||||
import XMonad.Actions.Minimize
|
||||
import XMonad.Util.XUtils (fi)
|
||||
|
||||
-- $usage
|
||||
|
Reference in New Issue
Block a user