on master help sign in
Mouse: support Normal mode events in terminals with a "screen" terminal type
commit82432db1e36f809600f0d2a4eee945cfec7ef58f authorJonathan Daugherty <cygnus@foobox.com> dateFri 17 Jun 2016, 16:46 (10 years ago) parente58c152
4 files changed+29−6
src/Graphics/Vty/Input/Classify.hs+1 src/Graphics/Vty/Input/Events.hs+1−1 src/Graphics/Vty/Input/Mouse.hs+26−4 src/Graphics/Vty/Output.hs+1−1
src/Graphics/Vty/Input/Classify.hs+1
@@ -57,6 +57,7 @@ classify table =
5757 let standardClassifier = compile table
5858 in \s -> case s of
5959 ('\ESC':'[':'<':cs) | length cs >= 6 -> classifySGRMouseEvent cs
60+ ('\ESC':'[':'M':cs) | length cs >= 3 -> classifyNormalMouseEvent cs
6061 c:cs | ord c >= 0xC2 -> classifyUtf8 c cs
6162 _ -> standardClassifier s
6263
src/Graphics/Vty/Input/Events.hs+1−1
@@ -32,7 +32,7 @@ data Event
3232 = EvKey Key [Modifier]
3333 -- | \todo mouse events are not supported
3434 | EvMouseDown Int Int Button [Modifier]
35− | EvMouseUp Int Int Button
35+ | EvMouseUp Int Int (Maybe Button)
3636 -- | if read from 'eventChannel' this is the size at the time of the signal. If read from
3737 -- 'nextEvent' this is the size at the time the event was processed by Vty. Typically these are
3838 -- the same, but if somebody is resizing the terminal quickly they can be different.
src/Graphics/Vty/Input/Mouse.hs+26−4
@@ -2,6 +2,7 @@ module Graphics.Vty.Input.Mouse
22 ( requestSGRMouseEvents
33 , disableSGRMouseEvents
44 , classifySGRMouseEvent
5+ , classifyNormalMouseEvent
56 ) where
67
78import Graphics.Vty.Input.Events
@@ -63,8 +64,8 @@ hasBitSet :: Int -> Int -> Bool
6364hasBitSet val bit = val .&. bit > 0
6465
6566-- Given a modifer/button value, determine which button was indicated
66−getButton :: Int -> Parser Button
67−getButton mods =
67+getSGRButton :: Int -> Parser Button
68+getSGRButton mods =
6869 let buttonMap = [ (leftButton, BLeft)
6970 , (middleButton, BMiddle)
7071 , (rightButton, BRight)
@@ -112,6 +113,27 @@ expectChar c = do
112113 c' <- readChar
113114 if c' == c then return () else failParse
114115
116+-- Attempt to classify a control sequence as a "normal" mouse event. To
117+-- get here we should have already read "\ESC[M" so that will not be
118+-- included in the string to be parsed.
119+classifyNormalMouseEvent :: [Char] -> KClass
120+classifyNormalMouseEvent s = runParser s $ do
121+ statusChar <- readChar
122+ xCoordChar <- readChar
123+ yCoordChar <- readChar
124+
125+ let xCoord = fromEnum xCoordChar - 32
126+ yCoord = fromEnum yCoordChar - 32
127+ status = fromEnum statusChar
128+ modifiers = getModifiers status
129+
130+ let press = status .&. buttonMask /= 3
131+ case press of
132+ True -> do
133+ button <- getSGRButton status
134+ return $ EvMouseDown xCoord yCoord button modifiers
135+ False -> return $ EvMouseUp xCoord yCoord Nothing
136+
115137-- Attempt to classify a control sequence as an SGR mouse event. To
116138-- get here we should have already read "\ESC[<" so that will not be
117139-- included in the string to be parsed.
@@ -125,8 +147,8 @@ classifySGRMouseEvent s = runParser s $ do
125147 final <- readChar
126148
127149 let modifiers = getModifiers mods
128− button <- getButton mods
150+ button <- getSGRButton mods
129151 case final of
130152 'M' -> return $ EvMouseDown xCoord yCoord button modifiers
131− 'm' -> return $ EvMouseUp xCoord yCoord button
153+ 'm' -> return $ EvMouseUp xCoord yCoord (Just button)
132154 _ -> failParse
src/Graphics/Vty/Output.hs+1−1
@@ -61,7 +61,7 @@ import Data.Monoid ((<>))
6161-- with only what is provided in the haskell platform. Use ansi-terminal
6262outputForConfig :: Config -> IO Output
6363outputForConfig Config{ outputFd = Just fd, termName = Just termName, .. } = do
64− t <- if "xterm" `isPrefixOf` termName
64+ t <- if "xterm" `isPrefixOf` termName || "screen" `isPrefixOf` termName
6565 then XTermColor.reserveTerminal termName fd
6666 -- Not an xterm-like terminal. try for generic terminfo.
6767 else TerminfoBased.reserveTerminal termName fd