33 * @brief Definitions for Qt tray menu implemenation
44 */
55// standard includes
6+ #include < chrono>
67#include < filesystem>
8+ #include < thread>
79
810// qt includes
911#include < QApplication>
2224
2325namespace {
2426 constexpr int DEFAULT_PANEL_THICKNESS = 24 ;
27+ constexpr int CURSOR_POSITION_POLL_INTERVAL_MS = 10 ;
28+ constexpr int CURSOR_POSITION_TIMEOUT_MS = 500 ;
2529 constexpr int CURSOR_POSITION_TOLERANCE = 2 ;
2630
2731 bool positionsAreClose (const QPoint &first, const QPoint &second) {
2832 return (first - second).manhattanLength () <= CURSOR_POSITION_TOLERANCE ;
2933 }
3034
35+ bool waitForCursorPosition (const QPoint &targetPosition, const QRect &targetGeometry = {}) {
36+ const auto deadline = std::chrono::steady_clock::now () + std::chrono::milliseconds (CURSOR_POSITION_TIMEOUT_MS );
37+ do {
38+ const QPoint currentPosition = QCursor::pos ();
39+ if (targetGeometry.isValid () ? targetGeometry.contains (currentPosition) : positionsAreClose (currentPosition, targetPosition)) {
40+ return true ;
41+ }
42+ std::this_thread::sleep_for (std::chrono::milliseconds (CURSOR_POSITION_POLL_INTERVAL_MS ));
43+ } while (std::chrono::steady_clock::now () < deadline);
44+
45+ const QPoint currentPosition = QCursor::pos ();
46+ return targetGeometry.isValid () ? targetGeometry.contains (currentPosition) : positionsAreClose (currentPosition, targetPosition);
47+ }
48+
3149 bool fallbackTrayIconPosition (QPoint *position) {
3250 const QScreen *screen = QGuiApplication::primaryScreen ();
3351 if (screen == nullptr ) {
@@ -405,8 +423,7 @@ bool QtTrayMenu::positionMouseOverIcon() {
405423 mousePositionSaved = true ;
406424 }
407425 QCursor::setPos (targetPosition);
408- const QPoint currentPosition = QCursor::pos ();
409- const bool positioned = iconGeometry.isValid () ? iconGeometry.contains (currentPosition) : positionsAreClose (currentPosition, targetPosition);
426+ const bool positioned = waitForCursorPosition (targetPosition, iconGeometry);
410427 if (!positioned) {
411428 qWarning (" QtTrayMenu: could not position the mouse over the tray icon" );
412429 }
@@ -419,8 +436,8 @@ bool QtTrayMenu::restoreMousePosition() {
419436 }
420437
421438 QCursor::setPos (savedMousePosition);
439+ const bool restored = waitForCursorPosition (savedMousePosition);
422440 mousePositionSaved = false ;
423- const bool restored = positionsAreClose (QCursor::pos (), savedMousePosition);
424441 if (!restored) {
425442 qWarning (" QtTrayMenu: could not restore the saved mouse position" );
426443 }
0 commit comments