gtk-sni-tray 0.1.8.0 → 0.1.8.1
raw patch · 3 files changed
+53/−23 lines, 3 filesdep ~gi-gdkdep ~gi-gtk
Dependency ranges changed: gi-gdk, gi-gtk
Files
- README.md +12/−7
- gtk-sni-tray.cabal +4/−4
- src/StatusNotifier/Tray.hs +37/−12
README.md view
@@ -1,14 +1,16 @@ gtk-sni-tray-===============+============++[](https://hackage.haskell.org/package/gtk-sni-tray) [](http://stackage.org/lts/package/gtk-sni-tray) [](http://stackage.org/nightly/package/gtk-sni-tray) -gtk-sni-tray provides a [StatusNotifierHost](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierHost/) widget written using the gtk+3 bindings for haskell provided by [gi-gtk](https://hackage.haskell.org/package/gi-gtk). It also provides a simple standalone executable, `gtk-sni-tray-standalone`, that is configured with command line arguments. This executable will run the aforementioned widget by itself in a strut window, on each monitor for each it is requested.+gtk-sni-tray provides a [StatusNotifierHost](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierHost/) widget written using the gtk+3 bindings for haskell provided by [gi-gtk](https://hackage.haskell.org/package/gi-gtk). It also provides a simple standalone executable, `gtk-sni-tray-standalone`, that is configured with command line arguments. This executable will run the aforementioned widget by itself in a strut window, on each monitor it is requested. taffybar------------It is generally recommeneded that you use this widget through [taffybar](https://github.com/travitch/taffybar) with [this module](https://github.com/travitch/taffybar/blob/master/src/System/Taffybar/Widget/SNITray.hs), which will allow you to combine it with other useful widgets, and will give more flexibility in configuration.+--------+It is generally recommeneded that you use this widget through [taffybar](https://github.com/travitch/taffybar) with [this module](https://github.com/travitch/taffybar/blob/master/src/System/Taffybar/Widget/SNITray.hs), which will allow you to combine it with other useful widgets, and will allow more flexibility in configuration. StatusNotifierWatcher---------------------------+--------------------- By default, it is assumed that you are running an isolated StatusNotifierWatcher daemon. [status-notifier-item](https://github.com/IvanMalison/status-notifier-item) provides a StatusNotifierWatcher executable that you can use for this purpose. If you get an error like ```@@ -18,7 +20,10 @@ when you start `gtk-sni-tray-standalone` it is probably because you have not started a StatusNotifierWatcher on your system. You can solve this problem by passing the `--watcher` flag to `gtk-sni-tray-standalone`, but this is not recommeneded, because many SNI processes do not monitor for new watcher processes, and so may not immediately register when this new watcher is started. Installation----------------+------------ -Both [`stack`](https://www.haskell.org/cabal/download.html) and [`cabal`](https://www.haskell.org/cabal/download.html) can be used to install gtk-sni-tray.+[`nix`](https://nixos.org/download.html),+[`stack`](https://docs.haskellstack.org/en/stable/README/) and+[`cabal`](https://www.haskell.org/cabal/download.html) can all be used to+install gtk-sni-tray.
gtk-sni-tray.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.34.4.+-- This file has been generated from package.yaml by hpack version 0.34.7. -- -- see: https://github.com/sol/hpack name: gtk-sni-tray-version: 0.1.8.0+version: 0.1.8.1 synopsis: A standalone StatusNotifierItem/AppIndicator tray description: Please see the README on Github at <https://github.com/IvanMalison/gtk-sni-tray#readme> category: System@@ -47,10 +47,10 @@ , gi-cairo-connector , gi-cairo-render , gi-dbusmenugtk3- , gi-gdk+ , gi-gdk >=3.0.25 && <4 , gi-gdkpixbuf >=2.0.16 , gi-glib- , gi-gtk >=3.0.21+ , gi-gtk >=3.0.38 && <4 , gtk-strut >=0.1.2.1 , haskell-gi >=0.21.2 , haskell-gi-base >=0.21.1
src/StatusNotifier/Tray.hs view
@@ -4,15 +4,18 @@ module StatusNotifier.Tray where import Control.Concurrent.MVar as MV+import Control.Exception.Base import Control.Exception.Enclosed (catchAny) import Control.Monad import Control.Monad.Trans.Class import Control.Monad.Trans.Maybe import DBus.Client import qualified DBus.Internal.Types as DBusTypes+import Data.Bool (bool) import qualified Data.ByteString as BS import Data.Coerce import Data.Foldable (traverse_)+import Data.GI.Base.GError import Data.Int import Data.List import qualified Data.Map.Strict as Map@@ -28,7 +31,7 @@ import GI.Gdk.Objects.Screen import GI.Gdk.Structs.EventScroll import GI.GdkPixbuf.Enums-import GI.GdkPixbuf.Objects.Pixbuf+import GI.GdkPixbuf.Objects.Pixbuf as Gdk import qualified GI.Gtk as Gtk import GI.Gtk.Flags import GI.Gtk.Objects.IconTheme@@ -70,7 +73,8 @@ targetWidth = case orientation of Gtk.OrientationHorizontal -> False _ -> True- (scaledWidth, scaledHeight) = getScaledWidthHeight targetWidth size width height+ (scaledWidth, scaledHeight) =+ getScaledWidthHeight targetWidth size width height trayLogger DEBUG $ printf "Scaling pb to %s, actualW: %s, actualH: %s, scaledW: %s, scaledH: %s"@@ -100,6 +104,26 @@ return themeForIcon +catchGErrorsAsLeft :: IO a -> IO (Either GError a)+catchGErrorsAsLeft action = catch (Right <$> action) (return . Left)++catchGErrorsAsNothing :: IO a -> IO (Maybe a)+catchGErrorsAsNothing action = catchGErrorsAsLeft action >>= rightToJustLogLeft+ where rightToJustLogLeft (Right value) = return $ Just value+ rightToJustLogLeft (Left error) = do+ trayLogger WARNING $ printf "Encountered error: %s" $ show error+ return Nothing++safePixbufNewFromFile :: FilePath -> IO (Maybe Gdk.Pixbuf)+safePixbufNewFromFile =+ handleResult . catchGErrorsAsNothing . Gdk.pixbufNewFromFile+ where+#if MIN_VERSION_gi_gdkpixbuf(2,0,26)+ handleResult = fmap join+#else+ handleResult = id+#endif+ getIconPixbufByName :: Int32 -> T.Text -> Maybe String -> IO (Maybe Pixbuf) getIconPixbufByName size name themePath = do trayLogger DEBUG $ printf "Getting Pixbuf from name for %s" name@@ -132,7 +156,7 @@ #else let handleResult = sequenceA #endif- handleResult $ pixbufNewFromFile <$> maybeFile+ handleResult $ safePixbufNewFromFile <$> maybeFile getIconPathFromThemePath :: String -> String -> IO (Maybe String) getIconPathFromThemePath name themePath = if name == "" then return Nothing else do@@ -297,7 +321,8 @@ when requestResize $ do trayLogger DEBUG "Requesting resize"- pixBuf <- getInfo info serviceName >>= getScaledPixBufFromInfo size+ pixBuf <- getInfo info serviceName >>=+ getScaledPixBufFromInfo size when (isNothing pixBuf) $ trayLogger WARNING $ printf "Got null pixbuf for info %s" $@@ -341,12 +366,11 @@ button <- Gdk.getEventButtonButton event x <- round <$> Gdk.getEventButtonXRoot event y <- round <$> Gdk.getEventButtonYRoot event- isMenu <- getInfoAttr itemIsMenu False serviceName- let action = if isMenu then PopupMenu else- case button of- 1 -> leftClickAction- 2 -> middleClickAction- 3 -> rightClickAction+ action <- case button of+ 1 -> bool leftClickAction PopupMenu <$> getInfoAttr+ itemIsMenu True serviceName+ 2 -> return middleClickAction+ _ -> return rightClickAction case action of Activate -> void $ IC.activate client serviceName servicePath x y SecondaryActivate -> void $ IC.secondaryActivate client@@ -385,7 +409,7 @@ updateHandler ItemRemoved ItemInfo { itemServiceName = name } = getContext name >>= removeWidget where removeWidget Nothing =- trayLogger INFO "Attempt to remove widget with unrecognized service name."+ trayLogger WARNING "removeWidget: unrecognized service name." removeWidget (Just ItemContext { contextButton = widgetToRemove }) = do Gtk.containerRemove trayBox widgetToRemove@@ -395,7 +419,8 @@ updateHandler OverlayIconUpdated i = updateIconFromInfo i updateHandler ToolTipUpdated info@ItemInfo { itemServiceName = name } =- void $ getContext name >>= traverse (flip setTooltipText info . contextButton)+ void $ getContext name >>=+ traverse (flip setTooltipText info . contextButton) updateHandler _ _ = return ()