Details
-
Bug
-
Resolution: Done
-
Not Evaluated
-
None
-
5.11.2
-
None
-
XCode 10
Description
QMacNativeWidget (whose goal is to embed Qt widgets into a native NSView) always return a null position, no matter where the parent NSView is moved.
The consequence of that is that any Qt menu pop at a wrong position, since it ultimately takes that null position as an absolute reference.
My understanding is that Qt's global coordinate conversion can only go up to the root Qt parent, which in this case is the QMacNativeWidget relatively set at 0,0 of its parent NSView, so it does not take into account the position inherited from the parent NSView when calculating the global coordinate.
You can retrieve that absolute position of QMacNativeWidget with the following code:
NSView *nativeWidgetView = reinterpret_cast<NSView *>(nativeWidget->winId()); NSRect nativeRect = [nativeWidgetView.window convertRectToScreen:nativeWidgetView.frame];
Attached is a very minimal repro project, and a screenshot of it.
Is there any workaround for that problem ? Almost all the menus in my applications are affected, including non-native QMenuBars and QToolButton with menus. The only popup menus that aren't affected are those popping at the absolute mouse position during a right click, since it does not rely on widgets position.
Here's a minimal source code to repro, which is a slightly modified version of the example shown in the documentation of QMacNativeWidget:
#include <QtWidgets> #include <QMacNativeWidget> #import <ApplicationServices/ApplicationServices.h> #import "Cocoa/Cocoa.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSWindow *window = [[NSWindow alloc] initWithContentRect:NSMakeRect(200, 600, 200, 200) styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask backing:NSBackingStoreBuffered defer:NO]; QMacNativeWidget *nativeWidget = new QMacNativeWidget(); nativeWidget->move(0, 0); nativeWidget->resize(200,200); nativeWidget->setPalette(QPalette(Qt::red)); nativeWidget->setAutoFillBackground(true); QVBoxLayout *layout = new QVBoxLayout(); QToolButton *menuButton = new QToolButton; menuButton->setText("Menu Button"); QMenu *menu=new QMenu("Test Menu"); menu->addAction("Action1"); menu->addAction("Action2"); menuButton->setMenu(menu); layout->addWidget(menuButton); nativeWidget->setLayout(layout); // Adjust Cocoa layouts NSView *nativeWidgetView = reinterpret_cast<NSView *>(nativeWidget->winId()); NSView *contentView = [window contentView]; [contentView setAutoresizesSubviews:YES]; [nativeWidgetView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [nativeWidgetView setAutoresizesSubviews:YES]; // Add the nativeWidget to the window. [contentView addSubview:nativeWidgetView positioned:NSWindowAbove relativeTo:nil]; nativeWidget->show(); menuButton->show(); // Show the window. [window makeKeyAndOrderFront:window]; [pool release]; return app.exec(); }