-- | Bind media keys for Spotify using @dbus@. module XMonad.Util.Spotify ( -- * default keybindings mediaKeys , mediaKeysWith -- * Media control in the 'X' monad , audioPrev , audioNext , audioPlayPause , audioStop , audioNextWith , audioPrevWith , audioPlayPauseWith , audioStopWith ) where import Control.Monad (void) import Control.Monad.IO.Class import qualified Data.Map as M import DBus import DBus.Client import Graphics.X11.ExtraTypes.XF86 import Graphics.X11.Types -- | @since 0.1.2.0 mediaKeys :: MonadIO m => M.Map (KeyMask, KeySym) (m ()) -> M.Map (KeyMask, KeySym) (m ()) mediaKeys = M.union mediaKeyMap where mediaKeyMap = M.fromList mediaKeyList mediaKeyList :: MonadIO m => [((KeyMask, KeySym), m ())] mediaKeyList = [ ((0, xF86XK_AudioNext), audioNext) , ((0, xF86XK_AudioPrev), audioPrev) , ((0, xF86XK_AudioPlay), audioPlayPause) , ((0, xF86XK_AudioStop), audioStop) ] -- | Given your keymaps, add the media keybindings. Currently they are set up -- for Spotify. mediaKeysWith :: MonadIO m => Client -> M.Map (KeyMask, KeySym) (m ()) -> M.Map (KeyMask, KeySym) (m ()) mediaKeysWith client = M.union mediaKeyMap where mediaKeyMap = M.fromList (mediaKeyListWith client) mediaKeyListWith :: MonadIO m => Client -> [((KeyMask, KeySym), m ())] mediaKeyListWith client = [ ((0, xF86XK_AudioNext), audioNextWith client) , ((0, xF86XK_AudioPrev), audioPrevWith client) , ((0, xF86XK_AudioPlay), audioPlayPauseWith client) , ((0, xF86XK_AudioStop), audioStopWith client) ] spWith :: MonadIO m => Client -> String -> m () spWith client str = void $ liftIO $ call_ client (methodCall (objectPath_ "/org/mpris/MediaPlayer2") (interfaceName_ "org.mpris.MediaPlayer2.Player") (memberName_ str)) { methodCallDestination = Just (busName_ "org.mpris.MediaPlayer2.spotify") } sp :: MonadIO m => String -> m () sp str = do client <- liftIO connectSession spWith client str liftIO $ disconnect client -- | @since 0.1.2.0 audioNextWith :: MonadIO m => Client -> m () audioNextWith = flip spWith "Next" -- | @since 0.1.2.0 audioPrevWith :: MonadIO m => Client -> m () audioPrevWith = flip spWith "Previous" -- | @since 0.1.2.0 audioPlayPauseWith :: MonadIO m => Client -> m () audioPlayPauseWith = flip spWith "PlayPause" -- | @since 0.1.2.0 audioStopWith :: MonadIO m => Client -> m () audioStopWith = flip spWith "Stop" -- | Action in the 'X' monad to go to next audioNext :: MonadIO m => m () audioNext = sp "Next" -- | Action in the 'X' monad to go the previous audioPrev :: MonadIO m => m () audioPrev = sp "Previous" -- | Action in the 'X' monad to play/pause audioPlayPause :: MonadIO m => m () audioPlayPause = sp "PlayPause" audioStop :: MonadIO m => m () audioStop = sp "Stop"