From 5ce50a3cc01973ecb9f6fe78c9172c08ee34adba Mon Sep 17 00:00:00 2001 From: Daniel Schoepe Date: Tue, 7 Apr 2009 19:18:19 +0000 Subject: [PATCH] Update focus on mouse moves within inactive windows This patch adds functionality to update the focus on moves in unfocused windows, which would make sense if one wanted the focus to follow the mouse. Currently this only happens when the mouse enters/leaves a window. This patch should fix issue #205. --- XMonad/Actions/UpdateFocus.hs | 61 +++++++++++++++++++++++++++++++++++ xmonad-contrib.cabal | 1 + 2 files changed, 62 insertions(+) create mode 100644 XMonad/Actions/UpdateFocus.hs diff --git a/XMonad/Actions/UpdateFocus.hs b/XMonad/Actions/UpdateFocus.hs new file mode 100644 index 00000000..fb51ea36 --- /dev/null +++ b/XMonad/Actions/UpdateFocus.hs @@ -0,0 +1,61 @@ +----------------------------------------------------------------------------- +-- | +-- Module : XMonadContrib.UpdateFocus +-- Copyright : (c) Daniel Schoepe +-- License : BSD3-style (see LICENSE) +-- +-- Maintainer : Daniel Schoepe +-- Stability : unstable +-- Portability : unportable +-- +-- Updates the focus on mouse move in unfocused windows. +-- +----------------------------------------------------------------------------- + +module XMonad.Actions.UpdateFocus ( + -- * Usage + -- $usage + focusOnMouseMove, + adjustEventInput +) where + +import XMonad +import qualified XMonad.StackSet as W +import Graphics.X11.Xlib.Extras +import Control.Monad (when) +import Data.Monoid + +-- $usage +-- To make the focus update on mouse movement within an unfocused window, add the +-- following to your @~\/.xmonad\/xmonad.hs@: +-- +-- > import XMonad.Actions.UpdateFocus +-- > xmonad $ defaultConfig { +-- > .. +-- > 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 (MotionEvent { ev_x = x, ev_y = y, ev_window = root }) = do + -- check only every 15 px to avoid excessive calls to translateCoordinates + when (x `mod` 15 == 0 || y `mod` 15 == 0) $ do + dpy <- asks display + Just foc <- withWindowSet $ return . W.peek + -- get the window under the pointer: + (_,_,_,w) <- io $ translateCoordinates dpy root root (fromIntegral x) (fromIntegral y) + when (foc /= w) $ focus w + return (All True) +focusOnMouseMove _ = return (All True) + +-- | Adjusts the event mask to pick up pointer movements. +adjustEventInput :: X () +adjustEventInput = withDisplay $ \dpy -> do + rootw <- asks theRoot + io $ selectInput dpy rootw $ substructureRedirectMask .|. substructureNotifyMask + .|. enterWindowMask .|. leaveWindowMask .|. structureNotifyMask + .|. buttonPressMask .|. pointerMotionMask \ No newline at end of file diff --git a/xmonad-contrib.cabal b/xmonad-contrib.cabal index ce8a82e3..e092dbf2 100644 --- a/xmonad-contrib.cabal +++ b/xmonad-contrib.cabal @@ -98,6 +98,7 @@ library XMonad.Actions.TagWindows XMonad.Actions.TopicSpace XMonad.Actions.UpdatePointer + XMonad.Actions.UpdateFocus XMonad.Actions.Warp XMonad.Actions.WindowNavigation XMonad.Actions.WindowGo