xmonad-contrib- Community-maintained extensions for xmonad
Copyright(c) 2018 L. S. Leary
LicenseBSD3-style (see LICENSE)
MaintainerL. S. Leary
Safe HaskellSafe-Inferred



Provides hooks and actions that keep track of recently focused windows on a per workspace basis and automatically refocus the last window on loss of the current (if appropriate as determined by user specified criteria).



To use this module, you must either include refocusLastLogHook in your log hook or refocusLastLayoutHook in your layout hook; don't use both. This suffices to make use of both toggleFocus and shiftRLWhen but will not refocus automatically upon loss of the current window; for that you must include in your event hook refocusLastWhen pred for some valid pred.

The event hooks that trigger refocusing only fire when a window is lost completely, not when it's simply e.g. moved to another workspace. Hence you will need to use shiftRLWhen pred or refocusWhen pred as appropriate if you want the same behaviour in such cases.

Example configuration:

import XMonad
import XMonad.Hooks.RefocusLast
import qualified Data.Map.Strict as M

main :: IO ()
main = xmonad def
    { handleEventHook = refocusLastWhen myPred <> handleEventHook def
    , logHook         = refocusLastLogHook     <> logHook         def
--  , layoutHook      = refocusLastLayoutHook   $  layoutHook      def
    , keys            = refocusLastKeys        <> keys            def
    } where
        myPred = refocusingIsActive <||> isFloat
        refocusLastKeys cnf
          = M.fromList
          $ ((modMask cnf              , xK_a), toggleFocus)
          : ((modMask cnf .|. shiftMask, xK_a), swapWithLast)
          : ((modMask cnf              , xK_b), toggleRefocusing)
          : [ ( (modMask cnf .|. shiftMask, n)
              , windows =<< shiftRLWhen myPred wksp
            | (n, wksp) <- zip [xK_1..xK_9] (workspaces cnf)

refocusLastLogHook :: X () Source #

A log hook recording the current workspace's most recently focused windows into extensible state.

refocusLastLayoutHook :: l a -> ModifiedLayout RefocusLastLayoutHook l a Source #

Records a workspace's recently focused windows into extensible state upon relayout. Potentially a less wasteful alternative to refocusLastLogHook, as it does not run on WM_NAME propertyNotify events.

refocusLastWhen :: Query Bool -> Event -> X All Source #

Given a predicate on the event window determining whether or not to act, construct an event hook that runs iff the core xmonad event handler will unmanage the window, and which shifts focus to the last focused window on the appropriate workspace if desired.


Impure Query Bool predicates on event windows for use as arguments to refocusLastWhen, shiftRLWhen and refocusWhen. Can be combined with <||> or <&&>. Use like e.g.

, handleEventHook = refocusLastWhen refocusingIsActive

or in a keybinding:

windows =<< shiftRLWhen (refocusingIsActive <&&> isFloat) "3"

It's also valid to use a property lookup like className =? "someProgram" as a predicate, and it should function as expected with e.g. shiftRLWhen. In the event hook on the other hand, the window in question has already been unmapped or destroyed, so external lookups to X properties don't work: only the information fossilised in xmonad's state is available.

refocusingIsActive :: Query Bool Source #

Holds iff refocusing is toggled active.

isFloat :: Query Bool Source #

Holds iff the event window is a float.


toggleRefocusing :: X () Source #

Toggle automatic refocusing at runtime. Has no effect unless the refocusingIsActive predicate has been used.

toggleFocus :: X () Source #

Refocuses the previously focused window; acts as a toggle. Is not affected by toggleRefocusing.

swapWithLast :: X () Source #

Swaps the current and previous windows of the current workspace. Is not affected by toggleRefocusing.

refocusWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet) Source #

Given a target workspace and a predicate on its current window, produce a windows suitable function that will refocus that workspace appropriately. Allows you to hook refocusing into any action you can run through windows. See the implementation of shiftRLWhen for a straight-forward usage example.

shiftRLWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet) Source #

Sends the focused window to the specified workspace, refocusing the last focused window if the predicate holds on the current window. Note that the native version of this, windows . W.shift, has a nice property that this does not: shifting a window to another workspace then shifting it back preserves its place in the stack. Can be used in a keybinding like e.g.

windows =<< shiftRLWhen refocusingIsActive "3"


(windows <=< shiftRLWhen refocusingIsActive) "3"

where <=< is imported from Control.Monad.

updateRecentsOn :: WorkspaceId -> X () Source #

Perform an update to the RecentWins for the specified workspace. The RefocusLast log and layout hooks are both implemented trivially in terms of this function. Only exported to aid extensibility.


The types and constructors used in this module are exported principally to aid extensibility; typical users will have nothing to gain from this section.

data RecentWins Source #

Data type holding onto the previous and current Window.




newtype RecentsMap Source #

Newtype wrapper for a Map holding the RecentWins for each workspace. Is an instance of ExtensionClass with persistence of state.

data RefocusLastLayoutHook a Source #

A LayoutModifier that updates the RecentWins for a workspace upon relayout.




Instances details
LayoutModifier RefocusLastLayoutHook a Source # 
Instance details

Defined in XMonad.Hooks.RefocusLast

Read (RefocusLastLayoutHook a) Source # 
Instance details

Defined in XMonad.Hooks.RefocusLast

Show (RefocusLastLayoutHook a) Source # 
Instance details

Defined in XMonad.Hooks.RefocusLast

Library functions

withRecentsIn :: WorkspaceId -> a -> (Window -> Window -> X a) -> X a Source #

Perform an X action dependent on successful lookup of the RecentWins for the specified workspace, or return a default value.