Safe Haskell | None |
---|---|
Language | Haskell2010 |
- data DBusConnection
- data ConnectionType
- connectBus :: ConnectionType -> MethodCallHandler -> SignalHandler -> IO DBusConnection
- makeServer :: ConnectionType -> Objects -> IO DBusConnection
- type MethodCallHandler = DBusConnection -> MessageHeader -> [SomeDBusValue] -> IO ()
- type SignalHandler = DBusConnection -> MessageHeader -> [SomeDBusValue] -> IO ()
- checkAlive :: DBusConnection -> IO Bool
- waitFor :: DBusConnection -> IO ()
- objectRoot :: Objects -> Handler
- ignore :: Monad m => t -> t1 -> t2 -> m ()
- data MatchRule = MatchRule {
- mrType :: Maybe MessageType
- mrSender :: Maybe Text
- mrInterface :: Maybe Text
- mrMember :: Maybe Text
- mrPath :: Maybe (Bool, ObjectPath)
- mrDestination :: Maybe Text
- mrArgs :: [(Int, Text)]
- mrArgPaths :: [(Int, Text)]
- mrArg0namespace :: Maybe Text
- mrEavesdrop :: Maybe Bool
- data Signal a = Signal {}
- data SignalDescription a = SignalDescription {}
- data SomeSignalDescription where
- SSD :: forall a. SingI a => SignalDescription a -> SomeSignalDescription
- matchAll :: MatchRule
- matchSignal :: Signal a -> MatchRule -> Bool
- addMatch :: (MonadIO m, MonadThrow m) => MatchRule -> DBusConnection -> m ()
- removeMatch :: (MonadIO m, MonadThrow m) => MatchRule -> DBusConnection -> m ()
- addSignalHandler :: MatchSignal -> MatchRule -> (SomeSignal -> IO ()) -> DBusConnection -> IO ()
- signalChan :: MatchSignal -> DBusConnection -> IO (TChan SomeSignal)
- handleSignal :: Representable a => SignalDescription (FlattenRepType (RepType a)) -> Maybe Text -> MatchRule -> (a -> IO ()) -> DBusConnection -> IO ()
- class SingI (RepType a) => Representable a where
- type family FlattenRepType a :: [DBusType]
- makeRepresentable :: Name -> Q [Dec]
- makeRepresentableTuple :: Int -> Q Dec
- data DBusValue :: DBusType -> * where
- DBVByte :: Word8 -> DBusValue (DBusSimpleType TypeByte)
- DBVBool :: Bool -> DBusValue (DBusSimpleType TypeBoolean)
- DBVInt16 :: Int16 -> DBusValue (DBusSimpleType TypeInt16)
- DBVUInt16 :: Word16 -> DBusValue (DBusSimpleType TypeUInt16)
- DBVInt32 :: Int32 -> DBusValue (DBusSimpleType TypeInt32)
- DBVUInt32 :: Word32 -> DBusValue (DBusSimpleType TypeUInt32)
- DBVInt64 :: Int64 -> DBusValue (DBusSimpleType TypeInt64)
- DBVUInt64 :: Word64 -> DBusValue (DBusSimpleType TypeUInt64)
- DBVDouble :: Double -> DBusValue (DBusSimpleType TypeDouble)
- DBVUnixFD :: Word32 -> DBusValue (DBusSimpleType TypeUnixFD)
- DBVString :: Text -> DBusValue (DBusSimpleType TypeString)
- DBVObjectPath :: ObjectPath -> DBusValue (DBusSimpleType TypeObjectPath)
- DBVSignature :: [DBusType] -> DBusValue (DBusSimpleType TypeSignature)
- DBVVariant :: SingI t => DBusValue t -> DBusValue TypeVariant
- DBVArray :: [DBusValue a] -> DBusValue (TypeArray a)
- DBVByteArray :: ByteString -> DBusValue (TypeArray (DBusSimpleType TypeByte))
- DBVStruct :: DBusStruct ts -> DBusValue (TypeStruct ts)
- DBVDict :: [(DBusValue (DBusSimpleType k), DBusValue v)] -> DBusValue (TypeDict k v)
- DBVUnit :: DBusValue TypeUnit
- castDBV :: (SingI s, SingI t) => DBusValue s -> Maybe (DBusValue t)
- data DBusStruct :: [DBusType] -> * where
- StructSingleton :: DBusValue a -> DBusStruct `[a]`
- StructCons :: DBusValue a -> DBusStruct as -> DBusStruct (a : as)
- data SomeDBusValue where
- DBV :: SingI t => DBusValue t -> SomeDBusValue
- dbusValue :: SingI t => SomeDBusValue -> Maybe (DBusValue t)
- fromVariant :: SingI t => DBusValue TypeVariant -> Maybe (DBusValue t)
- data DBusSimpleType
- data DBusType
- newtype Signature = Signature {
- fromSignature :: [DBusType]
- typeOf :: SingI t => DBusValue t -> DBusType
- newtype Object = Object {}
- data Interface = Interface {}
- data ObjectPath
- objectPath :: Text -> ObjectPath
- objectPathToText :: ObjectPath -> Text
- stripObjectPrefix :: ObjectPath -> ObjectPath -> Maybe ObjectPath
- isPathPrefix :: ObjectPath -> ObjectPath -> Bool
- isRoot :: ObjectPath -> Bool
- isEmpty :: ObjectPath -> Bool
- data Method where
- Method :: (SingI avs, SingI ts) => MethodWrapper avs ts -> Text -> ArgumentDescription (ArgParity avs) -> ArgumentDescription (ArgParity ts) -> Method
- data MethodWrapper av rv where
- MReturn :: SingI ts => MethodHandlerT IO (DBusArguments ts) -> MethodWrapper [] ts
- MAsk :: SingI t => (DBusValue t -> MethodWrapper avs rv) -> MethodWrapper (t : avs) rv
- data ArgumentDescription parity where
- (:>) :: Text -> ArgumentDescription n -> ArgumentDescription (Arg n)
- Done :: ArgumentDescription Null
- repMethod :: RepMethod f => f -> MethodWrapper (RepMethodArgs f) (RepMethodValue f)
- callMethod :: (Representable args, Representable ret) => Text -> ObjectPath -> Text -> Text -> args -> [Flag] -> DBusConnection -> IO (Either MethodError ret)
- callMethod' :: Text -> ObjectPath -> Text -> Text -> [SomeDBusValue] -> [Flag] -> DBusConnection -> IO (STM (Either [SomeDBusValue] [SomeDBusValue]))
- call :: (Representable ret, Representable args) => MethodDescription (FlattenRepType (RepType args)) (FlattenRepType (RepType ret)) -> Text -> args -> [Flag] -> DBusConnection -> IO (Either MethodError ret)
- callAsync :: (Representable args, Representable ret) => MethodDescription (FlattenRepType (RepType args)) (FlattenRepType (RepType ret)) -> Text -> args -> [Flag] -> DBusConnection -> IO (STM (Either MethodError ret))
- fromResponse :: Representable a => Either [SomeDBusValue] [SomeDBusValue] -> Either MethodError a
- data MsgError = MsgError {}
- data MethodError
- newtype MethodHandlerT m a = MHT {
- unMHT :: ExceptT MsgError (WriterT [SomeSignal] m) a
- data MethodDescription args rets where
- MD :: {
- methodObjectPath :: ObjectPath
- methodInterface :: Text
- methodMember :: Text
- methodArgs :: ArgumentDescription (ArgParity args)
- methodResult :: ArgumentDescription (ArgParity rets)
- MD :: {
- data SomeMethodDescription where
- SMD :: (SingI args, SingI rets) => MethodDescription args rets -> SomeMethodDescription
- data Property t where
- Property :: forall t. SingI t => {
- propertyPath :: ObjectPath
- propertyInterface :: Text
- propertyName :: Text
- propertyGet :: Maybe (MethodHandlerT IO (DBusValue t))
- propertySet :: Maybe (DBusValue t -> MethodHandlerT IO Bool)
- propertyEmitsChangedSignal :: PropertyEmitsChangedSignal
- Property :: forall t. SingI t => {
- data SomeProperty where
- SomeProperty :: forall t. SingI t => {
- fromSomeProperty :: Property t
- SomeProperty :: forall t. SingI t => {
- data PropertyEmitsChangedSignal
- data RemoteProperty a = RP {
- rpEntity :: Text
- rpObject :: ObjectPath
- rpInterface :: Text
- rpName :: Text
- propertyChanged :: (MonadIO m, Representable a) => Property (RepType a) -> a -> MethodHandlerT m ()
- emitPropertyChanged :: Representable a => Property (RepType a) -> a -> DBusConnection -> IO ()
- getProperty :: Representable a => RemoteProperty (RepType a) -> DBusConnection -> IO (Either MethodError a)
- setProperty :: Representable a => RemoteProperty (RepType a) -> a -> DBusConnection -> IO (Either MethodError ())
- handlePropertyChanged :: Representable a => RemoteProperty (RepType a) -> (Maybe a -> IO ()) -> DBusConnection -> IO ()
- mkProperty :: Representable a => ObjectPath -> Text -> Text -> Maybe (MethodHandlerT IO a) -> Maybe (a -> MethodHandlerT IO Bool) -> PropertyEmitsChangedSignal -> Property (RepType a)
- mkTVarProperty :: Representable a => ObjectPath -> Text -> Text -> PropertyAccess -> PropertyEmitsChangedSignal -> TVar a -> Property (RepType a)
- addIntrospectable :: Objects -> Objects
- requestName :: (MonadIO m, MonadThrow m) => Text -> RequestNameFlag -> DBusConnection -> m RequestNameReply
- data RequestNameFlag = RequestNameFlag {}
- data RequestNameReply
- releaseName :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m ReleaseNameReply
- data ReleaseNameReply
- listQueuedOwners :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m [Text]
- listNames :: (MonadIO m, MonadThrow m) => DBusConnection -> m [Text]
- listActivatableNames :: (MonadIO m, MonadThrow m) => DBusConnection -> m [Text]
- nameHasOwner :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m Bool
- startServiceByName :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m StartServiceResult
- getNameOwner :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m Text
- getConnectionUnixUser :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m Word32
- getConnectionProcessID :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m Word32
- getID :: (MonadIO m, MonadThrow m) => DBusConnection -> m Text
- def :: Default a => a
Connection management
data DBusConnection Source
data ConnectionType Source
Which Bus to connect to
System | The well-known system bus. First the environmental variable DBUS_SYSTEM_BUS_ADDRESS is checked and if it doesn't exist the address unix:path=/var/run/dbus/system_bus_socket is used |
Session | The well-known session bus. Refers to the address stored in the environmental variable DBUS_SESSION_BUS_ADDRESS |
Address String | The bus at the give addresss |
:: ConnectionType | Bus to connect to |
-> MethodCallHandler | Handler for incoming method calls |
-> SignalHandler | Handler for incoming signals |
-> IO DBusConnection |
Create a new connection to a message bus
makeServer :: ConnectionType -> Objects -> IO DBusConnection Source
type MethodCallHandler = DBusConnection -> MessageHeader -> [SomeDBusValue] -> IO () Source
type SignalHandler = DBusConnection -> MessageHeader -> [SomeDBusValue] -> IO () Source
checkAlive :: DBusConnection -> IO Bool Source
Check whether connection is alive
waitFor :: DBusConnection -> IO () Source
Wait until connection is closed
Message handling
objectRoot :: Objects -> Handler Source
Create a message handler that dispatches matches to the methods in a root object
Signals
MatchRule | |
|
data SignalDescription a Source
Eq (SignalDescription a) | |
SingI [DBusType] a => Show (SignalDescription a) | |
Typeable ([DBusType] -> *) SignalDescription |
data SomeSignalDescription where Source
SSD :: forall a. SingI a => SignalDescription a -> SomeSignalDescription |
matchSignal :: Signal a -> MatchRule -> Bool Source
Match a Signal against a rule. The argN, argNPath and arg0namespace parameter are ignored at the moment
addMatch :: (MonadIO m, MonadThrow m) => MatchRule -> DBusConnection -> m () Source
Add a match rule
removeMatch :: (MonadIO m, MonadThrow m) => MatchRule -> DBusConnection -> m () Source
Remove a match rule
addSignalHandler :: MatchSignal -> MatchRule -> (SomeSignal -> IO ()) -> DBusConnection -> IO () Source
Add a match rule for the given signal specification and call function on all incoming matching signals
signalChan :: MatchSignal -> DBusConnection -> IO (TChan SomeSignal) Source
Add a match rule for the given signal specification and put all incoming signals into the TChan
handleSignal :: Representable a => SignalDescription (FlattenRepType (RepType a)) -> Maybe Text -> MatchRule -> (a -> IO ()) -> DBusConnection -> IO () Source
Add a match rule (computed from the SignalDescription) and install a handler that tries to convert the Signal's body and passes it to the callback
Representable Types
class SingI (RepType a) => Representable a where Source
Class of types that can be represented in the D-Bus type system.
The toRep and fromRep functions form a Prism and should follow the "obvious" laws:
fromRep (toRep x) == Just x
fmap toRep (fromRep x) =<= Just x
(where x =<= y
iff x
is Nothing
or x == y
)
All DBusValues
represent themselves and instances for
the following "canonical" pairs are provided
Haskell type => D-Bus type
- WordX and IntX => UIntX and IntX respectively (for X in {16, 32, 64})
Bool
=> BooleanWord8
=> ByteDouble
=> DoubleText
=> StringObjectPath
=> ObjectPathDBusType
=> Signature- [a] => Array of a (for Representable a)
ByteString
=> Array of Byte- Tuples up to length 20 => Structs of equal length where each of the members is itself Representable
Map
=> Dict where the keys can be represented by aDBusSimpleType
An instance for String
is impossible because it conflicts with the instance
for lists (use Text instead)
Also note that no Representable instances are provided for Int
, Integer
and Float
.
You can automatically derive an instance for your own Types with
makeRepresentable
toRep :: a -> DBusValue (RepType a) Source
Conversion from Haskell to D-Bus types
fromRep :: DBusValue (RepType a) -> Maybe a Source
Conversion from D-Bus to Haskell types.
type family FlattenRepType a :: [DBusType] Source
FlattenRepType TypeUnit = `[]` | |
FlattenRepType (TypeStruct ts) = ts | |
FlattenRepType (DBusSimpleType wild_1627472167) = Apply (Apply (:$) (Let1627472175TSym1 wild_1627472167)) `[]` | |
FlattenRepType (TypeArray wild_1627472165) = Apply (Apply (:$) (Let1627472180TSym1 wild_1627472165)) `[]` | |
FlattenRepType (TypeDict wild_1627472161 wild_1627472163) = Apply (Apply (:$) (Let1627472186TSym2 wild_1627472161 wild_1627472163)) `[]` | |
FlattenRepType (TypeDictEntry wild_1627472157 wild_1627472159) = Apply (Apply (:$) (Let1627472196TSym2 wild_1627472157 wild_1627472159)) `[]` | |
FlattenRepType TypeVariant = Apply (Apply (:$) Let1627472204TSym0) `[]` |
makeRepresentable :: Name -> Q [Dec] Source
makeRepresentableTuple :: Int -> Q Dec Source
DBus specific types
DBus Values
data DBusValue :: DBusType -> * where Source
Eq (DBusValue t) | |
SingI DBusType t => Show (DBusValue t) | |
SingI DBusType t => Representable (DBusValue t) | |
(IsMethod f, SingI DBusType t) => IsMethod (DBusValue t -> f) | |
type RepType (DBusValue t) = t | |
type ArgTypes (DBusValue t -> f) = (:) DBusType t (ArgTypes f) | |
type ResultType (DBusValue t -> f) = ResultType f |
data DBusStruct :: [DBusType] -> * where Source
StructSingleton :: DBusValue a -> DBusStruct `[a]` | |
StructCons :: DBusValue a -> DBusStruct as -> DBusStruct (a : as) |
Eq (DBusStruct t) | |
SingI [DBusType] a => Show (DBusStruct a) |
fromVariant :: SingI t => DBusValue TypeVariant -> Maybe (DBusValue t) Source
Extract a DBusValue from a Variant iff the type matches or return nothing
Signature
data DBusSimpleType Source
Types that are not composite. These can be the keys of a Dict
TypeByte | |
TypeBoolean | |
TypeInt16 | |
TypeUInt16 | |
TypeInt32 | |
TypeUInt32 | |
TypeInt64 | |
TypeUInt64 | |
TypeDouble | |
TypeUnixFD | |
TypeString | |
TypeObjectPath | |
TypeSignature |
DBusSimpleType DBusSimpleType | |
TypeArray DBusType | |
TypeStruct [DBusType] | |
TypeDict DBusSimpleType DBusType | |
TypeVariant | |
TypeDictEntry DBusSimpleType DBusType | |
TypeUnit |
Objects
data ObjectPath Source
objectPath :: Text -> ObjectPath Source
Parse an object path. Contrary to the standard, empty path parts are ignored
objectPathToText :: ObjectPath -> Text Source
isPathPrefix :: ObjectPath -> ObjectPath -> Bool Source
isRoot :: ObjectPath -> Bool Source
isEmpty :: ObjectPath -> Bool Source
Methods
Method :: (SingI avs, SingI ts) => MethodWrapper avs ts -> Text -> ArgumentDescription (ArgParity avs) -> ArgumentDescription (ArgParity ts) -> Method |
data MethodWrapper av rv where Source
MReturn :: SingI ts => MethodHandlerT IO (DBusArguments ts) -> MethodWrapper [] ts | |
MAsk :: SingI t => (DBusValue t -> MethodWrapper avs rv) -> MethodWrapper (t : avs) rv |
data ArgumentDescription parity where Source
(:>) :: Text -> ArgumentDescription n -> ArgumentDescription (Arg n) infixr 0 | |
Done :: ArgumentDescription Null |
Show (ArgumentDescription n) | |
Typeable (Parity -> *) ArgumentDescription |
repMethod :: RepMethod f => f -> MethodWrapper (RepMethodArgs f) (RepMethodValue f) Source
:: (Representable args, Representable ret) | |
=> Text | Entity to send the message to |
-> ObjectPath | Object |
-> Text | Interface |
-> Text | Member (method) to call |
-> args | Arguments |
-> [Flag] | Method call flags |
-> DBusConnection | Connection to send the call over |
-> IO (Either MethodError ret) |
Synchronously call a method.
This is the "cooked" version of callMethod''. It automatically converts arguments and returns values.
If the returned value's type doesn't match the expected type a
MethodSignatureMissmatch
is returned
You can pass in and extract multiple arguments and return values with types that are represented by DBus Structs (e.g. tuples). More specifically, multiple arguments/return values are handled in the following way:
- If the method returns multiple values and the RepType of the expected return value is a struct it tries to match up the arguments with the struct fields
- If the method returns a single struct and the RepType is a struct it will try to match up those two
- If the RepType of the expected return value is not a struct it will only match if the method returned exactly one value and those two match up (as per normal)
This means that if the RepType of the expected return value is a struct it might be matched in two ways: Either by the method returning multiple values or the method returning a single struct. At the moment there is no way to exclude either
:: Text | Entity to send the message to |
-> ObjectPath | Object |
-> Text | Interface |
-> Text | Member (method) name |
-> [SomeDBusValue] | Arguments |
-> [Flag] | Method call flags |
-> DBusConnection | Connection to send the call over |
-> IO (STM (Either [SomeDBusValue] [SomeDBusValue])) |
Asychronously call a method.
This is the "raw" version of callMethod
. It doesn't do argument conversion.
call :: (Representable ret, Representable args) => MethodDescription (FlattenRepType (RepType args)) (FlattenRepType (RepType ret)) -> Text -> args -> [Flag] -> DBusConnection -> IO (Either MethodError ret) Source
callAsync :: (Representable args, Representable ret) => MethodDescription (FlattenRepType (RepType args)) (FlattenRepType (RepType ret)) -> Text -> args -> [Flag] -> DBusConnection -> IO (STM (Either MethodError ret)) Source
fromResponse :: Representable a => Either [SomeDBusValue] [SomeDBusValue] -> Either MethodError a Source
Try to convert the response to a method call top Haskell types
data MethodError Source
newtype MethodHandlerT m a Source
A Transformer for (IO) actions that might want to send a signal.
MonadTrans MethodHandlerT | |
(Functor m, Monad m) => Alternative (MethodHandlerT m) | |
Monad m => Monad (MethodHandlerT m) | |
Functor m => Functor (MethodHandlerT m) | |
Monad m => MonadPlus (MethodHandlerT m) | |
(Monad m, Functor m) => Applicative (MethodHandlerT m) | |
MonadIO m => MonadIO (MethodHandlerT m) | |
Representable t => RepMethod (MethodHandlerT IO t) | |
SingI [DBusType] t => IsMethod (MethodHandlerT IO (DBusArguments t)) | |
type RepMethodArgs (MethodHandlerT IO t) = [] DBusType | |
type RepMethodValue (MethodHandlerT IO t) = FlattenRepType (RepType t) | |
type ArgTypes (MethodHandlerT IO (DBusArguments ts)) = [] DBusType | |
type ResultType (MethodHandlerT IO (DBusArguments ts)) = ts |
data MethodDescription args rets where Source
MD :: ObjectPath -> Text -> Text -> ArgumentDescription (ArgParity args) -> ArgumentDescription (ArgParity rets) -> MethodDescription args rets | |
|
Show (MethodDescription args rets) |
data SomeMethodDescription where Source
SMD :: (SingI args, SingI rets) => MethodDescription args rets -> SomeMethodDescription |
Properties
Property :: forall t. SingI t => ObjectPath -> Text -> Text -> Maybe (MethodHandlerT IO (DBusValue t)) -> Maybe (DBusValue t -> MethodHandlerT IO Bool) -> PropertyEmitsChangedSignal -> Property t | |
data SomeProperty where Source
SomeProperty :: forall t. SingI t => Property t -> SomeProperty | |
|
data RemoteProperty a Source
RP | |
|
Eq (RemoteProperty k a) | |
Show (RemoteProperty k a) |
propertyChanged :: (MonadIO m, Representable a) => Property (RepType a) -> a -> MethodHandlerT m () Source
emitPropertyChanged :: Representable a => Property (RepType a) -> a -> DBusConnection -> IO () Source
getProperty :: Representable a => RemoteProperty (RepType a) -> DBusConnection -> IO (Either MethodError a) Source
setProperty :: Representable a => RemoteProperty (RepType a) -> a -> DBusConnection -> IO (Either MethodError ()) Source
handlePropertyChanged :: Representable a => RemoteProperty (RepType a) -> (Maybe a -> IO ()) -> DBusConnection -> IO () Source
mkProperty :: Representable a => ObjectPath -> Text -> Text -> Maybe (MethodHandlerT IO a) -> Maybe (a -> MethodHandlerT IO Bool) -> PropertyEmitsChangedSignal -> Property (RepType a) Source
Create a property from a getter and a setter. It will emit a PropertyChanged signal when the setter is called. To change this behaviour modify the propertyEmitsChangedSignal field
mkTVarProperty :: Representable a => ObjectPath -> Text -> Text -> PropertyAccess -> PropertyEmitsChangedSignal -> TVar a -> Property (RepType a) Source
Make a property out of a TVar. The property is considered changed on every outside set, no matter if the updated value is actually different from the old one
Introspection
Message Bus
requestName :: (MonadIO m, MonadThrow m) => Text -> RequestNameFlag -> DBusConnection -> m RequestNameReply Source
data RequestNameFlag Source
releaseName :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m ReleaseNameReply Source
listQueuedOwners :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m [Text] Source
listNames :: (MonadIO m, MonadThrow m) => DBusConnection -> m [Text] Source
listActivatableNames :: (MonadIO m, MonadThrow m) => DBusConnection -> m [Text] Source
nameHasOwner :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m Bool Source
startServiceByName :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m StartServiceResult Source
getNameOwner :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m Text Source
getConnectionUnixUser :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m Word32 Source
getConnectionProcessID :: (MonadIO m, MonadThrow m) => Text -> DBusConnection -> m Word32 Source
getID :: (MonadIO m, MonadThrow m) => DBusConnection -> m Text Source