haskellxlibxmonad

XMonad, spawn floating window right above focused window


I am trying to spawn a floating window whose screen position would match currently focused, tiled or itself floating, window.

I am assuming the spawn command itself should reside inside keys list (like all other commands) while layout should reside in manageHook. I can distinguish the window precisely by setting unique WM_NAME (urxvt makes that easy), and I can access currently focused window inside keys list; however, I don't know if there's a proper, built-in/non-dirty way of passing this information downwards into the manageHook.

In addition, I am assuming (perhaps wrongly?) that during layout, focused window is going to be the newly spawned window - so I can't access it there inside layout code.

Three ideas I have (descending order of hacky):

All these seem a bit hacky; is there a better way?


Solution

  • Don't make this part of the spawning command, making it part of your ManageHook. Basic usage is like

    className "my-unique-class" --> doRectFloat blah
    

    where figuring out what to put in blah is probably the most annoying part. You can fetch the window's ID with ask, and the current layout with liftX (gets (layout . workspace . current . windowset)). I can't think of a good way to work out the rectangle of the currently focused window other than to then manually run that layout with doLayout, then search its output for the currently-focused window's ID. The values you need as the other arguments are also lurking in the windowset in various places, as well as the window ID of the currently focused window. So a sketch would look like:

    className "my-unique-class" --> do
        ws <- liftX (gets (current . windowset))
        case stack (workspace ws) of
            Nothing -> -- what do you want to do when there's no windows?
            Just st -> do
                (rects, _) <- liftX $ doLayout (layout $ workspace ws) (screenRect (screenDetail ws)) (stack (workspace ws))
                case lookup (focus st) rects of
                    Nothing -> -- what do you want to do when the layout doesn't display the currently focused window?
                    Just rect -> -- use rect and screenRect (screenDetail ws)