Skip to content

Commit 0670c55

Browse files
Benjamin Délèzeomichel
andauthored
Fix right click macos (cyberbotics#6251)
* get qmenu * create with parent * working solution * cleanup * clang format * Update src/webots/gui/WbView3D.cpp Co-authored-by: Olivier Michel <Olivier.Michel@cyberbotics.com> * Update WbSimulationView.cpp * style * clang * style * clang format --------- Co-authored-by: Olivier Michel <Olivier.Michel@cyberbotics.com>
1 parent a852ffb commit 0670c55

7 files changed

Lines changed: 49 additions & 41 deletions

File tree

src/webots/gui/WbSimulationView.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ void WbSimulationView::showEvent(QShowEvent *event) {
11451145
updateToggleView3DAction(mSplitterStatus & VIEW_3D_VISIBLE);
11461146
}
11471147

1148-
void WbSimulationView::showMenu(const QPoint &position) {
1148+
void WbSimulationView::showMenu(const QPoint &position, QWidget *parentWidget) {
11491149
const WbBaseNode *selectedNode = WbSelection::instance() ? WbSelection::instance()->selectedNode() : NULL;
1150-
WbContextMenuGenerator::generateContextMenu(position, selectedNode);
1150+
WbContextMenuGenerator::generateContextMenu(position, selectedNode, parentWidget);
11511151
}

src/webots/gui/WbSimulationView.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ protected slots:
106106
void keyPressEvent(QKeyEvent *event) override;
107107
void hideEvent(QHideEvent *event) override;
108108
void showEvent(QShowEvent *event) override;
109-
void showMenu(const QPoint &position);
109+
void showMenu(const QPoint &position, QWidget *parentWidget);
110110

111111
private slots:
112112
void makeMovie();

src/webots/gui/WbView3D.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "WbCapsule.hpp"
2323
#include "WbCone.hpp"
2424
#include "WbContactPointsRepresentation.hpp"
25+
#include "WbContextMenuGenerator.hpp"
2526
#include "WbCylinder.hpp"
2627
#include "WbDragOverlayEvent.hpp"
2728
#include "WbDragPoseEvent.hpp"
@@ -80,6 +81,7 @@
8081
#include <QtGui/QMouseEvent>
8182
#include <QtGui/QScreen>
8283
#include <QtWidgets/QApplication>
84+
#include <QtWidgets/QMenu>
8385

8486
#include <wren/camera.h>
8587
#include <wren/config.h>
@@ -1512,7 +1514,7 @@ void WbView3D::selectNode(const QMouseEvent *event) {
15121514
if (mIsRemoteMouseEvent || mDisabledUserInteractionsMap.value(WbAction::DISABLE_3D_VIEW_CONTEXT_MENU, false))
15131515
mRemoteContextMenuMatter = mPickedMatter;
15141516
else
1515-
emit contextMenuRequested(event->globalPosition().toPoint());
1517+
emit contextMenuRequested(event->globalPosition().toPoint(), mParentWidget);
15161518
}
15171519
return;
15181520
}
@@ -1554,7 +1556,7 @@ void WbView3D::selectNode(const QMouseEvent *event) {
15541556
if (mIsRemoteMouseEvent || mDisabledUserInteractionsMap.value(WbAction::DISABLE_3D_VIEW_CONTEXT_MENU, false))
15551557
mRemoteContextMenuMatter = selectedMatter;
15561558
else
1557-
emit contextMenuRequested(event->globalPosition().toPoint());
1559+
emit contextMenuRequested(event->globalPosition().toPoint(), mParentWidget);
15581560
}
15591561
}
15601562

@@ -1567,6 +1569,11 @@ void WbView3D::mousePressEvent(QMouseEvent *event) {
15671569
mDragVerticalAxisRotate)
15681570
return;
15691571

1572+
#ifdef __APPLE__
1573+
// Fix an issue on macOS where the context menu was not closed by a click.
1574+
delete mParentWidget->findChild<QMenu *>("ContextMenu");
1575+
#endif
1576+
15701577
mMouseEventInitialized = true;
15711578
updateMousesPosition(true, false);
15721579

src/webots/gui/WbView3D.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ protected slots:
120120
void mouseDoubleClicked(QMouseEvent *event);
121121
void screenshotReady();
122122
void applicationActionsUpdateRequested();
123-
void contextMenuRequested(const QPoint &pos);
123+
void contextMenuRequested(const QPoint &pos, QWidget *parentWidget);
124124

