@@ -112,7 +112,9 @@ ui vm dict initialCorpus cliSelectedContract = do
112112 -- UI initialization
113113 let buildVty = do
114114 v <- mkVty =<< vtyConfig
115- Vty. setMode (Vty. outputIface v) Vty. Mouse True
115+ let output = Vty. outputIface v
116+ when (Vty. supportsMode output Vty. Mouse ) $
117+ Vty. setMode output Vty. Mouse True
116118 pure v
117119 initialVty <- liftIO buildVty
118120 app <- customMain initialVty buildVty (Just uiChannel) <$> monitor
@@ -134,6 +136,7 @@ ui vm dict initialCorpus cliSelectedContract = do
134136 , displayFetchedDialog = False
135137 , displayLogPane = True
136138 , displayTestsPane = True
139+ , focusedPane = TestsPane
137140 , events = mempty
138141 , corpusSize = 0
139142 , coverage = 0
@@ -264,6 +267,19 @@ monitor = do
264267 else emptyWidget
265268 , runReader (campaignStatus uiState) conf ]
266269
270+ toggleFocus :: UIState -> UIState
271+ toggleFocus state =
272+ case state. focusedPane of
273+ TestsPane | state. displayLogPane -> state { focusedPane = LogPane }
274+ LogPane | state. displayTestsPane -> state { focusedPane = TestsPane }
275+ _ -> state
276+
277+ refocusIfNeeded :: UIState -> UIState
278+ refocusIfNeeded state = if
279+ (state. focusedPane == TestsPane && not state. displayTestsPane) ||
280+ (state. focusedPane == LogPane && not state. displayLogPane)
281+ then toggleFocus state else state
282+
267283 onEvent = \ case
268284 AppEvent (CampaignUpdated now tests c') ->
269285 modify' $ \ state -> state { campaigns = c', status = Running , now, tests }
@@ -295,15 +311,25 @@ monitor = do
295311 state { displayFetchedDialog = not state. displayFetchedDialog }
296312 VtyEvent (EvKey (KChar ' l' ) _) ->
297313 modify' $ \ state ->
298- state { displayLogPane = not state. displayLogPane }
314+ refocusIfNeeded $ state { displayLogPane = not state. displayLogPane }
299315 VtyEvent (EvKey (KChar ' t' ) _) ->
300316 modify' $ \ state ->
301- state { displayTestsPane = not state. displayTestsPane }
317+ refocusIfNeeded $ state { displayTestsPane = not state. displayTestsPane }
318+ VtyEvent (EvKey direction _) | direction == KPageUp || direction == KPageDown -> do
319+ state <- get
320+ let vp = case state. focusedPane of
321+ TestsPane -> viewportScroll TestsViewPort
322+ LogPane -> viewportScroll LogViewPort
323+ vScrollBy vp (if direction == KPageDown then 10 else - 10 )
324+ VtyEvent (EvKey k [] ) | k == KChar ' \t ' || k == KBackTab ->
325+ -- just two panes, so both keybindings just toggle the active one
326+ modify' toggleFocus
302327 VtyEvent (EvKey KEsc _) -> halt
303328 VtyEvent (EvKey (KChar ' c' ) l) | MCtrl `elem` l -> halt
304329 MouseDown (SBClick el n) _ _ _ ->
305330 case n of
306331 TestsViewPort -> do
332+ modify' $ \ state -> state { focusedPane = TestsPane }
307333 let vp = viewportScroll TestsViewPort
308334 case el of
309335 SBHandleBefore -> vScrollBy vp (- 1 )
@@ -312,6 +338,7 @@ monitor = do
312338 SBTroughAfter -> vScrollBy vp 10
313339 SBBar -> pure ()
314340 LogViewPort -> do
341+ modify' $ \ state -> state { focusedPane = LogPane }
315342 let vp = viewportScroll LogViewPort
316343 case el of
317344 SBHandleBefore -> vScrollBy vp (- 1 )
0 commit comments