{-# LANGUAGE DeriveGeneric #-}

------------------------------------------------------------------------------
-- |
-- Module: Xmobar.Text.SwaybarClicks
-- Copyright: (c) 2022 Jose Antonio Ortega Ruiz
-- License: BSD3-style (see LICENSE)
--
-- Maintainer: jao@gnu.org
-- Stability: unstable
-- Portability: portable
-- Created: Fri Feb 4, 2022 03:58
--
--
-- Handling of "click" events sent by swaybar via stdin
--
------------------------------------------------------------------------------


module Xmobar.Text.SwaybarClicks (startHandler) where

import Control.Monad (when)


import Data.Aeson

-- import qualified Data.ByteString.Lazy as BL

import GHC.Generics

import Xmobar.System.Utils (forkThread)
import Xmobar.Run.Actions (Action (..), runAction')

import Data.ByteString.Lazy.UTF8 (fromString)

data Click =
  Click { Click -> String
name :: String , Click -> Int
button :: Int } deriving (Click -> Click -> Bool
(Click -> Click -> Bool) -> (Click -> Click -> Bool) -> Eq Click
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Click -> Click -> Bool
$c/= :: Click -> Click -> Bool
== :: Click -> Click -> Bool
$c== :: Click -> Click -> Bool
Eq,Int -> Click -> ShowS
[Click] -> ShowS
Click -> String
(Int -> Click -> ShowS)
-> (Click -> String) -> ([Click] -> ShowS) -> Show Click
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Click] -> ShowS
$cshowList :: [Click] -> ShowS
show :: Click -> String
$cshow :: Click -> String
showsPrec :: Int -> Click -> ShowS
$cshowsPrec :: Int -> Click -> ShowS
Show,(forall x. Click -> Rep Click x)
-> (forall x. Rep Click x -> Click) -> Generic Click
forall x. Rep Click x -> Click
forall x. Click -> Rep Click x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Click x -> Click
$cfrom :: forall x. Click -> Rep Click x
Generic)

instance FromJSON Click

runClickAction :: Int -> Action -> IO ()
runClickAction :: Int -> Action -> IO ()
runClickAction Int
b a :: Action
a@(Spawn [Button]
bs String
_) =
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int -> Button
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b Button -> [Button] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Button]
bs) (Action -> IO ()
runAction' Action
a)

handleClick :: Maybe Click -> IO ()
handleClick :: Maybe Click -> IO ()
handleClick Maybe Click
Nothing = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
handleClick (Just Click
click) = do
  let mas :: Maybe [Action]
mas = String -> Maybe [Action]
forall a. Read a => String -> a
read (Click -> String
name Click
click) :: Maybe [Action]
      b :: Int
b = Click -> Int
button Click
click
  IO () -> ([Action] -> IO ()) -> Maybe [Action] -> IO ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) ((Action -> IO ()) -> [Action] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Int -> Action -> IO ()
runClickAction Int
b)) Maybe [Action]
mas

toClick :: String -> Maybe Click
toClick :: String -> Maybe Click
toClick (Char
',':String
s) = String -> Maybe Click
toClick String
s
toClick String
s = ByteString -> Maybe Click
forall a. FromJSON a => ByteString -> Maybe a
decode (String -> ByteString
fromString String
s)

readClicks :: IO ()
readClicks :: IO ()
readClicks = IO String
getLine IO String -> (String -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe Click -> IO ()
handleClick (Maybe Click -> IO ())
-> (String -> Maybe Click) -> String -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe Click
toClick IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
readClicks

startHandler :: IO ()
startHandler :: IO ()
startHandler = String -> IO () -> IO ()
forkThread String
"Swaybar event handler" IO ()
readClicks