125125
private:
126126
QWidget *mParentWidget;

src/webots/scene_tree/WbTreeView.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ void WbTreeView::showMenu(const QPoint &position) {
126126
return;
127127
const WbTreeItem *item = static_cast<WbTreeItem *>(indexes.at(0).internalPointer());
128128
assert(item);
129-
WbContextMenuGenerator::generateContextMenu(mapToGlobal(position), item->node());
129+
WbContextMenuGenerator::generateContextMenu(mapToGlobal(position), item->node(), NULL);
130130
}
131131

132132
void WbTreeView::scrollToModelIndex(const QModelIndex &index) {

src/webots/user_commands/WbContextMenuGenerator.cpp

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -77,62 +77,62 @@ namespace WbContextMenuGenerator {
7777
return suitableModels;
7878
}
7979

80-
void generateContextMenu(const QPoint &position, const WbNode *selectedNode) {
81-
QMenu contextMenu;
82-
contextMenu.setObjectName("ContextMenu");
83-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::CUT));
84-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::COPY));
85-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::PASTE));
86-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::RESET_VALUE));
87-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::EDIT_FIELD));
88-
contextMenu.addSeparator();
89-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::ADD_NEW));
90-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::DEL));
91-
contextMenu.addSeparator();
92-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::MOVE_VIEWPOINT_TO_OBJECT));
93-
QMenu *viewMenu = contextMenu.addMenu(QObject::tr("Ali&gn View to Object"));
80+
void generateContextMenu(const QPoint &position, const WbNode *selectedNode, QWidget *parentWidget) {
81+
QMenu *contextMenu = new QMenu(parentWidget);
82+
contextMenu->setObjectName("ContextMenu");
83+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::CUT));
84+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::COPY));
85+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::PASTE));
86+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::RESET_VALUE));
87+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::EDIT_FIELD));
88+
contextMenu->addSeparator();
89+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::ADD_NEW));
90+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::DEL));
91+
contextMenu->addSeparator();
92+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::MOVE_VIEWPOINT_TO_OBJECT));
93+
QMenu *viewMenu = contextMenu->addMenu(QObject::tr("Ali&gn View to Object"));
9494
viewMenu->addAction(WbActionManager::instance()->action(WbAction::OBJECT_FRONT_VIEW));
9595
viewMenu->addAction(WbActionManager::instance()->action(WbAction::OBJECT_BACK_VIEW));
9696
viewMenu->addAction(WbActionManager::instance()->action(WbAction::OBJECT_LEFT_VIEW));
9797
viewMenu->addAction(WbActionManager::instance()->action(WbAction::OBJECT_RIGHT_VIEW));
9898
viewMenu->addAction(WbActionManager::instance()->action(WbAction::OBJECT_TOP_VIEW));
9999
viewMenu->addAction(WbActionManager::instance()->action(WbAction::OBJECT_BOTTOM_VIEW));
100-
contextMenu.addSeparator();
100+
contextMenu->addSeparator();
101101

102102
// selection-dependent actions
103103
if (selectedNode) {
104104
// actions for robots
105105
if (gAreRobotActionsEnabled) {
106-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::EDIT_CONTROLLER));
107-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::SHOW_ROBOT_WINDOW));
108-
QMenu *subMenu = contextMenu.addMenu(QObject::tr("Overlays"));
106+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::EDIT_CONTROLLER));
107+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::SHOW_ROBOT_WINDOW));
108+
QMenu *subMenu = contextMenu->addMenu(QObject::tr("Overlays"));
109109
subMenu->addMenu(gRobotCameraMenu);
110110
subMenu->addMenu(gRobotRangeFinderMenu);
111111
subMenu->addMenu(gRobotDisplayMenu);
112-
contextMenu.addSeparator();
112+
contextMenu->addSeparator();
113113
}
114114

