From cf13f8f9a7acddc1134be3f71097633def1476a8 Mon Sep 17 00:00:00 2001
From: patrick brisbin <pbrisbin@gmail.com>
Date: Wed, 4 Jan 2023 15:23:48 -0500
Subject: [PATCH] X.H.EwmhDesktops: Add disableEwmhManageDesktopViewport

This combinator forces XMonad to *not* set _NET_DESKTOP_VIEWPORT.

This information is picked up by polybar's xworkspaces module and used
to re-group the workspaces by monitor. I (and others) find this super
confusing, but polybar doesn't not seem open to addressing it.

https://github.com/polybar/polybar/issues/2603

Opting in to the old behavior of not managing this property is one way
to work around it instead.
---
 CHANGES.md                   |  7 +++++++
 XMonad/Hooks/EwmhDesktops.hs | 36 ++++++++++++++++++++++++++++++++----
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index f04210bc..d033aac6 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -144,6 +144,13 @@
     - Fixed an issue where the bottom right window would not respond to
       `MirrorShrink` and `MirrorExpand` messages.
 
+  * `XMonad.Hooks.EwmhDesktops`
+
+    - Added `disableEwmhManageDesktopViewport` to avoid setting the
+      `_NET_DESKTOP_VIEWPORT` property, as it can lead to issues with
+      some status bars (see this
+      [polybar issue](https://github.com/polybar/polybar/issues/2603)).
+
 ### Other changes
 
 ## 0.17.1 (September 3, 2022)
diff --git a/XMonad/Hooks/EwmhDesktops.hs b/XMonad/Hooks/EwmhDesktops.hs
index 584684e8..85b27e68 100644
--- a/XMonad/Hooks/EwmhDesktops.hs
+++ b/XMonad/Hooks/EwmhDesktops.hs
@@ -40,6 +40,10 @@ module XMonad.Hooks.EwmhDesktops (
     -- $customActivate
     setEwmhActivateHook,
 
+    -- ** @_NET_DESKTOP_VIEWPORT@
+    -- $customManageDesktopViewport
+    disableEwmhManageDesktopViewport,
+
     -- * Standalone hooks (deprecated)
     ewmhDesktopsStartup,
     ewmhDesktopsLogHook,
@@ -102,6 +106,8 @@ data EwmhDesktopsConfig =
             -- ^ configurable workspace rename (see 'XMonad.Hooks.StatusBar.PP.ppRename')
         , activateHook :: ManageHook
             -- ^ configurable handling of window activation requests
+        , manageDesktopViewport :: Bool
+            -- ^ manage @_NET_DESKTOP_VIEWPORT@?
         }
 
 instance Default EwmhDesktopsConfig where
@@ -109,6 +115,7 @@ instance Default EwmhDesktopsConfig where
         { workspaceSort = getSortByIndex
         , workspaceRename = pure pure
         , activateHook = doFocus
+        , manageDesktopViewport = True
         }
 
 
@@ -228,6 +235,26 @@ setEwmhWorkspaceRename f = XC.modifyDef $ \c -> c{ workspaceRename = f }
 setEwmhActivateHook :: ManageHook -> XConfig l -> XConfig l
 setEwmhActivateHook h = XC.modifyDef $ \c -> c{ activateHook = h }
 
+-- $customManageDesktopViewport
+-- Setting @_NET_DESKTOP_VIEWPORT@ is typically desired but can lead to a
+-- confusing workspace list in polybar, where this information is used to
+-- re-group the workspaces by monitor. See
+-- <https://github.com/polybar/polybar/issues/2603 polybar#2603>.
+--
+-- To avoid this, you can use:
+--
+-- > main = xmonad $ … . disableEwmhManageDesktopViewport . ewmh . … $ def{…}
+--
+-- Note that if you apply this configuration in an already running environment,
+-- the property may remain at its previous value. It can be removed by running:
+--
+-- > xprop -root -remove _NET_DESKTOP_VIEWPORT
+--
+-- Which should immediately fix your bar.
+--
+disableEwmhManageDesktopViewport :: XConfig l -> XConfig l
+disableEwmhManageDesktopViewport = XC.modifyDef $ \c -> c{ manageDesktopViewport = False }
+
 
 -- | Initializes EwmhDesktops and advertises EWMH support to the X server.
 {-# DEPRECATED ewmhDesktopsStartup "Use ewmh instead." #-}
@@ -303,7 +330,7 @@ whenChanged :: (Eq a, ExtensionClass a) => a -> X () -> X ()
 whenChanged = whenX . XS.modified . const
 
 ewmhDesktopsLogHook' :: EwmhDesktopsConfig -> X ()
-ewmhDesktopsLogHook' EwmhDesktopsConfig{workspaceSort, workspaceRename} = withWindowSet $ \s -> do
+ewmhDesktopsLogHook' EwmhDesktopsConfig{workspaceSort, workspaceRename, manageDesktopViewport} = withWindowSet $ \s -> do
     sort' <- workspaceSort
     let ws = sort' $ W.workspaces s
 
@@ -365,9 +392,10 @@ ewmhDesktopsLogHook' EwmhDesktopsConfig{workspaceSort, workspaceRename} = withWi
     whenChanged (ActiveWindow activeWindow') $ setActiveWindow activeWindow'
 
     -- Set desktop Viewport
-    let visibleScreens = W.current s : W.visible s
-        currentTags    = map (W.tag . W.workspace) visibleScreens
-    whenChanged (MonitorTags currentTags) $ mkViewPorts s (map W.tag ws)
+    when manageDesktopViewport $ do
+        let visibleScreens = W.current s : W.visible s
+            currentTags    = map (W.tag . W.workspace) visibleScreens
+        whenChanged (MonitorTags currentTags) $ mkViewPorts s (map W.tag ws)
 
 -- | Create the viewports from the current 'WindowSet' and a list of
 -- already sorted workspace IDs.