control: tag -1 +moreinfo

Hello,

On Sat, Aug 06, 2016 at 04:23:02PM +0200, Jonas Smedegaard wrote:
> According to
> https://wiki.haskell.org/Xmonad/Notable_changes_since_0.11#.2AURGENT.2A_Bug_in_0.12_ManageDocks
> there is a bug in release 0.12 needing cherry-picking from git.

I can't reproduce this bug locally.  However, the attached patch is all
of upstream's recent commits that look to concern ManageDocks.

If anyone is seeing this bug, please apply this patch to the source
package and let us know if it fixes the problem.

To examine the individual commits I cherry-picked, see branch
fix-managedocks of repo <https://git.spwhitton.name/xmonad-contrib>,
from which I generated the patch.

-- 
Sean Whitton
From 6646f5944d945284106cef1d8d811ca0496d434e Mon Sep 17 00:00:00 2001
From: Sean Whitton <spwhit...@spwhitton.name>
Date: Sun, 3 Jan 2016 12:37:16 +0300
Subject: [PATCH] fix xmonad/xmonad#21

The following commits, from various authors in the upstream git
repository, are squashed into this commit:

fix build with older ghc

never query all the tree in X.H.ManageHook

minor fixes in X.H.ManageDocks

fix X.H.PositionStoreHooks for new signature of calcGaps

add calcGapForAll for other modules

typo

add new dock if it hasn't strut properties

handle PropertyNotify events on docks

add docksStartupHook for handling docks when restarted

handle docks remove correctly

fix slowdown when removing docks

some minor fixes in X.H.ManageDocks

send all docks messages only from event hook

Update XMonad.Config.Desktop for 0.12 ManageDocks
---
 XMonad/Actions/FloatSnap.hs        |   4 +-
 XMonad/Config/Desktop.hs           |   5 +-
 XMonad/Config/Gnome.hs             |   3 +-
 XMonad/Config/Kde.hs               |   3 +-
 XMonad/Config/Mate.hs              |   3 +-
 XMonad/Config/Xfce.hs              |   3 +-
 XMonad/Hooks/ManageDocks.hs        | 122 +++++++++++++++++++++++++++++--------
 XMonad/Hooks/PositionStoreHooks.hs |   8 ++-
 XMonad/Layout/DecorationAddons.hs  |   4 +-
 9 files changed, 116 insertions(+), 39 deletions(-)

diff --git a/XMonad/Actions/FloatSnap.hs b/XMonad/Actions/FloatSnap.hs
index baf511f..2d04fd3 100644
--- a/XMonad/Actions/FloatSnap.hs
+++ b/XMonad/Actions/FloatSnap.hs
@@ -33,7 +33,7 @@ import Data.Maybe (listToMaybe,fromJust,isNothing)
 import qualified XMonad.StackSet as W
 import qualified Data.Set as S
 
-import XMonad.Hooks.ManageDocks (calcGap)
+import XMonad.Hooks.ManageDocks (calcGapForAll)
 import XMonad.Util.Types (Direction2D(..))
 import XMonad.Actions.AfterDrag
 
@@ -291,7 +291,7 @@ getSnap horiz collidedist d w = do
     screen <- W.current <$> gets windowset
     let sr = screenRect $ W.screenDetail screen
         wl = W.integrate' . W.stack $ W.workspace screen
