Skip to content

Instantly share code, notes, and snippets.

@torarnv
Created March 3, 2023 11:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save torarnv/7bbd31d9879c390071d5aa0e9a1f2af1 to your computer and use it in GitHub Desktop.
Save torarnv/7bbd31d9879c390071d5aa0e9a1f2af1 to your computer and use it in GitHub Desktop.
diff --git i/src/plugins/platforms/cocoa/qcocoawindow.mm w/src/plugins/platforms/cocoa/qcocoawindow.mm
index cb813114ef8..be2efdae110 100644
--- i/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ w/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -134,16 +134,18 @@ void QCocoaWindow::initialize()
if (!m_view)
m_view = [[QNSView alloc] initWithCocoaWindow:this];
- // Compute the initial geometry based on the geometry set on the
- // QWindow. This geometry has already been reflected to the
- // QPlatformWindow in the constructor, so to ensure that the
- // resulting setGeometry call does not think the geometry has
- // already been applied, we reset the QPlatformWindow's view
- // of the geometry first.
- auto initialGeometry = QPlatformWindow::initialGeometry(window(),
- windowGeometry(), defaultWindowWidth, defaultWindowHeight);
- QPlatformWindow::d_ptr->rect = QRect();
- setGeometry(initialGeometry);
+ if (!isForeignWindow()) {
+ // Compute the initial geometry based on the geometry set on the
+ // QWindow. This geometry has already been reflected to the
+ // QPlatformWindow in the constructor, so to ensure that the
+ // resulting setGeometry call does not think the geometry has
+ // already been applied, we reset the QPlatformWindow's view
+ // of the geometry first.
+ auto initialGeometry = QPlatformWindow::initialGeometry(window(),
+ windowGeometry(), defaultWindowWidth, defaultWindowHeight);
+ QPlatformWindow::d_ptr->rect = QRect();
+ setGeometry(initialGeometry);
+ }
recreateWindowIfNeeded();
@@ -1468,7 +1470,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
const bool shouldBeContentView = !parentWindow
&& !((type & Qt::SubWindow) == Qt::SubWindow)
- && !isEmbeddedView;
+ && !isEmbeddedView && !isForeignWindow();
if (isContentView() != shouldBeContentView)
recreateReason |= ContentViewChanged;
@pmogylevskyi
Copy link

@torarnv , thank you for your job in this. I would like to note that some parts of your fix are in the Qt dev now. Please look at:

https://code.qt.io/cgit/qt/qtbase.git/tree/src/plugins/platforms/cocoa/qcocoawindow.mm#n120

However, the fix in QCocoaWindow::recreateWindowIfNeeded is slightly different in the Qt dev:

https://code.qt.io/cgit/qt/qtbase.git/tree/src/plugins/platforms/cocoa/qcocoawindow.mm#n1444

and your fix works great while with Qt dev one doesn't work at all.

Is there any chance to get your fix merged into Qt repo? Do you have any Qt tickets for it?

@torarnv
Copy link
Author

torarnv commented Apr 6, 2023

Thanks @pmogylevskyi , I'll have a look at while the dev fix doesn't work as expected for this use-case.

@pmogylevskyi
Copy link

Thank you, @torarnv . I just realized that all related fixes in Qt dev are yours :) Thank's great.

So I think it makes sense to describe my problem with the fix in QCocoaWindow::recreateWindowIfNeeded() in Qt dev more in detail. Currently I'm working on the integration UI of Audio Units into the Qt6 application by using QWidget::createWindowContainer. In time of Qt5.15 I used QMacCocoaViewContainer for that and everything worked well. After upgrading to Qt 6.4 I've got a crash somewhere in QCocoaWindow when showing the QDialog with integrated UI of AudioUnit (NSView). During my investigation I found your fixes for JUCE Qt and tried them for my case. No crash anymore but a blank window. After debugging I found that the problem is in CocoaWindow::recreateWindowIfNeeded() fix. I reverted Qt dev fix and applied your one from this patch and the problem is gone. Now I have perfect integration of the UI Audio Unit in my Qt6 app with correct geometry but it would be nice to have the fix on the Qt side as well. Therefore I raised this topic here. What is your suggestion in this case? There are any principal differences in fixes in QCocoaWindow::recreateWindowIfNeeded()  between the current patch and Qt dev?

@torarnv
Copy link
Author

torarnv commented Apr 24, 2023

@pmogylevskyi So you are not writing a plugin, you are writing a host? Where you get an incoming NSView for the plugin you're trying to host, which you embed into a QWidget UI using QWindow::fromWinId() + QWidget::createWindowContainer()? If so, that's a different use-case than the patches I did for JUCExQt. If you have a minimal sample application of this (with just a fake NSView you create), please file a JIRA issue at https://bugreports.qt.io/ so we can diagnose it. Thanks!

@pmogylevskyi
Copy link

@torarnv , thanks for your reply. Yes, I'm writing the host which loads plugins, e.g. third-party Audio Units plug-ins (IK MULTIMEDIA, Waves, etc. ), Apple Audio Units plug-ins. I'm get an incoming NSView from those plugins. It worked well in Qt 5.15.x but broken in Qt 6.4.2. I found a solution which based on your changes here. Unfortunately, I don't have the minimal sample application. I will try to write it and open JIRA ticket. Thanks!

@conradjones
Copy link

@pmogylevskyi are the builtin Apple Audio Units working for you in your app ? I am able to load / view NSView for most third party ones but some of the apples ones crash AUBandPass being the first example.
It is definitely to do with using QWindow::fromWinId() + QWidget::createWindowContainer() if I just do QWindow::fromWinId() and show that window it works fine, as soon as I add QWidget::createWindowContainer() to embed in a widget hierarchy (we need preset selection etc right) it crashes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment