mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-07-31 04:01:51 -07:00
X.H.WindowSwallowing: Fix single window getting lost
ConfigureEvents may occur after a window has been deleted, an UnmapEvent has already been sent (and thus xmonad already unmanaged the window), but before a DestroyWindowEvent is caught by the eventHook. For example, this is the case when one uses smartBorders with a single window (such that smartBorders is "active"). The ConfigureEvents sensibly already have an empty stack (because the UnmapEvent has already been received), which we then copy to the history. Whenever a parent window has been found, the sensible thing to do is to always restore it. The fact that oldStack is Nothing simply encodes an empty workspace and is thus something we definitely need to handle as well. Fixes: https://github.com/xmonad/xmonad-contrib/issues/638
This commit is contained in:
@@ -155,14 +155,19 @@ swallowEventHook parentQ childQ event = do
|
||||
maybeOldStack <- XS.gets stackBeforeWindowClosing
|
||||
oldFloating <- XS.gets floatingBeforeClosing
|
||||
case (maybeSwallowedParent, maybeOldStack) of
|
||||
-- If there actually is a corresponding swallowed parent window for this window,
|
||||
-- we will try to restore it.
|
||||
-- Because there are some cases where the stack-state is not stored correctly in the ConfigureEvent hook,
|
||||
-- we have to first check if the stack-state is valid.
|
||||
-- If it is, we can restore the parent exactly where the child window was before being closed.
|
||||
-- If the stored stack-state is invalid however, we still restore the window
|
||||
-- by just inserting it as the focused window in the stack.
|
||||
--
|
||||
-- After restoring, we remove the information about the swallowing from the state.
|
||||
(Just parent, Nothing) -> do
|
||||
windows (insertIntoStack parent)
|
||||
deleteState childWindow
|
||||
(Just parent, Just oldStack) -> do
|
||||
-- If there actually is a corresponding swallowed parent window for this window,
|
||||
-- we will try to restore it.
|
||||
-- because there are some cases where the stack-state is not stored correctly in the ConfigureEvent hook,
|
||||
-- we have to first check if the stack-state is valid.
|
||||
-- if it is, we can restore the parent exactly where the child window was before being closed
|
||||
-- if the stored stack-state is invalid however, we still restore the window
|
||||
-- by just inserting it as the focused window in the stack.
|
||||
stackStoredCorrectly <- do
|
||||
curStack <- withWindowSet (return . currentStack)
|
||||
let oldLen = length (W.integrate oldStack)
|
||||
@@ -178,13 +183,15 @@ swallowEventHook parentQ childQ event = do
|
||||
$ ws { W.floating = oldFloating }
|
||||
)
|
||||
else windows (insertIntoStack parent)
|
||||
-- after restoring, we remove the information about the swallowing from the state.
|
||||
XS.modify $ removeSwallowed childWindow
|
||||
XS.modify $ setStackBeforeWindowClosing Nothing
|
||||
deleteState childWindow
|
||||
_ -> return ()
|
||||
return ()
|
||||
_ -> return ()
|
||||
return $ All True
|
||||
where
|
||||
deleteState :: Window -> X ()
|
||||
deleteState childWindow = do
|
||||
XS.modify $ removeSwallowed childWindow
|
||||
XS.modify $ setStackBeforeWindowClosing Nothing
|
||||
|
||||
-- | insert a window as focused into the current stack, moving the previously focused window down the stack
|
||||
insertIntoStack :: a -> W.StackSet i l a sid sd -> W.StackSet i l a sid sd
|
||||
|
Reference in New Issue
Block a user