diff --git a/src/Gui/CommandView.cpp b/src/Gui/CommandView.cpp index b292d152fb..e63e66e250 100644 --- a/src/Gui/CommandView.cpp +++ b/src/Gui/CommandView.cpp @@ -3990,16 +3990,22 @@ void StdCmdClarifySelection::activated(int iMsg) return; } - // Get cursor position in the viewer - QPoint pos = QCursor::pos(); QWidget* widget = viewer->getGLWidget(); if (!widget) { return; } - QPoint local = widget->mapFromGlobal(pos); - SbVec2s point(static_cast(local.x()), - static_cast(widget->height() - local.y() - 1)); + // check if we have a stored right-click position (context menu) or should use current cursor position (keyboard shortcut) + SbVec2s point; + auto& storedPosition = viewer->navigationStyle()->getRightClickPosition(); + if (storedPosition.has_value()) { + point = storedPosition.value(); + } else { + QPoint pos = QCursor::pos(); + QPoint local = widget->mapFromGlobal(pos); + point = SbVec2s(static_cast(local.x()), + static_cast(widget->height() - local.y() - 1)); + } // Use ray picking to get all objects under cursor SoRayPickAction pickAction(viewer->getSoRenderManager()->getViewportRegion()); @@ -4063,9 +4069,16 @@ void StdCmdClarifySelection::activated(int iMsg) return; } + QPoint globalPos; + if (storedPosition.has_value()) { + globalPos = widget->mapToGlobal(QPoint(point[0], widget->height() - point[1] - 1)); + } else { + globalPos = QCursor::pos(); + } + // Use SelectionMenu to display and handle the pick menu SelectionMenu contextMenu(widget); - contextMenu.doPick(selections); + contextMenu.doPick(selections, globalPos); } bool StdCmdClarifySelection::isActive() diff --git a/src/Gui/Navigation/NavigationStyle.cpp b/src/Gui/Navigation/NavigationStyle.cpp index 03c9447438..9c97445e34 100644 --- a/src/Gui/Navigation/NavigationStyle.cpp +++ b/src/Gui/Navigation/NavigationStyle.cpp @@ -1024,6 +1024,11 @@ SbVec3f NavigationStyle::getRotationCenter(SbBool& found) const return this->rotationCenter; } +std::optional& NavigationStyle::getRightClickPosition() +{ + return rightClickPosition; +} + void NavigationStyle::setRotationCenter(const SbVec3f& cnt) { this->rotationCenter = cnt; @@ -1964,7 +1969,9 @@ void NavigationStyle::applyNavigationStyleChange(QAction* selectedAction) void NavigationStyle::openPopupMenu(const SbVec2s& position) { - Q_UNUSED(position); + // store the right-click position for potential use by Clarify Selection + rightClickPosition = position; + // ask workbenches and view provider, ... MenuItem view; Gui::Application::Instance->setupContextMenu("View", &view); @@ -2040,6 +2047,7 @@ void NavigationStyle::openPopupMenu(const SbVec2s& position) // handle navigation style change if user selected a navigation style option if (selectedAction && isNavigationStyleAction(selectedAction, navMenuGroup)) { applyNavigationStyleChange(selectedAction); + rightClickPosition.reset(); return; } @@ -2050,6 +2058,8 @@ void NavigationStyle::openPopupMenu(const SbVec2s& position) cmd->invoke(0); // required placeholder value - we don't use group command } } + + rightClickPosition.reset(); } PyObject* NavigationStyle::getPyObject() diff --git a/src/Gui/Navigation/NavigationStyle.h b/src/Gui/Navigation/NavigationStyle.h index ffa907d7e5..4faf708175 100644 --- a/src/Gui/Navigation/NavigationStyle.h +++ b/src/Gui/Navigation/NavigationStyle.h @@ -42,6 +42,7 @@ #include #include #include +#include // forward declarations class SoEvent; @@ -196,6 +197,8 @@ public: SbVec3f getRotationCenter(SbBool&) const; + std::optional& getRightClickPosition(); + PyObject *getPyObject() override; protected: @@ -298,6 +301,10 @@ protected: Py::SmartPtr pythonObject; + // store the position where right-click occurred just before + // the menu popped up + std::optional rightClickPosition; + private: friend class NavigationAnimator; diff --git a/src/Gui/Selection/SelectionView.cpp b/src/Gui/Selection/SelectionView.cpp index ddfedad372..93a5f1f986 100644 --- a/src/Gui/Selection/SelectionView.cpp +++ b/src/Gui/Selection/SelectionView.cpp @@ -728,7 +728,7 @@ struct SubMenuInfo { std::map> items; }; -PickData SelectionMenu::doPick(const std::vector &sels) +PickData SelectionMenu::doPick(const std::vector &sels, const QPoint& pos) { clear(); Gui::Selection().setClarifySelectionActive(true); @@ -739,7 +739,7 @@ PickData SelectionMenu::doPick(const std::vector &sels) processSelections(currentSelections, menus); buildMenuStructure(menus, currentSelections); - QAction* picked = this->exec(QCursor::pos()); + QAction* picked = this->exec(pos); return onPicked(picked, currentSelections); } diff --git a/src/Gui/Selection/SelectionView.h b/src/Gui/Selection/SelectionView.h index dfd365bb70..f051c14ebd 100644 --- a/src/Gui/Selection/SelectionView.h +++ b/src/Gui/Selection/SelectionView.h @@ -140,11 +140,12 @@ public: /** Populate and show the menu for picking geometry elements. * * @param sels: a list of geometry element references + * @param pos: optional position to show the menu (defaults to current cursor position) * @return Return the picked geometry reference * * The menu will be divided into submenus that are grouped by element type. */ - PickData doPick(const std::vector &sels); + PickData doPick(const std::vector &sels, const QPoint& pos = QCursor::pos()); public Q_SLOTS: void onHover(QAction *);