44 lines
1.3 KiB
Haskell
44 lines
1.3 KiB
Haskell
{-# LANGUAGE LambdaCase #-}
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
module Xmobar.Plugins.NetworkManager where
|
|
|
|
import Control.Concurrent
|
|
import Control.Monad
|
|
|
|
import DBus
|
|
import DBus.Client
|
|
import DBus.Internal.Types
|
|
|
|
import Xmobar
|
|
|
|
newtype NetworkManager = NetworkManager (String, String, String)
|
|
deriving (Read, Show)
|
|
|
|
rule :: MatchRule
|
|
rule = matchAny
|
|
{ matchInterface = Just "org.freedesktop.NetworkManager.VPN.Connection"
|
|
, matchMember = Just "VpnStateChanged"
|
|
}
|
|
|
|
-- TODO would polling be better for this? Using events means that we need
|
|
-- to catch all of them perfectly to stay synchronized...which *might* happen
|
|
|
|
instance Exec NetworkManager where
|
|
alias (NetworkManager _) = "networkmanager"
|
|
start (NetworkManager (text, colorOn, colorOff)) cb = do
|
|
-- start (NetworkManager _) cb = do
|
|
client <- connectSystem
|
|
-- TODO initialize
|
|
_ <- addMatch client rule $ cb . fmtState . getVPNState . signalBody
|
|
forever (threadDelay 5000000)
|
|
where
|
|
getVPNState = \case
|
|
[Variant (ValueAtom (AtomWord32 s)), _] -> Just s
|
|
_ -> Nothing
|
|
fmtState = \case
|
|
-- state = 5 means VPN is connected
|
|
Just s -> wrapColor text $ if s == 5 then colorOn else colorOff
|
|
Nothing -> "N/A"
|
|
wrapColor s c = "<fc=" ++ c ++ ">" ++ s ++ "</fc>"
|