From 1f9699c67e292bf0242126b0e5bccdc17b95e06b Mon Sep 17 00:00:00 2001
From: Benjamin Arnaud <benjamin.arnaud@videolabs.io>
Date: Thu, 5 May 2022 16:27:57 +0200
Subject: [PATCH] qt/QmlMenuPositioner: Fix the QMenu positioning

---
 modules/gui/qt/menus/qml_menu_wrapper.cpp | 24 ++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/modules/gui/qt/menus/qml_menu_wrapper.cpp b/modules/gui/qt/menus/qml_menu_wrapper.cpp
index 176b43db9027..1e3793f60e44 100644
--- a/modules/gui/qt/menus/qml_menu_wrapper.cpp
+++ b/modules/gui/qt/menus/qml_menu_wrapper.cpp
@@ -35,7 +35,9 @@
 #include "playlist/playlist_model.hpp"
 #include "dialogs/dialogs_provider.hpp"
 
+// Qt includes
 #include <QSignalMapper>
+#include <QScreen>
 
 namespace
 {
@@ -386,12 +388,28 @@ bool QmlMenuPositioner::eventFilter(QObject * object, QEvent * event)
 {
     if (event->type() == QEvent::Resize)
     {
+        QScreen * screen = QGuiApplication::screenAt(m_position);
+
+        if (screen == nullptr)
+            return QObject::eventFilter(object, event);
+
         QMenu * menu = static_cast<QMenu *> (object);
 
-        int x = m_position.x();
-        int y = m_position.y();
+        int width  = menu->width();
+        int height = menu->height();
+
+        QRect geometry = screen->availableGeometry();
+
+        int x = geometry.x();
+        int y = geometry.y();
+
+        // NOTE: We want a position within the screen boundaries.
+
+        x = qBound(x, m_position.x(), x + geometry.width() - width);
+
+        y = qBound(y, m_position.y() - height, y + geometry.height() - height);
 
-        menu->move(QPoint(x, y - menu->height()));
+        menu->move(QPoint(x, y));
     }
 
     return QObject::eventFilter(object, event);
-- 
GitLab