    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Actions.UpdateFocus
    -- Description :  Updates the focus on mouse move in unfocused windows.
    -- Copyright   :  (c) Daniel Schoepe
    -- License     :  BSD3-style (see LICENSE)
    --
    -- Maintainer  :  Daniel Schoepe <asgaroth_@gmx.de>
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- Updates the focus on mouse move in unfocused windows.
    --
    -----------------------------------------------------------------------------

    module XMonad.Actions.UpdateFocus (
        -- * Usage
        -- $usage
        focusOnMouseMove,
        adjustEventInput,
        focusUnderPointer,
    ) where

    import XMonad
    import XMonad.Prelude
    import qualified XMonad.StackSet as W

    -- $usage
    -- To make the focus update on mouse movement within an unfocused window, add the
    -- following to your @xmonad.hs@:
    --
    -- > import XMonad.Actions.UpdateFocus
    -- > xmonad $ def {
    -- >   ..
    -- >   startupHook = adjustEventInput
    -- >   handleEventHook = focusOnMouseMove
    -- >   ..
    -- > }
    --
    -- This module is probably only useful when focusFollowsMouse is set to True(default).

    -- | Changes the focus if the mouse is moved within an unfocused window.
    focusOnMouseMove :: Event -> X All
    focusOnMouseMove :: Event -> X All
    focusOnMouseMove MotionEvent{ ev_x :: Event -> CInt
    ev_x = CInt
    x, ev_y :: Event -> CInt
    ev_y = CInt
    y, ev_window :: Event -> Window
    ev_window = Window
    root } = do
        -- check only every 15 px to avoid excessive calls to translateCoordinates
        Bool -> X () -> X ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (CInt
    x CInt -> CInt -> CInt
    forall a. Integral a => a -> a -> a
    `mod` CInt
    15 CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == CInt
    0 Bool -> Bool -> Bool
    || CInt
    y CInt -> CInt -> CInt
    forall a. Integral a => a -> a -> a
    `mod` CInt
    15 CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == CInt
    0) (X () -> X ()) -> X () -> X ()
    forall a b. (a -> b) -> a -> b
    $ do
          Display
    dpy <- (XConf -> Display) -> X Display
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks XConf -> Display
    display
          Maybe Window
    foc <- (WindowSet -> X (Maybe Window)) -> X (Maybe Window)
    forall a. (WindowSet -> X a) -> X a
    withWindowSet ((WindowSet -> X (Maybe Window)) -> X (Maybe Window))
    -> (WindowSet -> X (Maybe Window)) -> X (Maybe Window)
    forall a b. (a -> b) -> a -> b
    $ Maybe Window -> X (Maybe Window)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe Window -> X (Maybe Window))
    -> (WindowSet -> Maybe Window) -> WindowSet -> X (Maybe Window)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSet -> Maybe Window
    forall i l a s sd. StackSet i l a s sd -> Maybe a
    W.peek
          -- get the window under the pointer:
          (Bool
    _,Position
    _,Position
    _,Window
    w) <- IO (Bool, Position, Position, Window)
    -> X (Bool, Position, Position, Window)
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    io (IO (Bool, Position, Position, Window)
     -> X (Bool, Position, Position, Window))
    -> IO (Bool, Position, Position, Window)
    -> X (Bool, Position, Position, Window)
    forall a b. (a -> b) -> a -> b
    $ Display
    -> Window
    -> Window
    -> Position
    -> Position
    -> IO (Bool, Position, Position, Window)
    translateCoordinates Display
    dpy Window
    root Window
    root (CInt -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral CInt
    x) (CInt -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral CInt
    y)
          Bool -> X () -> X ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Maybe Window
    foc Maybe Window -> Maybe Window -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Window -> Maybe Window
    forall a. a -> Maybe a
    Just Window
    w) (X () -> X ()) -> X () -> X ()
    forall a b. (a -> b) -> a -> b
    $ Window -> X ()
    focus Window
    w
        All -> X All
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> All
    All Bool
    True)
    focusOnMouseMove Event
    _ = All -> X All
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> All
    All Bool
    True)

    -- | Adjusts the event mask to pick up pointer movements.
    adjustEventInput :: X ()
    adjustEventInput :: X ()
    adjustEventInput = (Display -> X ()) -> X ()
    forall a. (Display -> X a) -> X a
    withDisplay ((Display -> X ()) -> X ()) -> (Display -> X ()) -> X ()
    forall a b. (a -> b) -> a -> b
    $ \Display
    dpy -> do
      Window
    rootw <- (XConf -> Window) -> X Window
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks XConf -> Window
    theRoot
      IO () -> X ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    io (IO () -> X ()) -> IO () -> X ()
    forall a b. (a -> b) -> a -> b
    $ Display -> Window -> Window -> IO ()
    selectInput Display
    dpy Window
    rootw (Window -> IO ()) -> Window -> IO ()
    forall a b. (a -> b) -> a -> b
    $  Window
    substructureRedirectMask Window -> Window -> Window
    forall a. Bits a => a -> a -> a
    .|. Window
    substructureNotifyMask
                                    Window -> Window -> Window
    forall a. Bits a => a -> a -> a
    .|. Window
    enterWindowMask Window -> Window -> Window
    forall a. Bits a => a -> a -> a
    .|. Window
    leaveWindowMask Window -> Window -> Window
    forall a. Bits a => a -> a -> a
    .|. Window
    structureNotifyMask
                                    Window -> Window -> Window
    forall a. Bits a => a -> a -> a
    .|. Window
    buttonPressMask Window -> Window -> Window
    forall a. Bits a => a -> a -> a
    .|. Window
    pointerMotionMask

    -- | Focus the window under the mouse pointer, unless we're currently changing
    -- focus with the mouse or dragging. This is the inverse to
    -- "XMonad.Actions.UpdatePointer": instead of moving the mouse pointer to
    -- match the focus, we change the focus to match the mouse pointer.
    --
    -- This is meant to be used together with
    -- 'XMonad.Actions.UpdatePointer.updatePointer' in individual key bindings.
    -- Bindings that change focus should invoke
    -- 'XMonad.Actions.UpdatePointer.updatePointer' at the end, bindings that
    -- switch workspaces or change layouts should call 'focusUnderPointer' at the
    -- end. Neither should go to 'logHook', as that would override the other.
    --
    -- This is more finicky to set up than 'focusOnMouseMove', but ensures that
    -- focus is updated immediately, without having to touch the mouse.
    focusUnderPointer :: X ()
    focusUnderPointer :: X ()
    focusUnderPointer = X Bool -> X () -> X ()
    whenX (Bool -> Bool
    not (Bool -> Bool) -> X Bool -> X Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ((XConf -> Bool) -> X Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks XConf -> Bool
    mouseFocused X Bool -> X Bool -> X Bool
    forall (m :: * -> *). Monad m => m Bool -> m Bool -> m Bool
    <||> (XState -> Bool) -> X Bool
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets (Maybe (Position -> Position -> X (), X ()) -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe (Position -> Position -> X (), X ()) -> Bool)
    -> (XState -> Maybe (Position -> Position -> X (), X ()))
    -> XState
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . XState -> Maybe (Position -> Position -> X (), X ())
    dragging))) (X () -> X ()) -> X () -> X ()
    forall a b. (a -> b) -> a -> b
    $ do
      Display
    dpy <- (XConf -> Display) -> X Display
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks XConf -> Display
    display
      Window
    root <- (XConf -> Window) -> X Window
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks XConf -> Window
    theRoot
      (Bool
    _, Window
    _, Window
    w', CInt
    _, CInt
    _, CInt
    _, CInt
    _, Modifier
    _) <- IO (Bool, Window, Window, CInt, CInt, CInt, CInt, Modifier)
    -> X (Bool, Window, Window, CInt, CInt, CInt, CInt, Modifier)
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    io (IO (Bool, Window, Window, CInt, CInt, CInt, CInt, Modifier)
     -> X (Bool, Window, Window, CInt, CInt, CInt, CInt, Modifier))
    -> IO (Bool, Window, Window, CInt, CInt, CInt, CInt, Modifier)
    -> X (Bool, Window, Window, CInt, CInt, CInt, CInt, Modifier)
    forall a b. (a -> b) -> a -> b
    $ Display
    -> Window
    -> IO (Bool, Window, Window, CInt, CInt, CInt, CInt, Modifier)
    queryPointer Display
    dpy Window
    root
      Maybe Window
    w <- (XState -> Maybe Window) -> X (Maybe Window)
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets (WindowSet -> Maybe Window
    forall i l a s sd. StackSet i l a s sd -> Maybe a
    W.peek (WindowSet -> Maybe Window)
    -> (XState -> WindowSet) -> XState -> Maybe Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . XState -> WindowSet
    windowset)
      Bool -> X () -> X ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Window
    w' Window -> Window -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Window
    none Bool -> Bool -> Bool
    && Window -> Maybe Window
    forall a. a -> Maybe a
    Just Window
    w' Maybe Window -> Maybe Window -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Maybe Window
    w) (Window -> X ()
    focus Window
    w')