diff options
author | Liang Qi <liang.qi@qt.io> | 2021-11-25 19:58:42 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-12-08 20:26:20 +0000 |
commit | 998af0776002b2c6c4f0ed70ba7e332a8215aa78 (patch) | |
tree | 4fa2b5152f6fa4f8c929699294fce8045e08a5d5 /src/widgets | |
parent | 6036b9c706faf3f94715566e8b3b97c65271bc16 (diff) |
Widgets: setTransientParent() when a QMenu is a window
On some platforms, such as X11 and Wayland with some compositors,
QMenu could be a popup window, which should be set a transient parent
to get relative position, which is requested by Wayland.
Added transientParentWindow() for QMenuPrivate like QDialogPrivate.
Fixes: QTBUG-68636
Change-Id: I6d8880cb008ecf61a4c005898b38e3953379a13d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 493a85a9e468874471057910a61e7c54a45eee83)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/widgets/qmenu.cpp | 25 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu_p.h | 1 |
2 files changed, 26 insertions, 0 deletions
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index ed75d2c701..79fda37032 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -625,6 +625,29 @@ void QMenuPrivate::hideMenu(QMenu *menu) menu->d_func()->causedPopup.widget = nullptr; } +QWindow *QMenuPrivate::transientParentWindow() const +{ + Q_Q(const QMenu); + if (const QWidget *parent = q->nativeParentWidget()) { + if (parent->windowHandle()) + return parent->windowHandle(); + } + + if (const QWindow *w = q->windowHandle()) { + if (w->transientParent()) + return w->transientParent(); + } + + if (causedPopup.widget) { + if (const QWidget *w = causedPopup.widget.data()) { + if (const QWidget *ww = w->window()) + return ww->windowHandle(); + } + } + + return nullptr; +} + void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst) { Q_Q(QMenu); @@ -3060,6 +3083,8 @@ bool QMenu::event(QEvent *e) d->sloppyState.reset(); if (d->currentAction) d->popupAction(d->currentAction, 0, false); + if (isWindow() && window() && window()->windowHandle() && !window()->windowHandle()->transientParent()) + window()->windowHandle()->setTransientParent(d->transientParentWindow()); break; #if QT_CONFIG(tooltip) case QEvent::ToolTip: diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index ffe956d007..bad9c294f8 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -440,6 +440,7 @@ public: QMenuCaused causedPopup; void hideUpToMenuBar(); void hideMenu(QMenu *menu); + QWindow *transientParentWindow() const; //index mappings inline QAction *actionAt(int i) const { return q_func()->actions().at(i); } |