mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-11 18:22:16 -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:
@@ -1,4 +1,4 @@
|
||||
{-# LANGUAGE MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances, FlexibleContexts, PatternGuards #-}
|
||||
{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleContexts, PatternGuards #-}
|
||||
----------------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : XMonad.Layout.Minimize
|
||||
@@ -18,20 +18,14 @@ module XMonad.Layout.Minimize (
|
||||
-- * Usage
|
||||
-- $usage
|
||||
minimize,
|
||||
minimizeWindow,
|
||||
MinimizeMsg(RestoreMinimizedWin,RestoreNextMinimizedWin),
|
||||
Minimize,
|
||||
) where
|
||||
|
||||
import XMonad
|
||||
import qualified XMonad.StackSet as W
|
||||
import XMonad.Util.Minimize (Minimized(..))
|
||||
import XMonad.Layout.LayoutModifier
|
||||
import XMonad.Layout.BoringWindows as BW
|
||||
import XMonad.Util.WindowProperties (getProp32)
|
||||
import Data.List
|
||||
import qualified Data.Map as M
|
||||
import Data.Maybe
|
||||
import Foreign.C.Types (CLong)
|
||||
import qualified XMonad.Util.ExtensibleState as XS
|
||||
|
||||
-- $usage
|
||||
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
|
||||
@@ -47,97 +41,33 @@ import Foreign.C.Types (CLong)
|
||||
--
|
||||
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
|
||||
--
|
||||
-- In the key-bindings, do something like:
|
||||
--
|
||||
-- > , ((modm, xK_m ), withFocused minimizeWindow)
|
||||
-- > , ((modm .|. shiftMask, xK_m ), sendMessage RestoreNextMinimizedWin)
|
||||
--
|
||||
-- The first action will minimize the focused window, while the second one will restore
|
||||
-- the next minimized window.
|
||||
--
|
||||
-- For detailed instruction on editing the key binding see:
|
||||
--
|
||||
-- "XMonad.Doc.Extending#Editing_key_bindings".
|
||||
--
|
||||
-- The module is designed to work together with "XMonad.Layout.BoringWindows" so
|
||||
-- that minimized windows will be skipped over when switching the focused window with
|
||||
-- the keyboard. Include 'BW.boringWindows' in your layout hook and see the
|
||||
-- documentation of "XMonad.Layout.BoringWindows" on how to modify your keybindings.
|
||||
--
|
||||
-- See "XMonad.Actions.Minimize" for possible actions for minimizing/restoring windows
|
||||
--
|
||||
-- Also see "XMonad.Hooks.Minimize" if you want to be able to minimize
|
||||
-- and restore windows from your taskbar.
|
||||
|
||||
data Minimize a = Minimize [Window] (M.Map Window W.RationalRect) deriving ( Read, Show )
|
||||
minimize :: LayoutClass l Window => l Window -> ModifiedLayout Minimize l Window
|
||||
minimize = ModifiedLayout $ Minimize [] M.empty
|
||||
data Minimize a = Minimize deriving ( Read, Show )
|
||||
minimize :: l Window -> ModifiedLayout Minimize l Window
|
||||
minimize = ModifiedLayout Minimize
|
||||
|
||||
data MinimizeMsg = MinimizeWin Window
|
||||
| RestoreMinimizedWin Window
|
||||
| RestoreNextMinimizedWin
|
||||
deriving (Typeable, Eq)
|
||||
instance Message MinimizeMsg
|
||||
|
||||
minimizeWindow :: Window -> X ()
|
||||
minimizeWindow w = sendMessage (MinimizeWin w) >> BW.focusDown
|
||||
|
||||
setMinimizedState :: Window -> Int -> (CLong -> [CLong] -> [CLong]) -> X ()
|
||||
setMinimizedState win st f = do
|
||||
setWMState win st
|
||||
withDisplay $ \dpy -> do
|
||||
wm_state <- getAtom "_NET_WM_STATE"
|
||||
mini <- getAtom "_NET_WM_STATE_HIDDEN"
|
||||
wstate <- fromMaybe [] `fmap` getProp32 wm_state win
|
||||
let ptype = 4 -- The atom property type for changeProperty
|
||||
fi_mini = fromIntegral mini
|
||||
io $ changeProperty32 dpy win wm_state ptype propModeReplace (f fi_mini wstate)
|
||||
|
||||
setMinimized :: Window -> X ()
|
||||
setMinimized win = setMinimizedState win iconicState (:)
|
||||
|
||||
setNotMinimized :: Window -> X ()
|
||||
setNotMinimized win = setMinimizedState win normalState delete
|
||||
|
||||
instance LayoutModifier Minimize Window where
|
||||
modifierDescription _ = "Minimize"
|
||||
|
||||
modifyLayout (Minimize minimized _) wksp rect = do
|
||||
modifyLayout Minimize wksp rect = do
|
||||
minimized <- XS.gets minimizedStack
|
||||
let stack = W.stack wksp
|
||||
filtStack = stack >>=W.filter (\w -> not (w `elem` minimized))
|
||||
filtStack = stack >>= W.filter (`notElem` minimized)
|
||||
runLayout (wksp {W.stack = filtStack}) rect
|
||||
|
||||
handleMess (Minimize minimized unfloated) m
|
||||
| Just (MinimizeWin w) <- fromMessage m, not (w `elem` minimized) = do
|
||||
setMinimized w
|
||||
ws <- gets windowset
|
||||
case M.lookup w (W.floating ws) of
|
||||
Nothing -> return $ Just $ Minimize (w:minimized) unfloated
|
||||
Just r -> do
|
||||
modify (\s -> s { windowset = W.sink w ws})
|
||||
return $ Just $ Minimize (w:minimized) (M.insert w r unfloated)
|
||||
| Just (RestoreMinimizedWin w) <- fromMessage m = do
|
||||
setNotMinimized w
|
||||
case M.lookup w unfloated of
|
||||
Nothing -> return $ Just $ Minimize (minimized \\ [w]) unfloated
|
||||
Just r -> do
|
||||
ws <- gets windowset
|
||||
modify (\s -> s { windowset = W.float w r ws})
|
||||
return $ Just $ Minimize (minimized \\ [w]) (M.delete w unfloated)
|
||||
| Just RestoreNextMinimizedWin <- fromMessage m = do
|
||||
ws <- gets windowset
|
||||
if not (null minimized)
|
||||
then case M.lookup (head minimized) unfloated of
|
||||
Nothing -> do
|
||||
let w = head minimized
|
||||
setNotMinimized w
|
||||
modify (\s -> s { windowset = W.focusWindow w ws})
|
||||
return $ Just $ Minimize (tail minimized) unfloated
|
||||
Just r -> do
|
||||
let w = head minimized
|
||||
setNotMinimized w
|
||||
modify (\s -> s { windowset = (W.focusWindow w . W.float w r) ws})
|
||||
return $ Just $ Minimize (tail minimized) (M.delete w unfloated)
|
||||
else return Nothing
|
||||
handleMess Minimize m
|
||||
| Just BW.UpdateBoring <- fromMessage m = do
|
||||
minimized <- XS.gets minimizedStack
|
||||
ws <- gets (W.workspace . W.current . windowset)
|
||||
flip sendMessageWithNoRefresh ws $ BW.Replace "Minimize" minimized
|
||||
return Nothing
|
||||
|
Reference in New Issue
Block a user