tianbar 0.4.4.0 → 0.4.5.0
raw patch · 4 files changed
+109/−42 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- scripts/dbus.js +13/−1
- scripts/power.js +44/−26
- src/System/Tianbar/Plugin/DBus.hs +51/−14
- tianbar.cabal +1/−1
scripts/dbus.js view
@@ -19,7 +19,7 @@ * Listen for a particular DBus event. * @param match {Object} DBus match conditions ('path', 'iface', 'member') * @param handler {Function} The function to call upon receiving the event- * @returns {Callbacks} A jQuery callback object+ * @returns {Event} A Tianbar event object */ listen: function (match) { var evt = tianbar.createEvent();@@ -32,6 +32,18 @@ }); return evt.callback;+ },++ /**+ * Stop listening for a DBus event.+ * @param evt {Event} A Tianbar event object returned by listen().+ */+ removeMatch: function (evt) {+ $.ajax('tianbar:///dbus/' + busName + '/stop', {+ data: {+ index: evt.index+ }+ }); }, /**
scripts/power.js view
@@ -193,6 +193,23 @@ self.updated = $.Callbacks(); + // A map of device paths to device states+ self.devices = {};++ // Display the status of all the devices+ self.display = function () {+ // TODO: support updating individual devices+ var widget = self.widget();+ widget.empty();++ $.each(self.devices, function (_, device) {+ widget.append(self.formatDevice(device));+ });++ self.updated.fire();+ };++ // Refresh the device list and each device status self.refresh = function () { dbus.system.call({ 'destination': 'org.freedesktop.UPower',@@ -203,39 +220,40 @@ ] }).done(function (devices) { devices = devices.body[0];- var queries = $.map(devices, function(device) {- return dbus.system.call({- 'destination': 'org.freedesktop.UPower',- 'path': device,- 'iface': 'org.freedesktop.DBus.Properties',- 'member': 'GetAll',- 'body': [- 'string:org.freedesktop.UPower.Device',- ]- });+ // TODO: support device add and removal+ $.each(devices, function(_, device) {+ dbus.system.listen(+ { path: device }+ ).add(function() {+ self.refreshDevice(device);+ }+ );+ self.refreshDevice(device); });- $.when.apply($, queries).then(function (results) {- results = Array.prototype.slice.call(arguments, 0);-- var widget = self.widget();- widget.empty();- $.each(results, function (_, st) {- st = st.body[0];- widget.append(self.formatDevice(st));- });+ });+ }; - self.updated.fire();- });+ // Refresh an individual device+ self.refreshDevice = function (device) {+ dbus.system.call({+ 'destination': 'org.freedesktop.UPower',+ 'path': device,+ 'iface': 'org.freedesktop.DBus.Properties',+ 'member': 'GetAll',+ 'body': [+ 'string:org.freedesktop.UPower.Device',+ ]+ }).done(function (properties) {+ properties = properties.body[0];+ self.devices[device] = properties;+ self.display(); }); }; $(document).ready(function () { dbus.system.listen(- {- iface: 'org.freedesktop.UPower'- },- self.refresh- );+ { path: '/org/freedesktop/UPower' }+ ).add(self.refresh); self.refresh(); });
src/System/Tianbar/Plugin/DBus.hs view
@@ -1,11 +1,14 @@-module System.Tianbar.Plugin.DBus where+module System.Tianbar.Plugin.DBus (DBusPlugin) where -- DBus connectivity +import Control.Applicative+import Control.Concurrent import Control.Monad import Control.Monad.IO.Class import Data.Aeson (encode)+import qualified Data.Map as M import Happstack.Server @@ -16,43 +19,77 @@ import System.Tianbar.Plugin.DBus.JSON () import System.Tianbar.Plugin.DBus.FromData () +data Bus = Bus { busClient :: Client+ , busSignals :: MVar (M.Map String SignalHandler)+ }++busNew :: IO Client -> IO Bus+busNew conn = Bus <$> conn <*> newMVar M.empty++busDestroy :: Bus -> IO ()+-- TODO: remove signals?+busDestroy = disconnect . busClient++busAddListener :: (MonadIO m) => Bus -> String -> SignalHandler -> m ()+busAddListener bus index listener = liftIO $ modifyMVar_ (busSignals bus) $ \listeners ->+ return $ M.insert index listener listeners++busPopListener :: (MonadIO m) => Bus -> String -> m (Maybe SignalHandler)+busPopListener bus index = liftIO $ modifyMVar (busSignals bus) $ \listeners -> do+ let listener = M.lookup index listeners+ let listeners' = M.delete index listeners+ return (listeners', listener)+ data DBusPlugin = DBusPlugin { dbusHost :: Callbacks- , dbusSession :: Client- , dbusSystem :: Client+ , dbusSession :: Bus+ , dbusSystem :: Bus } -busNameMap :: [(String, DBusPlugin -> Client)]+busNameMap :: [(String, DBusPlugin -> Bus)] busNameMap = [ ("session", dbusSession) , ("system", dbusSystem) ] instance Plugin DBusPlugin where initialize c = do- session <- connectSession- system <- connectSystem+ session <- busNew connectSession+ system <- busNew connectSystem return $ DBusPlugin c session system - destroy plugin = mapM_ disconnect [dbusSession plugin, dbusSystem plugin]+ destroy plugin = mapM_ busDestroy [dbusSession plugin, dbusSystem plugin] handler plugin = dir "dbus" $ msum [ busHandler plugin busName (bus plugin) | (busName, bus) <- busNameMap ] -busHandler :: DBusPlugin -> String -> Client -> ServerPartT IO Response+busHandler :: DBusPlugin -> String -> Bus -> ServerPartT IO Response busHandler plugin busName bus = dir busName $ msum [ mzero , listenHandler plugin bus+ , stopHandler plugin bus , callHandler plugin bus ] -listenHandler :: DBusPlugin -> Client -> ServerPartT IO Response-listenHandler plugin client = dir "listen" $ withData $ \matcher -> do+listenHandler :: DBusPlugin -> Bus -> ServerPartT IO Response+listenHandler plugin bus = dir "listen" $ withData $ \matcher -> do nullDir index <- look "index"- _ <- liftIO $ addMatch client matcher $ \sig -> callback (dbusHost plugin) index [sig]+ listener <- liftIO $ addMatch (busClient bus) matcher $ \sig -> callback (dbusHost plugin) index [sig]+ busAddListener bus index listener return $ toResponse ("ok" :: String) -callHandler :: DBusPlugin -> Client -> ServerPartT IO Response-callHandler _ client = dir "call" $ withData $ \mcall -> do+stopHandler :: DBusPlugin -> Bus -> ServerPartT IO Response+stopHandler _ bus = dir "stop" $ do nullDir- res <- liftIO $ call client mcall+ index <- look "index"+ listener <- busPopListener bus index+ case listener of+ Just l -> do+ liftIO $ removeMatch (busClient bus) l+ return $ toResponse ("ok" :: String)+ Nothing -> mzero++callHandler :: DBusPlugin -> Bus -> ServerPartT IO Response+callHandler _ bus = dir "call" $ withData $ \mcall -> do+ nullDir+ res <- liftIO $ call (busClient bus) mcall return $ toResponse $ encode res
tianbar.cabal view
@@ -1,5 +1,5 @@ name: tianbar-version: 0.4.4.0+version: 0.4.5.0 synopsis: A desktop bar based on WebKit description: A desktop bar using WebKit for rendering as much as possible.