summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2016-10-05 21:56:58 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2016-10-10 16:06:41 +0000
commitf835b5aa9cba2665423e6e96a45d97c3c80296a5 (patch)
tree32f35432d9046302b799cb55a067195059e40580 /src/plugins/platforms/cocoa
parent1df4b2a3609d977cc8123f1f82e454d0333287d4 (diff)
macOS: Get rid of m_qtView member in QCocoaWindow that aliased m_view
The member was mirroring m_view in all cases except for foreign windows. Instead of a member we now check window()->type() != Qt::ForeignWindow, which is more explicit, especially for people not normally working on the macOS platform. To call methods that are only implemented for our QNSView subclass, a new qnsview_cast() function has been introduced. Change-Id: I0a2cfe1a5e4502250c17e1c3ebdce19e9ee5e572 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm25
-rw-r--r--src/plugins/platforms/cocoa/qcocoainputcontext.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm61
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm4
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm7
9 files changed, 65 insertions, 49 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 5bad5973c4..9c410506b0 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -237,7 +237,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
if (QWindow *window = iface->window()) {
QCocoaWindow *win = static_cast<QCocoaWindow*>(window->handle());
- return win->qtView();
+ return qnsview_cast(win->view());
}
QAccessibleInterface *parent = iface->parent();
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index af5418315c..a74995319b 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -40,6 +40,7 @@
#include "qcocoabackingstore.h"
#include "qcocoawindow.h"
+#include "qcocoahelpers.h"
QT_BEGIN_NAMESPACE
@@ -51,7 +52,7 @@ QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
QCocoaBackingStore::~QCocoaBackingStore()
{
if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle()))
- [cocoaWindow->m_qtView clearBackingStore:this];
+ [qnsview_cast(cocoaWindow->view()) clearBackingStore:this];
}
QImage::Format QCocoaBackingStore::format() const
@@ -68,7 +69,7 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion &region, const QPo
return;
if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle()))
- [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset];
+ [qnsview_cast(cocoaWindow->view()) flushBackingStore:this region:region offset:offset];
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index 536a2d2d58..1b038a6b5e 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -55,6 +55,8 @@
#include <QtGui/qpalette.h>
#include <QtGui/qscreen.h>
+Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSView));
+
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaCocoaWindow)
@@ -74,6 +76,8 @@ NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions);
Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions);
Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions);
+QT_MANGLE_NAMESPACE(QNSView) *qnsview_cast(NSView *view);
+
// Misc
void qt_mac_transformProccessToForegroundApplication();
QString qt_mac_applicationName();
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 1dee11678e..c57567bdd6 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -40,7 +40,7 @@
#include <qpa/qplatformtheme.h>
#include "qcocoahelpers.h"
-
+#include "qnsview.h"
#include <QtCore>
#include <QtGui>
@@ -143,7 +143,30 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
return actions;
}
+/*!
+ Returns the view cast to a QNSview if possible.
+
+ If the view is not a QNSView, nil is returned, which is safe to
+ send messages to, effectivly making [qnsview_cast(view) message]
+ a no-op.
+ For extra verbosity and clearer code, please consider checking
+ that window()->type() != Qt::ForeignWindow before using this cast.
+
+ Do not use this method soley to check for foreign windows, as
+ that will make the code harder to read for people not working
+ primarily on macOS, who do not know the difference between the
+ NSView and QNSView cases.
+*/
+QNSView *qnsview_cast(NSView *view)
+{
+ if (![view isKindOfClass:[QNSView class]]) {
+ qCWarning(lcQpaCocoaWindow) << "NSView is not QNSView, consider checking for Qt::ForeignWindow";
+ return nil;
+ }
+
+ return static_cast<QNSView *>(view);
+}
//
// Misc
diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
index ae060d5e2d..9e3d747cd7 100644
--- a/src/plugins/platforms/cocoa/qcocoainputcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
@@ -41,6 +41,7 @@
#include "qcocoainputcontext.h"
#include "qcocoanativeinterface.h"
#include "qcocoawindow.h"
+#include "qcocoahelpers.h"
#include <Carbon/Carbon.h>
@@ -102,7 +103,8 @@ void QCocoaInputContext::reset()
if (!mWindow)
return;
- QNSView *view = static_cast<QCocoaWindow *>(mWindow->handle())->qtView();
+ QCocoaWindow *window = static_cast<QCocoaWindow *>(mWindow->handle());
+ QNSView *view = qnsview_cast(window->view());
if (!view)
return;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 11bd6b5cb9..bd7b23bc1b 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -183,7 +183,6 @@ public:
void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE;
NSView *view() const;
- QNSView *qtView() const;
NSWindow *nativeWindow() const;
void setEmbeddedInForeignView(bool subwindow);
@@ -260,7 +259,6 @@ public: // for QNSView
void removeMonitor();
NSView *m_view;
- QNSView *m_qtView;
QCocoaNSWindow *m_nsWindow;
QPointer<QCocoaWindow> m_forwardWindow;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index b5503be1a7..c75090f0c2 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -122,7 +122,7 @@ static void qt_closePopups()
QCocoaWindow *pw = self.platformWindow;
if (pw && pw->m_forwardWindow) {
if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) {
- QNSView *forwardView = pw->m_qtView;
+ QNSView *forwardView = qnsview_cast(pw->view());
if (theEvent.type == NSLeftMouseUp) {
[forwardView mouseUp:theEvent];
pw->m_forwardWindow.clear();
@@ -163,12 +163,8 @@ static void qt_closePopups()
NSPoint loc = [theEvent locationInWindow];
NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]];
NSRect contentFrame = [[self.window contentView] frame];
- if (NSMouseInRect(loc, windowFrame, NO) &&
- !NSMouseInRect(loc, contentFrame, NO))
- {
- QNSView *contentView = pw->m_qtView;
- [contentView handleFrameStrutMouseEvent: theEvent];
- }
+ if (NSMouseInRect(loc, windowFrame, NO) && !NSMouseInRect(loc, contentFrame, NO))
+ [qnsview_cast(pw->view()) handleFrameStrutMouseEvent:theEvent];
}
}
@@ -352,7 +348,6 @@ const int QCocoaWindow::NoAlertRequest = -1;
QCocoaWindow::QCocoaWindow(QWindow *tlw)
: QPlatformWindow(tlw)
, m_view(nil)
- , m_qtView(nil)
, m_nsWindow(0)
, m_viewIsEmbedded(false)
, m_viewIsToBeEmbedded(false)
@@ -393,8 +388,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
if (tlw->type() == Qt::ForeignWindow) {
m_view = (NSView *)WId(tlw->property("_q_foreignWinId").value<WId>());
} else {
- m_qtView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this];
- m_view = m_qtView;
+ m_view = [[QNSView alloc] initWithQWindow:tlw platformWindow:this];
// Enable high-dpi OpenGL for retina displays. Enabling has the side
// effect that Cocoa will start calling glViewport(0, 0, width, height),
// overriding any glViewport calls in application code. This is usually not a
@@ -436,17 +430,15 @@ QCocoaWindow::~QCocoaWindow()
// Make sure to disconnect observer in all case if view is valid
// to avoid notifications received when deleting when using Qt::AA_NativeWindows attribute
- if (m_qtView) {
- [[NSNotificationCenter defaultCenter] removeObserver:m_qtView];
- }
+ if (window()->type() != Qt::ForeignWindow)
+ [[NSNotificationCenter defaultCenter] removeObserver:m_view];
// The QNSView object may outlive the corresponding QCocoaWindow object,
// for example during app shutdown when the QNSView is embedded in a
// foregin NSView hiearchy. Clear the pointers to the QWindow/QCocoaWindow
// here to make sure QNSView does not dereference stale pointers.
- if (m_qtView) {
- [m_qtView clearQWindowPointers];
- }
+ if (window()->type() != Qt::ForeignWindow)
+ [qnsview_cast(m_view) clearQWindowPointers];
// While it is unlikely that this window will be in the popup stack
// during deletetion we clear any pointers here to make sure.
@@ -518,8 +510,8 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
QMacAutoReleasePool pool;
if (m_viewIsEmbedded) {
- if (m_qtView) {
- [m_qtView setFrame:NSMakeRect(0, 0, rect.width(), rect.height())];
+ if (window()->type() != Qt::ForeignWindow) {
+ [m_view setFrame:NSMakeRect(0, 0, rect.width(), rect.height())];
} else {
QPlatformWindow::setGeometry(rect);
}
@@ -542,7 +534,7 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
[m_view setFrame:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
}
- if (!m_qtView)
+ if (window()->type() == Qt::ForeignWindow)
QPlatformWindow::setGeometry(rect);
// will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm)
@@ -1071,9 +1063,9 @@ bool QCocoaWindow::isOpaque() const
// When ordering below the window must be tranclucent.
static GLint openglSourfaceOrder = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER");
- bool translucent = (window()->format().alphaBufferSize() > 0
+ bool translucent = window()->format().alphaBufferSize() > 0
|| window()->opacity() < 1
- || (m_qtView && [m_qtView hasMask]))
+ || [qnsview_cast(m_view) hasMask]
|| (surface()->supportsOpenGL() && openglSourfaceOrder == -1);
return !translucent;
}
@@ -1132,8 +1124,8 @@ void QCocoaWindow::setMask(const QRegion &region)
if (m_nsWindow)
[m_nsWindow setBackgroundColor:[NSColor clearColor]];
- [m_qtView setMaskRegion:&region];
- [m_nsWindow setOpaque: isOpaque()];
+ [qnsview_cast(m_view) setMaskRegion:&region];
+ [m_nsWindow setOpaque:isOpaque()];
}
bool QCocoaWindow::setKeyboardGrabEnabled(bool grab)
@@ -1182,11 +1174,6 @@ NSView *QCocoaWindow::view() const
return m_view;
}
-QNSView *QCocoaWindow::qtView() const
-{
- return m_qtView;
-}
-
NSWindow *QCocoaWindow::nativeWindow() const
{
return m_nsWindow;
@@ -1211,7 +1198,7 @@ void QCocoaWindow::windowDidMove()
if (m_isNSWindowChild)
return;
- [m_qtView updateGeometry];
+ [qnsview_cast(m_view) updateGeometry];
}
void QCocoaWindow::windowDidResize()
@@ -1223,14 +1210,14 @@ void QCocoaWindow::windowDidResize()
return;
clipChildWindows();
- [m_qtView updateGeometry];
+ [qnsview_cast(m_view) updateGeometry];
}
void QCocoaWindow::windowDidEndLiveResize()
{
if (m_synchedWindowState == Qt::WindowMaximized && ![m_nsWindow isZoomed]) {
m_effectivelyMaximized = false;
- [m_qtView notifyWindowStateChanged:Qt::WindowNoState];
+ [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowNoState];
}
}
@@ -1306,8 +1293,8 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
bool usesNSPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
// No child QNSWindow should notify its QNSView
- if (m_nsWindow && m_qtView && m_parentCocoaWindow && !oldParentCocoaWindow)
- [[NSNotificationCenter defaultCenter] removeObserver:m_qtView
+ if (m_nsWindow && (window()->type() != Qt::ForeignWindow) && m_parentCocoaWindow && !oldParentCocoaWindow)
+ [[NSNotificationCenter defaultCenter] removeObserver:m_view
name:nil object:m_nsWindow];
// Remove current window (if any)
@@ -1325,8 +1312,8 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
// Only non-child QNSWindows should notify their QNSViews
// (but don't register more than once).
- if (m_qtView && (noPreviousWindow || (wasNSWindowChild && !m_isNSWindowChild)))
- [[NSNotificationCenter defaultCenter] addObserver:m_qtView
+ if ((window()->type() != Qt::ForeignWindow) && (noPreviousWindow || (wasNSWindowChild && !m_isNSWindowChild)))
+ [[NSNotificationCenter defaultCenter] addObserver:m_view
selector:@selector(windowNotification:)
name:nil // Get all notifications
object:m_nsWindow];
@@ -1673,8 +1660,8 @@ void QCocoaWindow::setWindowCursor(NSCursor *cursor)
// Othervise, set the cursor if this window is under the mouse. In
// this case QNSView::cursorUpdate will set the cursor as the pointer
// moves.
- if (m_nsWindow && m_qtView) {
- [m_nsWindow invalidateCursorRectsForView : m_qtView];
+ if (m_nsWindow && window()->type() != Qt::ForeignWindow) {
+ [m_nsWindow invalidateCursorRectsForView:m_view];
} else {
if (m_windowUnderMouse)
[cursor set];
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 7ac3cafc3c..be2342d51e 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -749,7 +749,7 @@ static bool _q_dontOverrideCtrlLMB = false;
QNSView *targetView = self;
if (m_platformWindow && m_platformWindow->m_forwardWindow) {
if (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp)
- targetView = m_platformWindow->m_forwardWindow->m_qtView;
+ targetView = qnsview_cast(m_platformWindow->m_forwardWindow->view());
else
m_platformWindow->m_forwardWindow.clear();
}
@@ -759,7 +759,7 @@ static bool _q_dontOverrideCtrlLMB = false;
// Tooltips must be transparent for mouse events
// The bug reference is QTBUG-46379
if (!popup->m_windowFlags.testFlag(Qt::ToolTip)) {
- if (QNSView *popupView = popup->qtView())
+ if (QNSView *popupView = qnsview_cast(popup->view()))
targetView = popupView;
}
}
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index b96a9491e8..cbae4fc50f 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qnswindowdelegate.h"
+#include "qcocoahelpers.h"
#include <QDebug>
#include <qpa/qwindowsysteminterface.h>
@@ -60,7 +61,7 @@
if (m_cocoaWindow->m_windowUnderMouse) {
QPointF windowPoint;
QPointF screenPoint;
- [m_cocoaWindow->m_qtView convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ [qnsview_cast(m_cocoaWindow->view()) convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleEnterEvent(m_cocoaWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
}
}
@@ -110,8 +111,8 @@
- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
{
Q_UNUSED(newFrame);
- if (m_cocoaWindow && m_cocoaWindow->m_qtView)
- [m_cocoaWindow->m_qtView notifyWindowWillZoom:![window isZoomed]];
+ if (m_cocoaWindow && m_cocoaWindow->window()->type() != Qt::ForeignWindow)
+ [qnsview_cast(m_cocoaWindow->view()) notifyWindowWillZoom:![window isZoomed]];
return YES;
}