on master help sign in
Add support for terminal focus events
4bcebb1Jonathan Daugherty
src/Graphics/Vty/Input/Classify.hs+2
@@ -10,6 +10,7 @@ where
10
10
11import Graphics.Vty.Input.Events
11import Graphics.Vty.Input.Events
12import Graphics.Vty.Input.Mouse
12import Graphics.Vty.Input.Mouse
13+import Graphics.Vty.Input.Focus
13import Graphics.Vty.Input.Paste
14import Graphics.Vty.Input.Paste
14import Graphics.Vty.Input.Classify.Types
15import Graphics.Vty.Input.Classify.Types
15
16
@@ -59,6 +60,7 @@ classify table =
59 then parseBracketedPaste s
60 then parseBracketedPaste s
60 else Prefix
61 else Prefix
61 _ | isMouseEvent s -> classifyMouseEvent s
62 _ | isMouseEvent s -> classifyMouseEvent s
63+ _ | isFocusEvent s -> classifyFocusEvent s
62 c:cs | ord c >= 0xC2 -> classifyUtf8 c cs
64 c:cs | ord c >= 0xC2 -> classifyUtf8 c cs
63 _ -> standardClassifier s
65 _ -> standardClassifier s
64
66
src/Graphics/Vty/Input/Events.hs+4
@@ -56,6 +56,10 @@ data Event
56 -- input (which is probably bad, so beware!) Note that the data is
56 -- input (which is probably bad, so beware!) Note that the data is
57 -- provided in raw form and you'll have to decode (e.g. as UTF-8) if
57 -- provided in raw form and you'll have to decode (e.g. as UTF-8) if
58 -- that's what your application expects.
58 -- that's what your application expects.
59+ | EvLostFocus
60+ -- ^ The terminal running the application lost input focus.
61+ | EvGainedFocus
62+ -- ^ The terminal running the application gained input focus.
59 deriving (Eq,Show,Read,Ord,Generic)
63 deriving (Eq,Show,Read,Ord,Generic)
60
64
61type ClassifyMap = [(String,Event)]
65type ClassifyMap = [(String,Event)]
src/Graphics/Vty/Input/Focus.hsnew file+47
@@ -0,0 +1,47 @@
1+module Graphics.Vty.Input.Focus
2+ ( requestFocusEvents
3+ , disableFocusEvents
4+ , isFocusEvent
5+ , classifyFocusEvent
6+ )
7+where
8+
9+import Graphics.Vty.Input.Events
10+import Graphics.Vty.Input.Classify.Types
11+import Graphics.Vty.Input.Classify.Parse
12+
13+import Control.Monad.State
14+import Data.List (isPrefixOf)
15+
16+-- | These sequences set xterm-based terminals to send focus event
17+-- sequences.
18+requestFocusEvents :: String
19+requestFocusEvents = "\ESC[?1004h"
20+
21+-- | These sequences disable focus events.
22+disableFocusEvents :: String
23+disableFocusEvents = "\ESC[?1004l"
24+
25+-- | Does the specified string begin with a focus event?
26+isFocusEvent :: String -> Bool
27+isFocusEvent s = isPrefixOf focusIn s ||
28+ isPrefixOf focusOut s
29+
30+focusIn :: String
31+focusIn = "\ESC[I"
32+
33+focusOut :: String
34+focusOut = "\ESC[O"
35+
36+-- | Attempt to classify an input string as a focus event.
37+classifyFocusEvent :: String -> KClass
38+classifyFocusEvent s = runParser s $ do
39+ when (not $ isFocusEvent s) failParse
40+
41+ expectChar '\ESC'
42+ expectChar '['
43+ ty <- readChar
44+ case ty of
45+ 'I' -> return EvGainedFocus
46+ 'O' -> return EvLostFocus
47+ _ -> failParse
src/Graphics/Vty/Output/Interface.hs+3
@@ -44,6 +44,9 @@ data Mode = Mouse
44 | BracketedPaste
44 | BracketedPaste
45 -- ^ Paste mode (whether the terminal is configured to provide
45 -- ^ Paste mode (whether the terminal is configured to provide
46 -- events on OS pastes)
46 -- events on OS pastes)
47+ | Focus
48+ -- ^ Focus-in/focus-out events (whether the terminal is
49+ -- configured to provide events on focus change)
47 deriving (Eq, Read, Show)
50 deriving (Eq, Read, Show)
48
51
49-- | The Vty terminal output interface.
52-- | The Vty terminal output interface.
src/Graphics/Vty/Output/XTermColor.hs+9
@@ -8,6 +8,7 @@ where
8
8
9import Graphics.Vty.Output.Interface
9import Graphics.Vty.Output.Interface
10import Graphics.Vty.Input.Mouse
10import Graphics.Vty.Input.Mouse
11+import Graphics.Vty.Input.Focus
11import qualified Graphics.Vty.Output.TerminfoBased as TerminfoBased
12import qualified Graphics.Vty.Output.TerminfoBased as TerminfoBased
12
13
13import Blaze.ByteString.Builder (writeToByteString)
14import Blaze.ByteString.Builder (writeToByteString)
@@ -38,12 +39,18 @@ reserveTerminal variant outFd = liftIO $ do
38 t <- TerminfoBased.reserveTerminal variant' outFd
39 t <- TerminfoBased.reserveTerminal variant' outFd
39
40
40 mouseModeStatus <- newIORef False
41 mouseModeStatus <- newIORef False
42+ focusModeStatus <- newIORef False
41 pasteModeStatus <- newIORef False
43 pasteModeStatus <- newIORef False
42
44
43 let xtermSetMode t' m newStatus = do
45 let xtermSetMode t' m newStatus = do
44 curStatus <- getModeStatus t' m
46 curStatus <- getModeStatus t' m
45 when (newStatus /= curStatus) $
47 when (newStatus /= curStatus) $
46 case m of
48 case m of
49+ Focus -> liftIO $ do
50+ case newStatus of
51+ True -> flushedPut requestFocusEvents
52+ False -> flushedPut disableFocusEvents
53+ writeIORef focusModeStatus newStatus
47 Mouse -> liftIO $ do
54 Mouse -> liftIO $ do
48 case newStatus of
55 case newStatus of
49 True -> flushedPut requestMouseEvents
56 True -> flushedPut requestMouseEvents
@@ -56,6 +63,7 @@ reserveTerminal variant outFd = liftIO $ do
56 writeIORef pasteModeStatus newStatus
63 writeIORef pasteModeStatus newStatus
57
64
58 xtermGetMode Mouse = liftIO $ readIORef mouseModeStatus
65 xtermGetMode Mouse = liftIO $ readIORef mouseModeStatus
66+ xtermGetMode Focus = liftIO $ readIORef focusModeStatus
59 xtermGetMode BracketedPaste = liftIO $ readIORef pasteModeStatus
67 xtermGetMode BracketedPaste = liftIO $ readIORef pasteModeStatus
60
68
61 let t' = t
69 let t' = t
@@ -64,6 +72,7 @@ reserveTerminal variant outFd = liftIO $ do
64 when (not utf8a) $ liftIO $ flushedPut setDefaultCharSet
72 when (not utf8a) $ liftIO $ flushedPut setDefaultCharSet
65 setMode t' BracketedPaste False
73 setMode t' BracketedPaste False
66 setMode t' Mouse False
74 setMode t' Mouse False
75+ setMode t' Focus False
67 releaseTerminal t
76 releaseTerminal t
68 , mkDisplayContext = \tActual r -> do
77 , mkDisplayContext = \tActual r -> do
69 dc <- mkDisplayContext t tActual r
78 dc <- mkDisplayContext t tActual r
vty.cabal+1
@@ -85,6 +85,7 @@ library
85 Graphics.Vty.Input.Classify.Parse
85 Graphics.Vty.Input.Classify.Parse
86 Graphics.Vty.Input.Loop
86 Graphics.Vty.Input.Loop
87 Graphics.Vty.Input.Mouse
87 Graphics.Vty.Input.Mouse
88+ Graphics.Vty.Input.Focus
88 Graphics.Vty.Input.Paste
89 Graphics.Vty.Input.Paste
89 Graphics.Vty.Input.Terminfo
90 Graphics.Vty.Input.Terminfo
90 Graphics.Vty.PictureToSpans
91 Graphics.Vty.PictureToSpans