115115
// actions for nodes in general
116116
if (gAreNodeActionsEnabled) {
117-
QMenu *subMenu = contextMenu.addMenu(QObject::tr("Follow Object"));
117+
QMenu *subMenu = contextMenu->addMenu(QObject::tr("Follow Object"));
118118
subMenu->addAction(WbActionManager::instance()->action(WbAction::FOLLOW_NONE));
119119
subMenu->addAction(WbActionManager::instance()->action(WbAction::FOLLOW_TRACKING));
120120
subMenu->addAction(WbActionManager::instance()->action(WbAction::FOLLOW_MOUNTED));
121121
subMenu->addAction(WbActionManager::instance()->action(WbAction::FOLLOW_PAN_AND_TILT));
122122

123-
subMenu = contextMenu.addMenu(QObject::tr("Optional Rendering"));
123+
subMenu = contextMenu->addMenu(QObject::tr("Optional Rendering"));
124124
subMenu->addAction(WbActionManager::instance()->action(WbAction::CENTER_OF_MASS));
125125
subMenu->addAction(WbActionManager::instance()->action(WbAction::CENTER_OF_BUOYANCY));
126126
subMenu->addAction(WbActionManager::instance()->action(WbAction::SUPPORT_POLYGON));
127127

128-
contextMenu.addSeparator();
128+
contextMenu->addSeparator();
129129

130130
const WbBaseNode *selectedBaseNode = static_cast<const WbBaseNode *>(selectedNode);
131131
if (selectedBaseNode->nodeType() == WB_NODE_ROBOT)
132-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::EXPORT_URDF));
132+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::EXPORT_URDF));
133133

134134
if (!gAreProtoActionsEnabled) {
135-
subMenu = contextMenu.addMenu(QObject::tr("Transform To..."));
135+
subMenu = contextMenu->addMenu(QObject::tr("Transform To..."));
136136
const QStringList suitableTransformToModels = fillTransformToItems(selectedNode);
137137

138138
if (!suitableTransformToModels.isEmpty()) {
@@ -149,27 +149,27 @@ namespace WbContextMenuGenerator {
149149
// actions for PROTO nodes
150150
if (gAreProtoActionsEnabled) {
151151
QAction *editProtoAction(WbActionManager::instance()->action(WbAction::EDIT_PROTO_SOURCE));
152-
contextMenu.addAction(editProtoAction);
152+
contextMenu->addAction(editProtoAction);
153153
if (gAreExternProtoActionsEnabled) {
154154
editProtoAction->setStatusTip(QObject::tr("Copy and edit the PROTO file in Text Editor."));
155-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::SHOW_PROTO_SOURCE));
155+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::SHOW_PROTO_SOURCE));
156156
} else
157157
editProtoAction->setStatusTip(QObject::tr("Edit the PROTO file in Text Editor."));
158158
editProtoAction->setToolTip(editProtoAction->statusTip());
159159

160160
if (selectedNode->isTemplate())
161-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::SHOW_PROTO_RESULT));
161+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::SHOW_PROTO_RESULT));
162162

163-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::CONVERT_TO_BASE_NODES));
164-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::CONVERT_ROOT_TO_BASE_NODES));
163+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::CONVERT_TO_BASE_NODES));
164+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::CONVERT_ROOT_TO_BASE_NODES));
165165
}
166-
contextMenu.addSeparator();
166+
contextMenu->addSeparator();
167167
}
168-
contextMenu.addAction(WbActionManager::instance()->action(WbAction::OPEN_HELP));
168+
contextMenu->addAction(WbActionManager::instance()->action(WbAction::OPEN_HELP));
169169

170170
QObject *focusObject = WbActionManager::instance()->focusObject();
171-
WbActionManager::instance()->setFocusObject(&contextMenu);
172-
contextMenu.exec(position);
171+
WbActionManager::instance()->setFocusObject(contextMenu);
172+
contextMenu->exec(position);
173173
WbActionManager::instance()->setFocusObject(focusObject);
174174
}
175175
} // namespace WbContextMenuGenerator

src/webots/user_commands/WbContextMenuGenerator.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@
2222
#include <QtCore/QPoint>
2323

2424
class QMenu;
25+
class QWidget;
2526
class WbNode;
2627

2728
namespace WbContextMenuGenerator {
28-
void generateContextMenu(const QPoint &position, const WbNode *selectedNode);
29+
void generateContextMenu(const QPoint &position, const WbNode *selectedNode, QWidget *parentWidget);
2930
void enableNodeActions(bool enabled);
3031
void enableProtoActions(bool enabled);
3132
void enableExternProtoActions(bool enabled);

0 commit comments

Comments
 (0)