From a2d58025b63d43a843bf14138221086f25c280f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?=
 <morten.sorvig@theqtcompany.com>
Date: Thu, 10 Mar 2016 12:50:52 +0100
Subject: [PATCH] Cocoa: Improve native view lifetime accuracy.

Ideally all native NSWindows and NSViews owned by
QCocoaWindow should be deallocated during the QCocoaWindow
destructor. In reality this does not always happen
since Cocoa is free to hold references to the views
after Qt releases its reference.

We can help Cocoa clean up:

- Clear the first responder for the NSWindow under
  the ~QCocoaWndow() autoreleasepool.

- Use an autoreleasepool to clean up temp objects
  from [NSWindow orderFront:] immediately.

Together this makes the QNSView lifetime be contained
by the QCocoaWindow lifetime, at least for simple
QWindow usage. It also fixes the observed memory leak
reported in QTBUG-51766

Change-Id: Idd224f54ebd6f61f274461a204ff30c666b22768
Task-number: QTBUG-51766
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@theqtcompany.com>
---
 src/plugins/platforms/cocoa/qcocoawindow.mm | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 00cb43c9405..e4cd57a115d 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -409,6 +409,7 @@ QCocoaWindow::~QCocoaWindow()
 #endif
 
     QMacAutoReleasePool pool;
+    [m_nsWindow makeFirstResponder:nil];
     [m_nsWindow setContentView:nil];
     [m_nsWindow.helper detachFromPlatformWindow];
     if (m_isNSWindowChild) {
@@ -990,7 +991,15 @@ void QCocoaWindow::raise()
             [parentNSWindow removeChildWindow:m_nsWindow];
             [parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
         } else {
-            [m_nsWindow orderFront: m_nsWindow];
+            {
+                // Clean up autoreleased temp objects from orderFront immediately.
+                // Failure to do so has been observed to cause leaks also beyond any outer
+                // autorelease pool (for example around a complete QWindow
+                // construct-show-raise-hide-delete cyle), counter to expected autoreleasepool
+                // behavior.
+                QMacAutoReleasePool pool;
+                [m_nsWindow orderFront: m_nsWindow];
+            }
             static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS");
             if (raiseProcess) {
                 ProcessSerialNumber psn;
-- 
GitLab