diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -214,6 +214,9 @@
             , trayIconExpand = expand
             , trayAlignment = align
             , trayOverlayScale = overlayScale
+            , trayLeftClickAction = Activate
+            , trayMiddleClickAction = SecondaryActivate
+            , trayRightClickAction = PopupMenu
             }
         window <- Gtk.windowNew Gtk.WindowTypeToplevel
         when (not noStrut) $
diff --git a/gtk-sni-tray.cabal b/gtk-sni-tray.cabal
--- a/gtk-sni-tray.cabal
+++ b/gtk-sni-tray.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           gtk-sni-tray
-version:        0.1.6.2
+version:        0.1.7.0
 synopsis:       A standalone StatusNotifierItem/AppIndicator tray
 description:    Please see the README on Github at <https://github.com/IvanMalison/gtk-sni-tray#readme>
 category:       System
@@ -79,7 +79,7 @@
     , gtk-strut
     , hslogger
     , optparse-applicative
-    , status-notifier-item >=0.3.0.0 && <0.4.0.0
+    , status-notifier-item >=0.3.1.0 && <0.4.0.0
     , text
     , unix
   default-language: Haskell2010
diff --git a/src/StatusNotifier/Tray.hs b/src/StatusNotifier/Tray.hs
--- a/src/StatusNotifier/Tray.hs
+++ b/src/StatusNotifier/Tray.hs
@@ -12,6 +12,7 @@
 import qualified DBus.Internal.Types as DBusTypes
 import qualified Data.ByteString as BS
 import           Data.Coerce
+import           Data.Foldable (traverse_)
 import           Data.Int
 import           Data.List
 import qualified Data.Map.Strict as Map
@@ -24,6 +25,7 @@
 import qualified GI.Gdk as Gdk
 import           GI.Gdk.Enums
 import           GI.Gdk.Objects.Screen
+import           GI.Gdk.Structs.EventScroll
 import           GI.GdkPixbuf.Enums
 import           GI.GdkPixbuf.Objects.Pixbuf
 import qualified GI.Gtk as Gtk
@@ -163,6 +165,8 @@
 
 data TrayImageSize = Expand | TrayImageSize Int32
 
+data TrayClickAction = Activate | SecondaryActivate | PopupMenu
+
 data TrayParams = TrayParams
   { trayHost :: Host
   , trayClient :: Client
@@ -171,6 +175,9 @@
   , trayIconExpand :: Bool
   , trayAlignment :: StrutAlignment
   , trayOverlayScale :: Rational
+  , trayLeftClickAction :: TrayClickAction
+  , trayMiddleClickAction :: TrayClickAction
+  , trayRightClickAction :: TrayClickAction
   }
 
 buildTray :: TrayParams -> IO Gtk.Box
@@ -185,6 +192,9 @@
                      , trayIconExpand = shouldExpand
                      , trayAlignment = alignment
                      , trayOverlayScale = overlayScale
+                     , trayLeftClickAction = leftClickAction
+                     , trayMiddleClickAction = middleClickAction
+                     , trayRightClickAction = rightClickAction
                      } = do
   trayLogger INFO "Building tray"
 
@@ -201,8 +211,11 @@
           _ ->
             Gdk.getRectangleWidth rectangle
 
-      getInfo def name = fromMaybe def . Map.lookup name <$> getInfoMap
+      getInfoAttr fn def name = maybe def fn . Map.lookup name <$> getInfoMap
 
+      getInfo :: ItemInfo -> DBusTypes.BusName -> IO ItemInfo
+      getInfo = getInfoAttr id
+
       updateIconFromInfo info@ItemInfo { itemServiceName = name } =
         getContext name >>= updateIcon
         where updateIcon Nothing = updateHandler ItemAdded info
@@ -244,6 +257,7 @@
           trayLogger INFO logText
 
           button <- Gtk.eventBoxNew
+          Gtk.widgetAddEvents button [Gdk.EventMaskScrollMask]
 
           image <-
             case imageSize of
@@ -312,11 +326,41 @@
               popupItemForMenu menu =
                 Gtk.menuPopupAtWidget menu image
                    GravitySouthWest GravityNorthWest Nothing
-              popupItemMenu =
-                maybe activateItem popupItemForMenu maybeMenu >> return False
-              activateItem = void $ IC.activate client serviceName servicePath 0 0
 
-          _ <- Gtk.onWidgetButtonPressEvent button $ const popupItemMenu
+          _ <- Gtk.onWidgetButtonPressEvent button $ \event -> do
+            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
+            case action of
+              Activate -> void $ IC.activate client serviceName servicePath x y
+              SecondaryActivate -> void $ IC.secondaryActivate client
+                                   serviceName servicePath x y
+              PopupMenu -> maybe (return ()) popupItemForMenu maybeMenu
+            return False
+          _ <- Gtk.onWidgetScrollEvent button $ \event -> do
+            direction <- getEventScrollDirection event
+            let direction' = case direction of
+                               ScrollDirectionUp -> Just "vertical"
+                               ScrollDirectionDown -> Just "vertical"
+                               ScrollDirectionLeft -> Just "horizontal"
+                               ScrollDirectionRight -> Just "horizontal"
+                               _ -> Nothing
+                -- deltaX/deltaY are provided only in case of smooth scrolling which
+                -- is enabled via additional flag, we don't to enable/handle it
+                delta = case direction of
+                          ScrollDirectionUp -> -1
+                          ScrollDirectionDown -> 1
+                          ScrollDirectionLeft -> -1
+                          ScrollDirectionRight -> 1
+                          _ -> 0
+            traverse_ (IC.scroll client serviceName servicePath delta) direction'
+            return False
 
           MV.modifyMVar_ contextMap $ return . Map.insert serviceName context
 
@@ -377,10 +421,12 @@
                                       } = getPixBufFrom size name mpath pixmaps
 
       getOverlayPixBufFromInfo size
-                               info@ItemInfo { overlayIconName = name
-                                             , iconThemePath = mpath
-                                             , overlayIconPixmaps = pixmaps
-                                             } = getPixBufFrom size (fromMaybe "" name) mpath pixmaps
+                               info@ItemInfo
+                                     { overlayIconName = name
+                                     , iconThemePath = mpath
+                                     , overlayIconPixmaps = pixmaps
+                                     } = getPixBufFrom size (fromMaybe "" name)
+                               mpath pixmaps
 
       getPixBufFrom size name mpath pixmaps = do
         let tooSmall (w, h, _) = w < size || h < size