-    gr <- fmap ($sr) $ calcGap $ S.fromList [minBound .. maxBound]
+    gr <- fmap ($sr) $ calcGapForAll $ S.fromList [minBound .. maxBound]
     wla <- filter (collides wa) `fmap` (io $ mapM (getWindowAttributes d) $ filter (/=w) wl)
 
     return ( neighbours (back wa sr gr wla) (wpos wa)
diff --git a/XMonad/Config/Desktop.hs b/XMonad/Config/Desktop.hs
index add5548..088aef8 100644
--- a/XMonad/Config/Desktop.hs
+++ b/XMonad/Config/Desktop.hs
@@ -165,9 +165,10 @@ import qualified Data.Map as M
 --
 
 desktopConfig = ewmh def
-    { startupHook     = setDefaultCursor xC_left_ptr
+    { startupHook     = setDefaultCursor xC_left_ptr <+> docksStartupHook <+> startupHook def
     , layoutHook      = desktopLayoutModifiers $ layoutHook def
-    , manageHook      = manageHook def <+> manageDocks
+    , manageHook      = manageDocks <+> manageHook def
+    , handleEventHook = docksEventHook <+> handleEventHook def
     , keys            = desktopKeys <+> keys def }
 
 desktopKeys (XConfig {modMask = modm}) = M.fromList $
diff --git a/XMonad/Config/Gnome.hs b/XMonad/Config/Gnome.hs
index 3ab7270..aa506e1 100644
--- a/XMonad/Config/Gnome.hs
+++ b/XMonad/Config/Gnome.hs
@@ -18,7 +18,8 @@ module XMonad.Config.Gnome (
     -- $usage
     gnomeConfig,
     gnomeRun,
-    gnomeRegister
+    gnomeRegister,
+    desktopLayoutModifiers
     ) where
 
 import XMonad
diff --git a/XMonad/Config/Kde.hs b/XMonad/Config/Kde.hs
index bda58a4..8046804 100644
--- a/XMonad/Config/Kde.hs
+++ b/XMonad/Config/Kde.hs
@@ -17,7 +17,8 @@ module XMonad.Config.Kde (
     -- * Usage
     -- $usage
     kdeConfig,
-    kde4Config
+    kde4Config,
+    desktopLayoutModifiers
     ) where
 
 import XMonad
diff --git a/XMonad/Config/Mate.hs b/XMonad/Config/Mate.hs
index d54f03c..16b1cce 100644
--- a/XMonad/Config/Mate.hs
+++ b/XMonad/Config/Mate.hs
@@ -20,7 +20,8 @@ module XMonad.Config.Mate (
     -- $usage
     mateConfig,
     mateRun,
-    mateRegister
+    mateRegister,
+    desktopLayoutModifiers
     ) where
 
 import XMonad
diff --git a/XMonad/Config/Xfce.hs b/XMonad/Config/Xfce.hs
index c6bca4c..713b975 100644
--- a/XMonad/Config/Xfce.hs
+++ b/XMonad/Config/Xfce.hs
@@ -16,7 +16,8 @@
 module XMonad.Config.Xfce (
     -- * Usage
     -- $usage
-    xfceConfig
+    xfceConfig,
+    desktopLayoutModifiers
     ) where
 
 import XMonad
diff --git a/XMonad/Hooks/ManageDocks.hs b/XMonad/Hooks/ManageDocks.hs
index a8acb96..93d131b 100644
--- a/XMonad/Hooks/ManageDocks.hs
+++ b/XMonad/Hooks/ManageDocks.hs
@@ -16,7 +16,7 @@ module XMonad.Hooks.ManageDocks (
     -- * Usage
     -- $usage
     manageDocks, checkDock, AvoidStruts, avoidStruts, avoidStrutsOn,
-    docksEventHook,
+    docksEventHook, docksStartupHook,
     ToggleStruts(..),
     SetStruts(..),
     module XMonad.Util.Types,
@@ -28,7 +28,7 @@ module XMonad.Hooks.ManageDocks (
 #endif
 
     -- for XMonad.Actions.FloatSnap
-    calcGap
+    calcGap, calcGapForAll
     ) where
 
 
@@ -40,8 +40,12 @@ import XMonad.Util.Types
 import XMonad.Util.WindowProperties (getProp32s)
 import XMonad.Util.XUtils (fi)
 import Data.Monoid (All(..), mempty)
+import Data.Functor((<$>))
 
 import qualified Data.Set as S
+import qualified Data.Map as M
+import Data.Maybe (fromMaybe, catMaybes)
+import Control.Monad (when, forM_, filterM)
 
 -- $usage
 -- To use this module, add the following import to @~\/.xmonad\/xmonad.hs@:
@@ -100,9 +104,10 @@ import qualified Data.Set as S
 -- | Detects if the given window is of type DOCK and if so, reveals
 --   it, but does not manage it.
 manageDocks :: ManageHook
-manageDocks = checkDock --> (doIgnore <+> clearGapCache)
-    where clearGapCache = do
-            liftX (broadcastMessage ClearGapCache)
+manageDocks = checkDock --> (doIgnore <+> setDocksMask)
+    where setDocksMask = do
+            ask >>= \win -> liftX $ withDisplay $ \dpy -> do
+                io $ selectInput dpy win (propertyChangeMask .|. structureNotifyMask)
             mempty
 
 -- | Checks if a window is a DOCK or DESKTOP window
@@ -118,13 +123,52 @@ checkDock = ask >>= \w -> liftX $ do
 -- | Whenever a new dock appears, refresh the layout immediately to avoid the
 -- new dock.
 docksEventHook :: Event -> X All
-docksEventHook (MapNotifyEvent {ev_window = w}) = do
-    whenX ((not `fmap` (isClient w)) <&&> runQuery checkDock w) $ do
-        broadcastMessage ClearGapCache
-        refresh
+docksEventHook (MapNotifyEvent { ev_window = w }) = do
+    whenX (runQuery checkDock w <&&> (not <$> isClient w)) $ do
+        strut <- getRawStrut w
+        sendMessage $ UpdateDock w strut
+        broadcastMessage $ UpdateDock w strut
+    return (All True)
+docksEventHook (PropertyEvent { ev_window = w
+                              , ev_atom = a }) = do
+    whenX (runQuery checkDock w) $ do
+        nws <- getAtom "_NET_WM_STRUT"
+        nwsp <- getAtom "_NET_WM_STRUT_PARTIAL"
+        when (a == nws || a == nwsp) $ do
+            strut <- getRawStrut w
+            broadcastMessage $ UpdateDock w strut
+            refresh
+    return (All True)
+docksEventHook (DestroyWindowEvent {ev_window = w}) = do
+    sendMessage (RemoveDock w)
+    broadcastMessage (RemoveDock w)
     return (All True)
 docksEventHook _ = return (All True)
 
+docksStartupHook :: X ()
+docksStartupHook = withDisplay $ \dpy -> do
+    rootw <- asks theRoot
+    (_,_,wins) <- io $ queryTree dpy rootw
+    docks <- filterM (runQuery checkDock) wins
+    forM_ docks $ \win -> do
+        strut <- getRawStrut win
+        broadcastMessage (UpdateDock win strut)
+    refresh
+
+getRawStrut :: Window -> X (Maybe (Either [CLong] [CLong]))
+getRawStrut w = do
+    msp <- fromMaybe [] <$> getProp32s "_NET_WM_STRUT_PARTIAL" w
+    if null msp
+        then do
+            mp <- fromMaybe [] <$> getProp32s "_NET_WM_STRUT" w
+            if null mp then return Nothing
+                       else return $ Just (Left mp)
+        else return $ Just (Right msp)
+
+getRawStruts :: [Window] -> X (M.Map Window (Maybe (Either [CLong] [CLong])))
+getRawStruts wins = M.fromList <$> zip wins <$> mapM getRawStrut wins
+
+
 -- | Gets the STRUT config, if present, in xmonad gap order
 getStrut :: Window -> X [Strut]
 getStrut w = do
@@ -141,13 +185,17 @@ getStrut w = do
         [(L, l, ly1, ly2), (R, r, ry1, ry2), (U, t, tx1, tx2), (D, b, bx1, bx2)]
     parseStrutPartial _ = []
 
+calcGapForAll :: S.Set Direction2D -> X (Rectangle -> Rectangle)
+calcGapForAll ss = withDisplay $ \dpy -> do
+    rootw <- asks theRoot
+    (_,_,wins) <- io $ queryTree dpy rootw
+    calcGap wins ss
+
 -- | Goes through the list of windows and find the gap so that all
 --   STRUT settings are satisfied.
-calcGap :: S.Set Direction2D -> X (Rectangle -> Rectangle)
-calcGap ss = withDisplay $ \dpy -> do
+calcGap :: [Window] -> S.Set Direction2D -> X (Rectangle -> Rectangle)
+calcGap wins ss = withDisplay $ \dpy -> do
     rootw <- asks theRoot
-    -- We don't keep track of dock like windows, so we find all of them here
-    (_,_,wins) <- io $ queryTree dpy rootw
     struts <- (filter careAbout . concat) `fmap` mapM getStrut wins
 
     -- we grab the window attributes of the root window rather than checking
@@ -170,11 +218,12 @@ avoidStrutsOn :: LayoutClass l a =>
                  [Direction2D]
               -> l a
               -> ModifiedLayout AvoidStruts l a
-avoidStrutsOn ss = ModifiedLayout $ AvoidStruts (S.fromList ss) Nothing
+avoidStrutsOn ss = ModifiedLayout $ AvoidStruts (S.fromList ss) Nothing M.empty
 
 data AvoidStruts a = AvoidStruts {
     avoidStrutsDirection :: S.Set Direction2D,
-    avoidStrutsRectCache :: Maybe (S.Set Direction2D, Rectangle, Rectangle )
+    avoidStrutsRectCache :: Maybe (S.Set Direction2D, Rectangle, Rectangle),
+    strutMap :: M.Map Window (Maybe (Either [CLong] [CLong]))
 }  deriving ( Read, Show )
 
 -- | Message type which can be sent to an 'AvoidStruts' layout
@@ -188,9 +237,11 @@ instance Message ToggleStruts
 
 -- | message sent to ensure that caching the gaps won't give a wrong result
 -- because a new dock has been added
-data ClearGapCache = ClearGapCache
+data DockMessage = UpdateDock Window (Maybe (Either [CLong] [CLong]))
+                 | RemoveDock Window
   deriving (Read,Show,Typeable)
-instance Message ClearGapCache
+instance Message DockMessage
+
 
 -- | SetStruts is a message constructor used to set or unset specific struts,
 -- regardless of whether or not the struts were originally set. Here are some
@@ -219,26 +270,45 @@ data SetStruts = SetStruts { addedStruts   :: [Direction2D]
 instance Message SetStruts
 
 instance LayoutModifier AvoidStruts a where
-    modifyLayoutWithUpdate as@(AvoidStruts ss cache) w r = do
-        nr <- case cache of
-            Just (ss', r', nr) | ss' == ss, r' == r -> return nr
+    modifyLayoutWithUpdate as@(AvoidStruts ss cache smap) w r = do
+        let dockWins = M.keys smap
+        nsmap <- getRawStruts dockWins
+        (nr, nsmap) <- case cache of
+            Just (ss', r', nr) | ss' == ss, r' == r -> do
+                nsmap <- getRawStruts dockWins
+                if nsmap /= smap
+                  then do
+                    nr <- fmap ($ r) (calcGap dockWins ss)
+                    setWorkarea nr
+                    return (nr, nsmap)
+                  else do
+                    return (nr, smap)
             _ -> do
-                nr <- fmap ($ r) (calcGap ss)
+                nsset <- getRawStruts dockWins
+                nr <- fmap ($ r) (calcGap dockWins ss)
                 setWorkarea nr
-                return nr
+                return (nr, nsset)
         arranged <- runLayout w nr
         let newCache = Just (ss, r, nr)
-        return (arranged, if newCache == cache
+        return (arranged, if newCache == cache && smap == nsmap
                     then Nothing
-                    else Just as{ avoidStrutsRectCache = newCache } )
+                    else Just as { avoidStrutsRectCache = newCache
+                                 , strutMap = nsmap })
 
-    pureMess as@(AvoidStruts { avoidStrutsDirection = ss }) m
+    pureMess as@(AvoidStruts { avoidStrutsDirection = ss, strutMap = sm }) m
         | Just ToggleStruts    <- fromMessage m = Just $ as { avoidStrutsDirection = toggleAll ss }
         | Just (ToggleStrut s) <- fromMessage m = Just $ as { avoidStrutsDirection = toggleOne s ss }
         | Just (SetStruts n k) <- fromMessage m
         , let newSS = S.fromList n `S.union` (ss S.\\ S.fromList k)
         , newSS /= ss = Just $ as { avoidStrutsDirection = newSS }
-        | Just ClearGapCache <- fromMessage m = Just $ as { avoidStrutsRectCache = Nothing }
+        | Just (UpdateDock dock strut) <- fromMessage m = if maybe True (/= strut) (M.lookup dock sm)
+                                            then Just $ as { avoidStrutsRectCache = Nothing
+                                                           , strutMap = M.insert dock strut sm }
+                                            else Nothing
+        | Just (RemoveDock dock) <- fromMessage m = if M.member dock sm
+                                            then Just $ as { avoidStrutsRectCache = Nothing
+                                                           , strutMap = M.delete dock sm }
+                                            else Nothing
         | otherwise = Nothing
       where toggleAll x | S.null x = S.fromList [minBound .. maxBound]
                         | otherwise = S.empty
diff --git a/XMonad/Hooks/PositionStoreHooks.hs b/XMonad/Hooks/PositionStoreHooks.hs
index 17ef59b..4e21caf 100644
--- a/XMonad/Hooks/PositionStoreHooks.hs
+++ b/XMonad/Hooks/PositionStoreHooks.hs
@@ -88,9 +88,11 @@ positionStoreInit mDecoTheme w  = withDisplay $ \d -> do
             else do
                 sc <- fromMaybe (W.current ws) <$> pointScreen (fi $ wa_x wa) (fi $ wa_y wa)
                 let sr = screenRect . W.screenDetail $ sc
-                sr' <- fmap ($ sr) (calcGap $ S.fromList [minBound .. maxBound])    -- take docks into account, accepting
-                                                                                    -- a somewhat unfortunate inter-dependency
-                                                                                    -- with 'XMonad.Hooks.ManageDocks'
+                rootw <- asks theRoot
+                (_,_,wins) <- io $ queryTree d rootw
+                sr' <- fmap ($ sr) (calcGapForAll $ S.fromList [minBound .. maxBound]) -- take docks into account, accepting
+                                                                                       -- a somewhat unfortunate inter-dependency
+                                                                                       -- with 'XMonad.Hooks.ManageDocks'
                 modifyPosStore (\ps -> posStoreInsert ps w
                                         (Rectangle (fi $ wa_x wa) (fi (wa_y wa) - fi decoH)
                                             (fi $ wa_width wa) (decoH + fi (wa_height wa))) sr' )
diff --git a/XMonad/Layout/DecorationAddons.hs b/XMonad/Layout/DecorationAddons.hs
index 0f4a799..9a7e23a 100644
--- a/XMonad/Layout/DecorationAddons.hs
+++ b/XMonad/Layout/DecorationAddons.hs
@@ -106,8 +106,8 @@ handleScreenCrossing w decoWin = withDisplay $ \d -> do
                         {-- 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])
+                        oldScreenRect' <- fmap ($ oldScreenRect) (calcGapForAll $ S.fromList [minBound .. maxBound])
+                        newScreenRect' <- fmap ($ newScreenRect) (calcGapForAll $ S.fromList [minBound .. maxBound])
                         wa <- io $ getWindowAttributes d decoWin
                         modifyPosStore (\ps ->
                             posStoreMove ps w (fi $ wa_x wa) (fi $ wa_y wa)
-- 
2.8.1

Attachment: signature.asc
Description: PGP signature

_______________________________________________
Pkg-haskell-maintainers mailing list
Pkg-haskell-maintainers@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-haskell-maintainers

Reply via email to