From e7c01f67998cf25301c945e743fb0b1b0c2506ad Mon Sep 17 00:00:00 2001 From: Yuanle Song Date: Sun, 9 Jun 2024 17:13:03 +0800 Subject: [PATCH] XMonad.Actions.GridSelect: added gs_cancelOnEmptyClick field In the original code, when a GridSelect is shown, user has to use keyboard to cancel it (ESC key by default). With this field added, when it is set to True (the default), mouse click on empty space can cancel the GridSelect. --- CHANGES.md | 8 ++++++++ XMonad/Actions/GridSelect.hs | 23 ++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b60e3f1bd..24ecbc51d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,14 @@ myFunc` should be changed to `historyCompletionP myConf myFunc`. If not `myConf` is lying around, `def` can be used instead. + * `XMonad.Actions.GridSelect` + + - Added `gs_cancelOnEmptyClick` field in `GSConfig`. Previously when a + GridSelect is shown, user has to use keyboard to cancel it (ESC key by + default). With this field added, when it is set to True (the default), + mouse click on empty space can cancel the GridSelect. When set to False, + the old behavior is preserved. + ### New Modules * `XMonad.Actions.Profiles` diff --git a/XMonad/Actions/GridSelect.hs b/XMonad/Actions/GridSelect.hs index 8ef7e2f4e..22072fb01 100644 --- a/XMonad/Actions/GridSelect.hs +++ b/XMonad/Actions/GridSelect.hs @@ -203,10 +203,14 @@ data GSConfig a = GSConfig { gs_colorizer :: a -> Bool -> X (String, String), gs_font :: String, gs_navigate :: TwoD a (Maybe a), + -- ^ Customize key bindings for a GridSelect gs_rearranger :: Rearranger a, gs_originFractX :: Double, gs_originFractY :: Double, - gs_bordercolor :: String + gs_bordercolor :: String, + gs_cancelOnEmptyClick :: Bool + -- ^ When True, click on empty space will + -- cancel GridSelect } -- | That is 'fromClassName' if you are selecting a 'Window', or @@ -386,13 +390,18 @@ updateElementsWithColorizer colorizer elementmap = do stdHandle :: Event -> TwoD a (Maybe a) -> TwoD a (Maybe a) stdHandle ButtonEvent{ ev_event_type = t, ev_x = x, ev_y = y } contEventloop | t == buttonRelease = do - s@TwoDState { td_paneX = px, td_paneY = py, - td_gsconfig = (GSConfig ch cw _ _ _ _ _ _ _ _) } <- get - let gridX = (fi x - (px - cw) `div` 2) `div` cw + s@TwoDState { td_paneX = px, td_paneY = py, td_gsconfig = gsconfig } <- get + let ch = gs_cellheight gsconfig + cw = gs_cellwidth gsconfig + gridX = (fi x - (px - cw) `div` 2) `div` cw gridY = (fi y - (py - ch) `div` 2) `div` ch case lookup (gridX,gridY) (td_elementmap s) of Just (_,el) -> return (Just el) - Nothing -> contEventloop + Nothing -> if gs_cancelOnEmptyClick gsconfig + then + return Nothing + else + contEventloop | otherwise = contEventloop stdHandle ExposeEvent{} contEventloop = updateAllElements >> contEventloop @@ -648,7 +657,7 @@ gridselect gsconfig elements = liftIO $ mapWindow dpy win liftIO $ selectInput dpy win (exposureMask .|. keyPressMask .|. buttonReleaseMask) status <- io $ grabKeyboard dpy win True grabModeAsync grabModeAsync currentTime - io $ grabPointer dpy win True buttonReleaseMask grabModeAsync grabModeAsync none none currentTime + _ <- io $ grabPointer dpy win True buttonReleaseMask grabModeAsync grabModeAsync none none currentTime font <- initXMF (gs_font gsconfig) let screenWidth = toInteger $ rect_width scr screenHeight = toInteger $ rect_height scr @@ -706,7 +715,7 @@ decorateName' w = do -- | Builds a default gs config from a colorizer function. buildDefaultGSConfig :: (a -> Bool -> X (String,String)) -> GSConfig a -buildDefaultGSConfig col = GSConfig 50 130 10 col "xft:Sans-8" defaultNavigation noRearranger (1/2) (1/2) "white" +buildDefaultGSConfig col = GSConfig 50 130 10 col "xft:Sans-8" defaultNavigation noRearranger (1/2) (1/2) "white" True -- | Brings selected window to the current workspace. bringSelected :: GSConfig Window -> X ()