diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index e60ca196acdb4ee9f086b5863a70de6c6008019b..9fcb221d374ee1bab49cb358bf2e1888e9096664 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -38,6 +38,7 @@
 
 #include <qpa/qplatformwindow.h>
 #include <QRect>
+#include <QPointer>
 
 #ifndef QT_NO_OPENGL
 #include "qcocoaglcontext.h"
@@ -47,6 +48,32 @@
 
 QT_FORWARD_DECLARE_CLASS(QCocoaWindow)
 
+QT_BEGIN_NAMESPACE
+
+class QCocoaWindowPointer
+{
+public:
+    void assign(QCocoaWindow *w);
+    void clear();
+
+    QCocoaWindow *data() const
+    { return watcher.isNull() ? Q_NULLPTR : window; }
+    bool isNull() const
+    { return watcher.isNull(); }
+    operator QCocoaWindow*() const
+    { return data(); }
+    QCocoaWindow *operator->() const
+    { return data(); }
+    QCocoaWindow &operator*() const
+    { return *data(); }
+
+private:
+    QPointer<QObject> watcher;
+    QCocoaWindow *window;
+};
+
+QT_END_NAMESPACE
+
 @class QT_MANGLE_NAMESPACE(QNSWindowHelper);
 
 @protocol QNSWindowProtocol
@@ -63,14 +90,13 @@ typedef NSWindow<QNSWindowProtocol> QCocoaNSWindow;
 @interface QT_MANGLE_NAMESPACE(QNSWindowHelper) : NSObject
 {
     QCocoaNSWindow *_window;
-    QCocoaWindow *_platformWindow;
+    QCocoaWindowPointer _platformWindow;
     BOOL _grabbingMouse;
     BOOL _releaseOnMouseUp;
-    QPointer<QObject> _watcher;
 }
 
 @property (nonatomic, readonly) QCocoaNSWindow *window;
-@property (nonatomic, readonly) QCocoaWindow *platformWindow;
+@property (nonatomic, readonly) QCocoaWindowPointer platformWindow;
 @property (nonatomic) BOOL grabbingMouse;
 @property (nonatomic) BOOL releaseOnMouseUp;
 
@@ -254,7 +280,7 @@ public: // for QNSView
     NSView *m_contentView;
     QNSView *m_qtView;
     QCocoaNSWindow *m_nsWindow;
-    QCocoaWindow *m_forwardWindow;
+    QCocoaWindowPointer m_forwardWindow;
 
     // TODO merge to one variable if possible
     bool m_contentViewIsEmbedded; // true if the m_contentView is actually embedded in a "foreign" NSView hiearchy
@@ -317,9 +343,8 @@ public: // for QNSView
     QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
     QHash<quintptr, bool> m_enabledContentBorderAreas; // identifer -> enabled state (true/false)
 
-    // This object is tracked by a 'watcher'
-    // object in a window helper, preventing use of dangling
-    // pointers.
+    // This object is tracked by QCocoaWindowPointer,
+    // preventing the use of dangling pointers.
     QObject sentinel;
 };
 
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 12e85c52054f2f804219b0b03b1141e46a22a544..dd67946a272dd1176d9bb269eb5012b9e4fc266f 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -85,7 +85,7 @@ static bool isMouseEvent(NSEvent *ev)
     self = [super init];
     if (self) {
         _window = window;
-        _platformWindow = platformWindow;
+        _platformWindow.assign(platformWindow);
 
         _window.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:_platformWindow];
 
@@ -94,7 +94,6 @@ static bool isMouseEvent(NSEvent *ev)
         // make sure that m_nsWindow stays valid until the
         // QCocoaWindow is deleted by Qt.
         [_window setReleasedWhenClosed:NO];
-        _watcher = &_platformWindow->sentinel;
     }
 
     return self;
@@ -103,19 +102,19 @@ static bool isMouseEvent(NSEvent *ev)
 - (void)handleWindowEvent:(NSEvent *)theEvent
 {
     QCocoaWindow *pw = self.platformWindow;
-    if (_watcher && pw && pw->m_forwardWindow) {
+    if (pw && pw->m_forwardWindow) {
         if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) {
             QNSView *forwardView = pw->m_qtView;
             if (theEvent.type == NSLeftMouseUp) {
                 [forwardView mouseUp:theEvent];
-                pw->m_forwardWindow = 0;
+                pw->m_forwardWindow.clear();
             } else {
                 [forwardView mouseDragged:theEvent];
             }
         }
 
         if (!pw->m_isNSWindowChild && theEvent.type == NSLeftMouseDown) {
-            pw->m_forwardWindow = 0;
+            pw->m_forwardWindow.clear();
         }
     }
 
@@ -142,7 +141,7 @@ static bool isMouseEvent(NSEvent *ev)
     if (!self.window.delegate)
         return; // Already detached, pending NSAppKitDefined event
 
-    if (_watcher && pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
+    if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
         NSPoint loc = [theEvent locationInWindow];
         NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]];
         NSRect contentFrame = [[self.window contentView] frame];
@@ -157,8 +156,7 @@ static bool isMouseEvent(NSEvent *ev)
 
 - (void)detachFromPlatformWindow
 {
-    _platformWindow = 0;
-    _watcher.clear();
+    self.platformWindow.clear();
     [self.window.delegate release];
     self.window.delegate = nil;
 }
@@ -179,7 +177,7 @@ static bool isMouseEvent(NSEvent *ev)
 - (void)dealloc
 {
     _window = nil;
-    _platformWindow = 0;
+    self.platformWindow.clear();
     [super dealloc];
 }
 
@@ -331,6 +329,18 @@ static bool isMouseEvent(NSEvent *ev)
 
 @end
 
+void QCocoaWindowPointer::assign(QCocoaWindow *w)
+{
+    window = w;
+    watcher = &w->sentinel;
+}
+
+void QCocoaWindowPointer::clear()
+{
+    window = Q_NULLPTR;
+    watcher.clear();
+}
+
 const int QCocoaWindow::NoAlertRequest = -1;
 
 QCocoaWindow::QCocoaWindow(QWindow *tlw)
@@ -338,7 +348,6 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
     , m_contentView(nil)
     , m_qtView(nil)
     , m_nsWindow(0)
-    , m_forwardWindow(0)
     , m_contentViewIsEmbedded(false)
     , m_contentViewIsToBeEmbedded(false)
     , m_parentCocoaWindow(0)
@@ -1320,7 +1329,7 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
         if (oldParentCocoaWindow) {
             if (!m_isNSWindowChild || oldParentCocoaWindow != m_parentCocoaWindow)
                 oldParentCocoaWindow->removeChildWindow(this);
-            m_forwardWindow = oldParentCocoaWindow;
+            m_forwardWindow.assign(oldParentCocoaWindow);
         }
 
         setNSWindow(m_nsWindow);
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 34c37d8aed0aba6bacd291ce9b2147b1b8cec973..0d58faa5bf03efe072c62bd610a6df18434ab4cc 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -741,7 +741,7 @@ QT_WARNING_POP
         if (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp)
             targetView = m_platformWindow->m_forwardWindow->m_qtView;
         else
-            m_platformWindow->m_forwardWindow = 0;
+            m_platformWindow->m_forwardWindow.clear();
     }
 
     // Popups implicitly grap mouse events; forward to the active popup if there is one