diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # Changelog for gtk-sni-tray
 
+## 0.1.11.3
+
+- Fix menu popup positioning: use `menuPopupAtPointer` with the actual button
+  press event (via `getCurrentEvent`) so the menu appears at the click location
+  instead of at an incorrect widget-relative position.
+
 ## 0.1.11.2
 
 - Add upper bounds to all dependencies per PVP.
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.11.2
+version:        0.1.11.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
diff --git a/src/StatusNotifier/Tray.hs b/src/StatusNotifier/Tray.hs
--- a/src/StatusNotifier/Tray.hs
+++ b/src/StatusNotifier/Tray.hs
@@ -377,20 +377,20 @@
                             , contextButton = eventBox
                             }
 
-              popupGtkMenu gtkMenu _triggerEvent = do
+              popupGtkMenu gtkMenu mEvent = do
                 Gtk.menuAttachToWidget gtkMenu eventBox Nothing
                 _ <- Gtk.onWidgetHide gtkMenu $
                   void $ GLib.idleAdd GLib.PRIORITY_LOW $ do
                     Gtk.widgetDestroy gtkMenu
                     return False
                 Gtk.widgetShowAll gtkMenu
-                -- Use menuPopupAtWidget: menuPopupAtPointer fails on
-                -- Wayland/layer-shell with "no trigger event" because the
-                -- GdkEvent's window is not a valid GDK surface.
-                Gtk.menuPopupAtWidget gtkMenu eventBox
-                  Gdk.GravitySouth Gdk.GravityNorth Nothing
+                Gtk.menuPopupAtPointer gtkMenu mEvent
 
           _ <- Gtk.onWidgetButtonPressEvent eventBox $ \event -> do
+            -- Capture the current event as a Gdk.Event before any
+            -- blocking calls (DBus etc.) so menuPopupAtPointer can
+            -- use its coordinates for popup positioning.
+            currentEvent <- Gtk.getCurrentEvent
             mouseButton <- Gdk.getEventButtonButton event
             x <- round <$> Gdk.getEventButtonXRoot event
             y <- round <$> Gdk.getEventButtonYRoot event
@@ -449,7 +449,7 @@
                          return ()
                        HaskellDBusMenu -> do
                          gtkMenu <- DBusMenu.buildMenu client serviceName p
-                         popupGtkMenu gtkMenu event)
+                         popupGtkMenu gtkMenu currentEvent)
                     (logActionError "PopupMenu"))
                   menuPath'
             return False
