xmonad / xmonad-contrib

Contributed modules for xmonad

Home Page:https://xmonad.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NamedScratchpad with nsHideOnFocusLoss does not show on workspace that has never had windows

glward opened this issue · comments

Problem Description

When using NamedScratchpads in combination with the nsHideOnFocusLoss hook, scratchpads do not show on workspaces unless they have had at least one window displayed on them since XMonad started.

Steps to Reproduce

  1. Start with minimal configuration below
  2. Attempt to spawn scratchpad. Nothing is shown
  3. Spawn a new window on the current workspace (and close it, even)
  4. Attempt to spawn scratchpad. Scratchpad spawns as normal
  5. Repeat for any workspaces that have never had any open windows on them

You can repeat the above steps with the log hook commented out and observe that it works as expected at step 2: even on a completely empty workspace that has never had windows, the scratchpad appears and disappears as expected. Pure speculation on my part, but I wonder if refocusLastLogHook has subtly different state on completely empty workspaces vs ones that had windows that are now closed.

Configuration File

Based on the config in #730 with added nsHideOnFocusLoss hook.

import XMonad
import XMonad.StackSet
import XMonad.Hooks.RefocusLast
import XMonad.Util.EZConfig (additionalKeysP)
import XMonad.Util.NamedScratchpad

main :: IO ()
main = xmonad $ def
  { manageHook = manageHook def <> namedScratchpadManageHook scratchpads
  , logHook = refocusLastLogHook >> nsHideOnFocusLoss scratchpads
}
 `additionalKeysP` [("M-m", namedScratchpadAction scratchpads "xterm")]

scratchpads :: [NamedScratchpad]
scratchpads =
  [NS "xterm"
      "xterm"
      (className =? "XTerm")
      (customFloating $ RationalRect (1 / 6) (1 / 6) (2 / 3) (2 / 3))]

Checklist

  • I've read CONTRIBUTING.md

  • I tested my configuration

    • With xmonad version v0.17.1 (commit 5cdddab1f156c7470d51aee445a00823dad604c1)
    • With xmonad-contrib commit 8546ea095b4d9959190d0853b405cdcda5c7ef9f

Thanks! The issue is actually less related to #728 and more to how nsHideOnFocusLoss handles what're the current and last focused windows.

Could you try the following patch to see if that fixes the issue?

From 54dd06cf67dff8340ceb8005716868e766037ccd Mon Sep 17 00:00:00 2001
From: Tony Zorman <soliditsallgood@mailbox.org>
Date: Sun, 20 Nov 2022 08:06:07 +0100
Subject: [PATCH] X.U.NamedScratchpads: Check for "new" workspace in
 nsHideOnFocusLoss

When XMonad was recently restarted, it can happen that the workspace
history is empty, hence the last focused window could actually be the
currently focused one.  In that case, we don't want to go through the
machinery of looking to hide any NSPs, as there is only one window in
the current workspace (the focused one).  This may or may not be a
scratchpad, we don't care.

Fixes: https://github.com/xmonad/xmonad-contrib/issues/779
---
 XMonad/Util/NamedScratchpad.hs | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/XMonad/Util/NamedScratchpad.hs b/XMonad/Util/NamedScratchpad.hs
index 18742e24..f4e9fdc6 100644
--- a/XMonad/Util/NamedScratchpad.hs
+++ b/XMonad/Util/NamedScratchpad.hs
@@ -286,8 +286,15 @@ allNamedScratchpadAction = someNamedScratchpadAction mapM_ runApplication
 nsHideOnFocusLoss :: NamedScratchpads -> X ()
 nsHideOnFocusLoss scratches = withWindowSet $ \winSet -> do
     let cur = W.currentTag winSet
-    withRecentsIn cur () $ \lastFocus _ ->
-        when (lastFocus `elem` W.index winSet && cur /= scratchpadWorkspaceTag) $
+    withRecentsIn cur () $ \lastFocus curFocus -> do
+        let isWorthy =
+              -- Check for the window being on the current workspace; if there
+              -- is no history (i.e., curFocus ≡ lastFocus), don't do anything
+              -- because the potential scratchpad is definitely focused.
+              lastFocus `elem` W.index winSet && lastFocus /= curFocus
+              -- Don't do anything on the NSP workspace, lest the world explodes.
+              && cur /= scratchpadWorkspaceTag
+        when isWorthy $
             whenX (isNSP lastFocus scratches) $
                 shiftToNSP (W.workspaces winSet) ($ lastFocus)
 
-- 
2.38.1

Yep, that seems to fix the issue. Thanks!