gtk-sni-tray 0.1.10.2 → 0.1.10.3
raw patch · 3 files changed
+74/−43 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- StatusNotifier.Tray: getIconPixbufFromByteString :: Int32 -> Int32 -> ByteString -> IO Pixbuf
+ StatusNotifier.Tray: getIconPixbufFromByteString :: Int32 -> Int32 -> ByteString -> IO (Maybe Pixbuf)
Files
- gtk-sni-tray.cabal +1/−1
- src/StatusNotifier/DBusMenu.hs +19/−9
- src/StatusNotifier/Tray.hs +54/−33
gtk-sni-tray.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: gtk-sni-tray-version: 0.1.10.2+version: 0.1.10.3 synopsis: A standalone StatusNotifierItem/AppIndicator tray description: Please see the README on Github at <https://github.com/IvanMalison/gtk-sni-tray#readme> category: System
src/StatusNotifier/DBusMenu.hs view
@@ -3,6 +3,7 @@ ( buildMenu ) where +import Control.Exception.Enclosed (catchAny) import Control.Monad (forM_, when) import Data.Int (Int32) import Data.Map.Strict (Map)@@ -15,6 +16,7 @@ import Data.GI.Base (unsafeCastTo) import qualified GI.Gtk as Gtk import System.Log.Logger (Priority(..), logM)+import Text.Printf dbusMenuLogger :: Priority -> String -> IO () dbusMenuLogger = logM "StatusNotifier.DBusMenu"@@ -171,9 +173,13 @@ -- Submenu handling: build children now, and refresh on show via AboutToShow/GetLayout. if null (lnChildren node) then do- _ <- Gtk.onMenuItemActivate item $ do- ts <- Gtk.getCurrentEventTime- sendClicked client dest path (lnId node) ts+ _ <- Gtk.onMenuItemActivate item $+ catchAny+ (do ts <- Gtk.getCurrentEventTime+ sendClicked client dest path (lnId node) ts)+ (\e -> dbusMenuLogger WARNING $+ printf "Menu item %d click failed (stale ID?): %s"+ (lnId node) (show e)) pure () else do addCssClass itemW "tray-menu-item-has-submenu"@@ -184,12 +190,16 @@ -- Populate with the eagerly-fetched layout so submenus are usable even if -- the service doesn't support/require lazy updates. populateGtkMenu client dest path submenu node- let refresh = do- -- Allow the service to update the submenu content lazily.- _ <- aboutToShow client dest path (lnId node)- (_, layout) <- getLayout client dest path (lnId node) 1 []- populateGtkMenu client dest path submenu layout- Gtk.widgetShowAll submenu+ let refresh =+ catchAny+ (do -- Allow the service to update the submenu content lazily.+ _ <- aboutToShow client dest path (lnId node)+ (_, layout) <- getLayout client dest path (lnId node) 1 []+ populateGtkMenu client dest path submenu layout+ Gtk.widgetShowAll submenu)+ (\e -> dbusMenuLogger WARNING $+ printf "Submenu %d refresh failed (stale ID?): %s"+ (lnId node) (show e)) _ <- Gtk.onWidgetShow submenu refresh Gtk.menuItemSetSubmenu item (Just submenu)
src/StatusNotifier/Tray.hs view
@@ -72,22 +72,25 @@ height <- pixbufGetHeight pixbuf let warnAndReturnOrig = trayLogger WARNING "Unable to scale pixbuf" >> return pixbuf- targetWidth = case orientation of- Gtk.OrientationHorizontal -> False- _ -> True- (scaledWidth, scaledHeight) =- getScaledWidthHeight targetWidth size width height- trayLogger DEBUG $- printf- "Scaling pb to %s, actualW: %s, actualH: %s, scaledW: %s, scaledH: %s"- (show size) (show width) (show height)- (show scaledWidth) (show scaledHeight)-- trayLogger DEBUG $ printf "targetW: %s, targetH: %s"+ if width <= 0 || height <= 0+ then warnAndReturnOrig+ else do+ let targetWidth = case orientation of+ Gtk.OrientationHorizontal -> False+ _ -> True+ (scaledWidth, scaledHeight) =+ getScaledWidthHeight targetWidth size width height+ trayLogger DEBUG $+ printf+ "Scaling pb to %s, actualW: %s, actualH: %s, scaledW: %s, scaledH: %s"+ (show size) (show width) (show height) (show scaledWidth) (show scaledHeight)- maybe warnAndReturnOrig return =<<- pixbufScaleSimple pixbuf scaledWidth scaledHeight InterpTypeBilinear + trayLogger DEBUG $ printf "targetW: %s, targetH: %s"+ (show scaledWidth) (show scaledHeight)+ maybe warnAndReturnOrig return =<<+ pixbufScaleSimple pixbuf scaledWidth scaledHeight InterpTypeBilinear+ themeLoadFlags :: [IconLookupFlags] themeLoadFlags = [IconLookupFlagsGenericFallback, IconLookupFlagsUseBuiltin] @@ -174,14 +177,18 @@ return $ (themePath </>) <$> find (isPrefixOf name) fileNames else return Nothing -getIconPixbufFromByteString :: Int32 -> Int32 -> BS.ByteString -> IO Pixbuf-getIconPixbufFromByteString width height byteString = do- trayLogger DEBUG "Getting Pixbuf from bytestring"- bytes <- bytesNew $ Just byteString- let bytesPerPixel = 4- rowStride = width * bytesPerPixel- sampleBits = 8- pixbufNewFromBytes bytes ColorspaceRgb True sampleBits width height rowStride+getIconPixbufFromByteString :: Int32 -> Int32 -> BS.ByteString -> IO (Maybe Pixbuf)+getIconPixbufFromByteString width height byteString+ | width <= 0 || height <= 0 = do+ trayLogger WARNING $ printf "Invalid icon dimensions: %dx%d" width height+ return Nothing+ | otherwise = catchGErrorsAsNothing $ do+ trayLogger DEBUG "Getting Pixbuf from bytestring"+ bytes <- bytesNew $ Just byteString+ let bytesPerPixel = 4+ rowStride = width * bytesPerPixel+ sampleBits = 8+ pixbufNewFromBytes bytes ColorspaceRgb True sampleBits width height rowStride data ItemContext = ItemContext { contextName :: DBusTypes.BusName@@ -379,18 +386,25 @@ itemIsMenu True serviceName 2 -> return middleClickAction _ -> return rightClickAction+ let logActionError actionName e =+ trayLogger WARNING $ printf "%s failed for %s: %s"+ (actionName :: String)+ (coerce serviceName :: String)+ (show e) case action of- Activate -> void $ IC.activate client serviceName servicePath x y- SecondaryActivate -> void $ IC.secondaryActivate client- serviceName servicePath x y+ Activate -> catchAny+ (void $ IC.activate client serviceName servicePath x y)+ (logActionError "Activate")+ SecondaryActivate -> catchAny+ (void $ IC.secondaryActivate client+ serviceName servicePath x y)+ (logActionError "SecondaryActivate") PopupMenu -> do menuPath' <- getInfoAttr menuPath Nothing serviceName traverse_ (\p -> catchAny (DBusMenu.buildMenu client serviceName p >>= (`popupGtkMenu` event))- (\e -> trayLogger WARNING $ printf "Failed to build menu for %s: %s"- (coerce serviceName :: String)- (show e)))+ (logActionError "PopupMenu")) menuPath' return False _ <- Gtk.onWidgetScrollEvent eventBox $ \event -> do@@ -409,7 +423,10 @@ ScrollDirectionLeft -> -1 ScrollDirectionRight -> 1 _ -> 0- traverse_ (IC.scroll client serviceName servicePath delta) direction'+ traverse_ (\d -> catchAny+ (void $ IC.scroll client serviceName servicePath delta d)+ (\e -> trayLogger WARNING $ printf "Scroll failed for %s: %s"+ (coerce serviceName :: String) (show e))) direction' return False MV.modifyMVar_ contextMap $ return . Map.insert serviceName context@@ -492,15 +509,19 @@ else minimumBy orderer largeEnough getFromPixmaps (w, h, p) = if BS.length p == 0- then Nothing- else Just $ getIconPixbufFromByteString w h p+ then return Nothing+ else getIconPixbufFromByteString w h p if null pixmaps then getIconPixbufByName size (T.pack name) mpath- else sequenceA $ getFromPixmaps selectedPixmap+ else getFromPixmaps selectedPixmap uiUpdateHandler updateType info = void $ Gdk.threadsAddIdle GLib.PRIORITY_DEFAULT $- updateHandler updateType info >> return False+ catchAny+ (updateHandler updateType info >> return False)+ (\e -> do+ trayLogger WARNING $ printf "Update handler failed: %s" (show e)+ return False) handlerId <- addUHandler uiUpdateHandler _ <- Gtk.onWidgetDestroy trayBox $ removeUHandler handlerId