From 077b4ff34b7bdece12ee7f7f7d6aa5b5172fff48 Mon Sep 17 00:00:00 2001 From: Yuanle Song Date: Sat, 8 Jun 2024 15:17:51 +0800 Subject: [PATCH] XMonad.Hooks.ScreenCorners: Add support for edges Previously only corners are supported, now support for edges are added. This is similar to Hot Edge shell extension in GNOME. --- CHANGES.md | 5 +++ XMonad/Hooks/ScreenCorners.hs | 59 ++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4e2b91b4bb..b60e3f1bd3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -75,6 +75,11 @@ - Added `visualSubmapSorted` to enable sorting of the keymap descriptions. + * `XMonad.Hooks.ScreenCorners` + + - Added screen edge support with `SCTop`, `SCBottom`, `SCLeft` and + `SCRight`. Now both corners and edges are supported. + ### Other changes ## 0.18.0 (February 3, 2024) diff --git a/XMonad/Hooks/ScreenCorners.hs b/XMonad/Hooks/ScreenCorners.hs index 819bd9ced8..69d79e3156 100644 --- a/XMonad/Hooks/ScreenCorners.hs +++ b/XMonad/Hooks/ScreenCorners.hs @@ -3,7 +3,7 @@ -- | -- Module : XMonad.Hooks.ScreenCorners -- Description : Run X () actions by touching the edge of your screen with your mouse. --- Copyright : (c) 2009 Nils Schweinsberg, 2015 Evgeny Kurnevsky +-- Copyright : (c) 2009 Nils Schweinsberg, 2015 Evgeny Kurnevsky, 2024 Yuanle Song -- License : BSD3-style (see LICENSE) -- -- Maintainer : Nils Schweinsberg @@ -42,6 +42,10 @@ data ScreenCorner = SCUpperLeft | SCUpperRight | SCLowerLeft | SCLowerRight + | SCTop + | SCBottom + | SCLeft + | SCRight deriving (Eq, Ord, Show) -------------------------------------------------------------------------------- @@ -74,25 +78,49 @@ addScreenCorners = mapM_ (uncurry addScreenCorner) -- Xlib functions -------------------------------------------------------------------------------- --- "Translate" a ScreenCorner to real (x,y) Positions +-- "Translate" a ScreenCorner to real (x,y) Positions with proper width and +-- height. createWindowAt :: ScreenCorner -> X Window -createWindowAt SCUpperLeft = createWindowAt' 0 0 +createWindowAt SCUpperLeft = createWindowAt' 0 0 1 1 createWindowAt SCUpperRight = withDisplay $ \dpy -> let w = displayWidth dpy (defaultScreen dpy) - 1 - in createWindowAt' (fi w) 0 + in createWindowAt' (fi w) 0 1 1 createWindowAt SCLowerLeft = withDisplay $ \dpy -> let h = displayHeight dpy (defaultScreen dpy) - 1 - in createWindowAt' 0 (fi h) + in createWindowAt' 0 (fi h) 1 1 createWindowAt SCLowerRight = withDisplay $ \dpy -> let w = displayWidth dpy (defaultScreen dpy) - 1 h = displayHeight dpy (defaultScreen dpy) - 1 - in createWindowAt' (fi w) (fi h) + in createWindowAt' (fi w) (fi h) 1 1 --- Create a new X window at a (x,y) Position -createWindowAt' :: Position -> Position -> X Window -createWindowAt' x y = withDisplay $ \dpy -> io $ do +createWindowAt SCTop = withDisplay $ \dpy -> + let w = displayWidth dpy (defaultScreen dpy) - 1 + -- leave some gap so corner and edge can work nicely when they overlap + threshold = 150 + in createWindowAt' threshold 0 (fi $ fi w - threshold * 2) 1 + +createWindowAt SCBottom = withDisplay $ \dpy -> + let w = displayWidth dpy (defaultScreen dpy) - 1 + h = displayHeight dpy (defaultScreen dpy) - 1 + threshold = 150 + in createWindowAt' threshold (fi h) (fi $ fi w - threshold * 2) 1 + +createWindowAt SCLeft = withDisplay $ \dpy -> + let h = displayHeight dpy (defaultScreen dpy) - 1 + threshold = 150 + in createWindowAt' 0 threshold 1 (fi $ fi h - threshold * 2) + +createWindowAt SCRight = withDisplay $ \dpy -> + let w = displayWidth dpy (defaultScreen dpy) - 1 + h = displayHeight dpy (defaultScreen dpy) - 1 + threshold = 150 + in createWindowAt' (fi w) threshold 1 (fi $ fi h - threshold * 2) + +-- Create a new X window at a (x,y) Position, with given width and height. +createWindowAt' :: Position -> Position -> Dimension -> Dimension -> X Window +createWindowAt' x y width height = withDisplay $ \dpy -> io $ do rootw <- rootWindow dpy (defaultScreen dpy) @@ -107,8 +135,8 @@ createWindowAt' x y = withDisplay $ \dpy -> io $ do rootw -- parent window x -- x y -- y - 1 -- width - 1 -- height + width -- width + height -- height 0 -- border width 0 -- depth inputOnly -- class @@ -122,7 +150,6 @@ createWindowAt' x y = withDisplay $ \dpy -> io $ do sync dpy False return w - -------------------------------------------------------------------------------- -- Event hook -------------------------------------------------------------------------------- @@ -162,9 +189,10 @@ screenCornerLayoutHook = ModifiedLayout ScreenCornerLayout -------------------------------------------------------------------------------- -- $usage -- --- This extension adds KDE-like screen corners to XMonad. By moving your cursor --- into one of your screen corners you can trigger an @X ()@ action, for --- example @"XMonad.Actions.GridSelect".goToSelected@ or +-- This extension adds KDE-like screen corners and GNOME Hot Edge like +-- features to XMonad. By moving your cursor into one of your screen corners +-- or edges, you can trigger an @X ()@ action, for example +-- @"XMonad.Actions.GridSelect".goToSelected@ or -- @"XMonad.Actions.CycleWS".nextWS@ etc. -- -- To use it, import it on top of your @xmonad.hs@: @@ -176,6 +204,7 @@ screenCornerLayoutHook = ModifiedLayout ScreenCornerLayout -- > myStartupHook = do -- > ... -- > addScreenCorner SCUpperRight (goToSelected def { gs_cellwidth = 200}) +-- > addScreenCorner SCBottom (goToSelected def) -- > addScreenCorners [ (SCLowerRight, nextWS) -- > , (SCLowerLeft, prevWS) -- > ]