xmonad-contrib icon indicating copy to clipboard operation
xmonad-contrib copied to clipboard

Previously floating fullscreen windows tiles after leaving fullscreen

Open toniz4 opened this issue 4 years ago • 9 comments

Problem Description

When opening a floating window, entering fullscreen with fullscreenEventHook and leaving fullscreen the window tiles instead of floating again.

Configuration File

Please include the smallest configuration file that reproduces the problem you are experiencing:

module Main (main) where

import XMonad
import XMonad.Hooks.EwmhDesktops
import qualified XMonad.StackSet as W
import qualified Data.Map        as M

main :: IO ()
main = xmonad def {
  handleEventHook = fullscreenEventHook,
  mouseBindings   = myMouseBindings
  }
  

myMouseBindings :: XConfig l -> M.Map (KeyMask, Button) (Window -> X())
myMouseBindings (XConfig {XMonad.modMask = modm}) = M.fromList $

    [ ((modm, button1), (\w -> focus w >> mouseMoveWindow w
                                       >> windows W.shiftMaster))

    , ((modm, button2), (\w -> focus w >> windows W.shiftMaster))

    , ((modm, button3), (\w -> focus w >> mouseResizeWindow w
                                       >> windows W.shiftMaster))

    ]

Checklist

toniz4 avatar Jan 30 '21 09:01 toniz4

This is due to this line simply sinking the window when fullscreen is removed; I guess the stackset could have changed in the meantime and for tiled windows trying to restore some sort of "previous position" is practically impossible.

I wonder if it's worth making an exception for floating windows here; what do other people think?

slotThe avatar Jan 30 '21 10:01 slotThe

simply sinking the window trying to restore some sort of "previous position" is practically impossible

If the stackset doesn't change, then "simply sinking the window" does restore its original position. When I fullscreen a tiled window and then unfullscreen it, everything is back to where it was. If the window is moved in between, then the stackset is changed and when it sinks, it sinks into the master position or something, but I'd argue that stackset changing during fullscreen isn't all that likely.

But floats… everything related to floats in xmonad is quite a hack, and fullscreening/maximization is a hack on top of a hack. :-( There's X.L.Fullscreen and X.L.Maximize, but they probably don't work with floats either. I wish floats weren't handled by the core at all but needed a layout modified instead, then we'd just slap the Fullscreen layout mod on top of the floating modified and everything would just work. With things as they are now, we can sure save the original float position in some extensible state in EwmhDesktops, but then any manual fullscreening or moving will result in weirdness as that will bypass this EwmhDesktops state tracking. (And I'm saying this as someone who would actually love to have this fixed, including being able to manually fullscreen floating windows and then have them go back to where they were.)

That being said, maybe it's still worth it? A simple extensible state with M.Map Window RationalRect for saving the original floating state (if the window is tiling, save the state by ensuring the Window is not in the map). If we export this and a couple helpers, I could then wire this into my toggleFullscreen and have the desired behaviour.

Oh and it seems there already is something similar: XMonad.Util.PositionStore, XMonad.Hooks.PositionStoreHooks, XMonad.Layout.PositionStoreFloat. XMonad.Util.PositionStore implements the extensible state. The rest implements layout-based floating, which (afaik) unfortunately needs decorations for moving windows, so that's not something that is widely used I'm afraid. Also not sure if it's okay to wire XMonad.Util.PositionStore into EwmhDesktops. It's definitely something one can play with, but it's a bit more difficult when compatibility with existing users' setups should be kept. :-/

liskin avatar Jan 30 '21 10:01 liskin

But! Maybe we can add some fullscreen/unfullscreen hooks to #399, which would then enable users to customize the behaviour, other module authors to add integrations with EwmhDesktops, and so on. That seems like something I can experiment with, even exploit as a motivation to get back to #399. :-)

liskin avatar Jan 30 '21 10:01 liskin

Dwm handles this by saving the previous state, height, width and cords of a window, and when getting back from fullscreen it just restores those values. It should be possible to do this with xmonad, but haskell still looks like a alien language to me.

toniz4 avatar Jan 30 '21 12:01 toniz4

If the stackset doesn't change, then "simply sinking the window" does restore its original position. When I fullscreen a tiled window and then unfullscreen it, everything is back to where it was. If the window is moved in between, then the stackset is changed and when it sinks, it sinks into the master position or something, but I'd argue that stackset changing during fullscreen isn't all that likely.

Oh, well TIL then, thanks! Maybe this looks how much I value floating windows in general :>

Dwm handles this by saving the previous state, height, width and cords of a window, and when getting back from fullscreen it just restores those values. It should be possible to do this with xmonad, but haskell still looks like a alien language to me.

Yes this was basically the idea here:

That being said, maybe it's still worth it? A simple extensible state with M.Map Window RationalRect for saving the original floating state (if the window is tiling, save the state by ensuring the Window is not in the map). If we export this and a couple helpers, I could then wire this into my toggleFullscreen and have the desired behaviour.

I have to say that wiring something into #399 sounds pretty awesome to me (if only because then that gets worked on and the last real blocker for 0.17 vanishes :>)

slotThe avatar Jan 30 '21 12:01 slotThe

Yeah, it all seems to fit into the puzzle. With (un)fullscreen hooks in EwmhDesktop, even X.L.Fullscreen can hook into it and make the two cooperate cleanly. That might be a considerable win. I'm excited. :-)

liskin avatar Jan 30 '21 13:01 liskin

what do other people think?

I think the floating window should remain floating. The fact that it becomes tiling is not intuitive. But, as far as I understand, it is not so easy to implement now :).

PRESFIL avatar May 09 '21 14:05 PRESFIL

Not that difficult, either: remember its state in XS on entering fullscreen, use saved state to put it back floating or tiled afterward, include an extra hook for delete window to clean up the state if it's closed while still fullscreen. The truly difficult one would be trying to remember its exact state in the tile, since it'd be dependent on the layout in question and might change.

geekosaur avatar May 09 '21 14:05 geekosaur

I'd advice using the layout modifiers in XMonad.Layout.Fullscreen instead if you want this behavior.

audunska avatar Jan 13 '22 19:01 audunska