Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix fromJust exception in Volume plugin #90

Closed
wants to merge 1 commit into from

2 participants

@dmalikov

Suppose there is no PCM alsa device.

Xmobar failed with error: Maybe.fromJust: Nothing exception running with following config:

Config { persistent = True
       , lowerOnStart = False
       , hideOnStart = False
       , font = "-*-terminus-medium-r-normal--12-*"
       , border = NoBorder
       , borderColor = "#1c1c1c"
       , bgColor = "#1c1c1c"
       , fgColor = "#8080A1"
       , position = Static { xpos = 120
                           , ypos = 1060
                           , width = 1800
                           , height = 20
                           }
       , commands = [ Run Volume "default" "PCM" [] 5, Run StdinReader ]
       , sepChar = "%"
       , alignSep = "}{"
       , template = " %StdinReader% }{ %default:PCM% "
       }
@jaor
Owner

I'm getting this compilation error in ghc 7.4.1:

src/Plugins/Monitors/Volume.hs:141:27:
    Ambiguous occurrence `catch'
    It could refer to either `Prelude.catch',
                             imported from `Prelude' at src/Plugins/Monitors/Volume.hs:15:8-30
                             (and originally defined in `System.IO.Error')
                          or `Sound.ALSA.Exception.catch',
                             imported from `Sound.ALSA.Exception' at src/Plugins/Monitors/Volume.hs:22:31-35
@jaor
Owner

pressed 'send' too soon, sorry... i can solve the problem with import Prelude hiding (catch): does that work also in ghc 7.6?

@jaor
Owner

@dmalikov, while we're at it, we might also take a look at http://code.google.com/p/xmobar/issues/detail?id=79, if you feel like it... (but i can do that if you don't, no problem)

@dmalikov

Yep, in ghc-7.6 there is a warning

src/Plugins/Monitors/Volume.hs:17:1: Warning:
    Module `Prelude' does not export `catch'

So I returned it back.

@dmalikov

I can't reproduce different values in xmobar and alsamixer. They are the same :[

@jaor
Owner
@jaor
Owner
@jaor jaor closed this
@dmalikov

Compiles and works fine on 7.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 3, 2013
  1. @dmalikov
This page is out of date. Refresh to see the latest.
Showing with 49 additions and 17 deletions.
  1. +49 −17 src/Plugins/Monitors/Volume.hs
View
66 src/Plugins/Monitors/Volume.hs
@@ -15,8 +15,9 @@
module Plugins.Monitors.Volume (runVolume, volumeConfig) where
import Prelude hiding ( catch )
-import Control.Monad ( liftM, mplus )
-import Data.Maybe
+import Control.Applicative ((<$>))
+import Control.Monad ( join, liftM2, liftM3, mplus )
+import Data.Traversable (sequenceA)
import Plugins.Monitors.Common
import Sound.ALSA.Mixer
import Sound.ALSA.Exception ( catch )
@@ -110,19 +111,50 @@ formatDb opts dbi = do
runVolume :: String -> String -> [String] -> Monitor String
runVolume mixerName controlName argv = do
opts <- io $ parseOpts argv
- control <- liftM fromJust $ io $ getControlByName mixerName controlName
- let volumeControl = fromJust $ mplus (playback $ volume control)
- (common $ volume control)
- switchControl = fromJust $ mplus (playback $ switch control)
- (common $ switch control)
- maybeNA = maybe (return "N/A")
- (lo, hi) <- io $ getRange volumeControl
- val <- io $ getChannel FrontLeft $ value volumeControl
- db <- io $ catch (getChannel FrontLeft $ dB volumeControl)
- (\_ -> return $ Just 0)
- sw <- io $ getChannel FrontLeft switchControl
- p <- maybeNA (formatVol lo hi) val
- b <- maybeNA (formatVolBar lo hi) val
- d <- maybeNA (formatDb opts) db
- s <- maybeNA (formatSwitch opts) sw
+ control <- io $ getControlByName mixerName controlName
+ (lo, hi) <- io . liftMaybe $ getRange <$> volumeControl control
+ val <- getVal $ volumeControl control
+ db <- getDB $ volumeControl control
+ sw <- getSw $ switchControl control
+ p <- liftMonitor $ liftM3 formatVol lo hi val
+ b <- liftMonitor $ liftM3 formatVolBar lo hi val
+ d <- getFormatDB opts db
+ s <- getFormatSwitch opts sw
parseTemplate [p, b, d, s]
+
+ where
+
+ volumeControl :: Maybe Control -> Maybe Volume
+ volumeControl c = join $ (playback . volume <$> c) `mplus` (common . volume <$> c)
+
+ switchControl :: Maybe Control -> Maybe Switch
+ switchControl c = join $ (playback . switch <$> c) `mplus` (common . switch <$> c)
+
+ liftMaybe :: Maybe (IO (a,b)) -> IO (Maybe a, Maybe b)
+ liftMaybe = fmap (liftM2 (,) (fmap fst) (fmap snd)) . sequenceA
+
+ liftMonitor :: Maybe (Monitor String) -> Monitor String
+ liftMonitor Nothing = return unavailable
+ liftMonitor (Just m) = m
+
+ getDB :: Maybe Volume -> Monitor (Maybe Integer)
+ getDB Nothing = return Nothing
+ getDB (Just v) = io $ catch (getChannel FrontLeft $ dB v) (const $ return $ Just 0)
+
+ getVal :: Maybe Volume -> Monitor (Maybe Integer)
+ getVal Nothing = return Nothing
+ getVal (Just v) = io $ getChannel FrontLeft $ value v
+
+ getSw :: Maybe Switch -> Monitor (Maybe Bool)
+ getSw Nothing = return Nothing
+ getSw (Just s) = io $ getChannel FrontLeft s
+
+ getFormatDB :: VolumeOpts -> Maybe Integer -> Monitor String
+ getFormatDB _ Nothing = return unavailable
+ getFormatDB opts (Just d) = formatDb opts d
+
+ getFormatSwitch :: VolumeOpts -> Maybe Bool -> Monitor String
+ getFormatSwitch _ Nothing = return unavailable
+ getFormatSwitch opts (Just sw) = formatSwitch opts sw
+
+ unavailable = "N/A"
Something went wrong with that request. Please try again.