summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm14
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h17
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm105
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h60
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm567
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h7
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm123
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h7
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm58
12 files changed, 553 insertions, 413 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index a74995319b..1d7ad772dc 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -57,7 +57,8 @@ QCocoaBackingStore::~QCocoaBackingStore()
QImage::Format QCocoaBackingStore::format() const
{
- if (static_cast<QCocoaWindow *>(window()->handle())->m_drawContentBorderGradient)
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
+ if (cocoaWindow && cocoaWindow->m_drawContentBorderGradient)
return QImage::Format_ARGB32_Premultiplied;
return QRasterBackingStore::format();
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index 7d11023b78..de4fa95530 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -132,7 +132,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
QPixmap pm = dragPixmap(m_drag, hotSpot);
QSize pmDeviceIndependentSize = pm.size() / pm.devicePixelRatio();
NSImage *nsimage = qt_mac_create_nsimage(pm);
- [nsimage setSize:pmDeviceIndependentSize.toCGSize()];
+ [nsimage setSize:NSSizeFromCGSize(pmDeviceIndependentSize.toCGSize())];
QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND);
m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index ef102990b4..7706f39198 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -62,6 +62,7 @@
#include <stdlib.h>
#include <qabstracteventdispatcher.h>
#include <qsysinfo.h>
+#include <qoperatingsystemversion.h>
#include <qglobal.h>
#include <QDir>
@@ -163,7 +164,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
[mSavePanel setDelegate:self];
#if QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_11)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_11)
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::OSXElCapitan)
mOpenPanel.accessoryViewDisclosed = YES;
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index c57567bdd6..b092d013c5 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -160,10 +160,8 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
*/
QNSView *qnsview_cast(NSView *view)
{
- if (![view isKindOfClass:[QNSView class]]) {
- qCWarning(lcQpaCocoaWindow) << "NSView is not QNSView, consider checking for Qt::ForeignWindow";
+ if (![view isKindOfClass:[QNSView class]])
return nil;
- }
return static_cast<QNSView *>(view);
}
@@ -235,13 +233,13 @@ QString qt_mac_applicationName()
return appName;
}
-int qt_mac_mainScreenHeight()
+int qt_mac_primaryScreenHeight()
{
QMacAutoReleasePool pool;
NSArray *screens = [NSScreen screens];
if ([screens count] > 0) {
- // The first screen in the screens array is documented
- // to have the (0,0) origin.
+ // The first screen in the screens array is documented to
+ // have the (0,0) origin and is designated the primary screen.
NSRect screenFrame = [[screens objectAtIndex: 0] frame];
return screenFrame.size.height;
}
@@ -250,12 +248,12 @@ int qt_mac_mainScreenHeight()
int qt_mac_flipYCoordinate(int y)
{
- return qt_mac_mainScreenHeight() - y;
+ return qt_mac_primaryScreenHeight() - y;
}
qreal qt_mac_flipYCoordinate(qreal y)
{
- return qt_mac_mainScreenHeight() - y;
+ return qt_mac_primaryScreenHeight() - y;
}
QPointF qt_mac_flipPoint(const NSPoint &p)
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 32f6fe0af1..5cf8e7d237 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QCocoaScreen : public QPlatformScreen
{
public:
- QCocoaScreen(int screenIndex);
+ QCocoaScreen(NSScreen *screen);
~QCocoaScreen();
// ----------------------------------------------------
@@ -84,11 +84,20 @@ public:
// ----------------------------------------------------
// Additional methods
void setVirtualSiblings(const QList<QPlatformScreen *> &siblings) { m_siblings = siblings; }
- NSScreen *osScreen() const;
+ NSScreen *nsScreen() const;
void updateGeometry();
+ QPointF mapToNative(const QPointF &pos) const { return flipCoordinate(pos); }
+ QRectF mapToNative(const QRectF &rect) const { return flipCoordinate(rect); }
+ QPointF mapFromNative(const QPointF &pos) const { return flipCoordinate(pos); }
+ QRectF mapFromNative(const QRectF &rect) const { return flipCoordinate(rect); }
+
+private:
+ QPointF flipCoordinate(const QPointF &pos) const;
+ QRectF flipCoordinate(const QRectF &rect) const;
+
public:
- int m_screenIndex;
+ NSScreen *m_nsScreen;
QRect m_geometry;
QRect m_availableGeometry;
QDpi m_logicalDpi;
@@ -144,7 +153,7 @@ public:
QList<int> possibleKeys(const QKeyEvent *event) const Q_DECL_OVERRIDE;
void updateScreens();
- QCocoaScreen *screenAtIndex(int index);
+ QCocoaScreen *screenForNSScreen(NSScreen *nsScreen);
void setToolbar(QWindow *window, NSToolbar *toolbar);
NSToolbar *toolbar(QWindow *window) const;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 92fffb4d15..d48722b82f 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -69,8 +69,8 @@ static void initResources()
QT_BEGIN_NAMESPACE
-QCocoaScreen::QCocoaScreen(int screenIndex) :
- QPlatformScreen(), m_screenIndex(screenIndex), m_refreshRate(60.0)
+QCocoaScreen::QCocoaScreen(NSScreen *screen)
+ : QPlatformScreen(), m_nsScreen(screen), m_refreshRate(60.0)
{
updateGeometry();
m_cursor = new QCocoaCursor;
@@ -81,46 +81,63 @@ QCocoaScreen::~QCocoaScreen()
delete m_cursor;
}
-NSScreen *QCocoaScreen::osScreen() const
+NSScreen *QCocoaScreen::nsScreen() const
{
- NSArray *screens = [NSScreen screens];
- return ((NSUInteger)m_screenIndex < [screens count]) ? [screens objectAtIndex:m_screenIndex] : nil;
+ return m_nsScreen;
+}
+
+/*!
+ Flips the Y coordinate of the point between quadrant I and IV.
+
+ The native coordinate system on macOS uses quadrant I, with origin
+ in bottom left, and Qt uses quadrant IV, with origin in top left.
+
+ By flippig the Y coordinate, we can map the position between the
+ two coordinate systems.
+*/
+QPointF QCocoaScreen::flipCoordinate(const QPointF &pos) const
+{
+ return QPointF(pos.x(), m_geometry.height() - pos.y());
+}
+
+/*!
+ Flips the Y coordinate of the rectangle between quadrant I and IV.
+
+ The native coordinate system on macOS uses quadrant I, with origin
+ in bottom left, and Qt uses quadrant IV, with origin in top left.
+
+ By flippig the Y coordinate, we can map the rectangle between the
+ two coordinate systems.
+*/
+QRectF QCocoaScreen::flipCoordinate(const QRectF &rect) const
+{
+ return QRectF(flipCoordinate(rect.topLeft() + QPoint(0, rect.height())), rect.size());
}
void QCocoaScreen::updateGeometry()
{
- NSScreen *nsScreen = osScreen();
- if (!nsScreen)
+ if (!m_nsScreen)
return;
- NSRect frameRect = [nsScreen frame];
+ // At this point the geometry is in native coordinates, but the size
+ // is correct, which we take advantage of next when we map the native
+ // coordinates to the Qt coordinate system.
+ m_geometry = QRectF::fromCGRect(m_nsScreen.frame).toRect();
+ m_availableGeometry = QRectF::fromCGRect(m_nsScreen.visibleFrame).toRect();
- if (m_screenIndex == 0) {
- m_geometry = QRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height);
- // This is the primary screen, the one that contains the menubar. Its origin should be
- // (0, 0), and it's the only one whose available geometry differs from its full geometry.
- NSRect visibleRect = [nsScreen visibleFrame];
- m_availableGeometry = QRect(visibleRect.origin.x,
- frameRect.size.height - (visibleRect.origin.y + visibleRect.size.height), // invert y
- visibleRect.size.width, visibleRect.size.height);
- } else {
- // NSScreen origin is at the bottom-left corner, QScreen is at the top-left corner.
- // When we get the NSScreen frame rect, we need to re-align its origin y coordinate
- // w.r.t. the primary screen, whose origin is (0, 0).
- NSRect r = [[[NSScreen screens] objectAtIndex:0] frame];
- QRect referenceScreenGeometry = QRect(r.origin.x, r.origin.y, r.size.width, r.size.height);
- m_geometry = QRect(frameRect.origin.x,
- referenceScreenGeometry.height() - (frameRect.origin.y + frameRect.size.height),
- frameRect.size.width, frameRect.size.height);
-
- // Not primary screen. See above.
- m_availableGeometry = m_geometry;
- }
+ // The reference screen for the geometry is always the primary screen, but since
+ // we may be in the process of creating and registering the primary screen, we
+ // must special-case that and assign it direcly.
+ QCocoaScreen *primaryScreen = (m_nsScreen == [[NSScreen screens] firstObject]) ?
+ this : static_cast<QCocoaScreen*>(QGuiApplication::primaryScreen()->handle());
+
+ m_geometry = primaryScreen->mapFromNative(m_geometry).toRect();
+ m_availableGeometry = primaryScreen->mapFromNative(m_availableGeometry).toRect();
m_format = QImage::Format_RGB32;
- m_depth = NSBitsPerPixelFromDepth([nsScreen depth]);
+ m_depth = NSBitsPerPixelFromDepth([m_nsScreen depth]);
- NSDictionary *devDesc = [nsScreen deviceDescription];
+ NSDictionary *devDesc = [m_nsScreen deviceDescription];
CGDirectDisplayID dpy = [[devDesc objectForKey:@"NSScreenNumber"] unsignedIntValue];
CGSize size = CGDisplayScreenSize(dpy);
m_physicalSize = QSizeF(size.width, size.height);
@@ -147,8 +164,7 @@ void QCocoaScreen::updateGeometry()
qreal QCocoaScreen::devicePixelRatio() const
{
QMacAutoReleasePool pool;
- NSScreen * screen = osScreen();
- return qreal(screen ? [screen backingScaleFactor] : 1.0);
+ return qreal(m_nsScreen ? [m_nsScreen backingScaleFactor] : 1.0);
}
QPlatformScreen::SubpixelAntialiasingType QCocoaScreen::subpixelAntialiasingTypeHint() const
@@ -423,7 +439,7 @@ void QCocoaIntegration::updateScreens()
// NSScreen documentation says do not cache the array returned from [NSScreen screens].
// However in practice, we can identify a screen by its pointer: if resolution changes,
// the NSScreen object will be the same instance, just with different values.
- if (existingScr->osScreen() == scr) {
+ if (existingScr->nsScreen() == scr) {
screen = existingScr;
break;
}
@@ -431,7 +447,7 @@ void QCocoaIntegration::updateScreens()
remainingScreens.remove(screen);
screen->updateGeometry();
} else {
- screen = new QCocoaScreen(i);
+ screen = new QCocoaScreen(scr);
mScreens.append(screen);
screenAdded(screen);
}
@@ -451,16 +467,21 @@ void QCocoaIntegration::updateScreens()
}
}
-QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
+QCocoaScreen *QCocoaIntegration::screenForNSScreen(NSScreen *nsScreen)
{
- if (index >= mScreens.count())
+ NSUInteger index = [[NSScreen screens] indexOfObject:nsScreen];
+ if (index == NSNotFound)
+ return 0;
+
+ if (index >= unsigned(mScreens.count()))
updateScreens();
- // It is possible that the screen got removed while updateScreens was called
- // so we do a sanity check to be certain
- if (index >= mScreens.count())
- return 0;
- return mScreens.at(index);
+ for (QCocoaScreen *screen : mScreens) {
+ if (screen->nsScreen() == nsScreen)
+ return screen;
+ }
+
+ return 0;
}
bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 2e9de03dfc..1cd4c1905a 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -96,6 +96,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindowHelper);
@property (nonatomic, readonly) QNSWindowHelper *helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw;
@@ -111,6 +112,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindow);
@property (nonatomic, readonly) QNSWindowHelper *helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw;
@@ -141,6 +143,13 @@ QT_BEGIN_NAMESPACE
// See the qt_on_cocoa manual tests for a working example, located
// in tests/manual/cocoa at the time of writing.
+#ifdef Q_MOC_RUN
+#define Q_NOTIFICATION_HANDLER(notification) Q_INVOKABLE Q_COCOA_NOTIFICATION_##notification
+#else
+#define Q_NOTIFICATION_HANDLER(notification)
+#define Q_NOTIFICATION_PREFIX QT_STRINGIFY2(Q_COCOA_NOTIFICATION_)
+#endif
+
class QCocoaMenuBar;
class QCocoaWindow : public QObject, public QPlatformWindow
@@ -187,12 +196,25 @@ public:
void setEmbeddedInForeignView(bool subwindow);
- void windowWillMove();
- void windowDidMove();
- void windowDidResize();
- void windowDidEndLiveResize();
+ Q_NOTIFICATION_HANDLER(NSWindowWillMoveNotification) void windowWillMove();
+ Q_NOTIFICATION_HANDLER(NSWindowDidMoveNotification) void windowDidMove();
+ Q_NOTIFICATION_HANDLER(NSWindowDidResizeNotification) void windowDidResize();
+ Q_NOTIFICATION_HANDLER(NSViewFrameDidChangeNotification) void viewDidChangeFrame();
+ Q_NOTIFICATION_HANDLER(NSViewGlobalFrameDidChangeNotification) void viewDidChangeGlobalFrame();
+ Q_NOTIFICATION_HANDLER(NSWindowDidEndLiveResizeNotification) void windowDidEndLiveResize();
+ Q_NOTIFICATION_HANDLER(NSWindowDidBecomeKeyNotification) void windowDidBecomeKey();
+ Q_NOTIFICATION_HANDLER(NSWindowDidResignKeyNotification) void windowDidResignKey();
+ Q_NOTIFICATION_HANDLER(NSWindowDidMiniaturizeNotification) void windowDidMiniaturize();
+ Q_NOTIFICATION_HANDLER(NSWindowDidDeminiaturizeNotification) void windowDidDeminiaturize();
+ Q_NOTIFICATION_HANDLER(NSWindowDidEnterFullScreenNotification) void windowDidEnterFullScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidExitFullScreenNotification) void windowDidExitFullScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidOrderOnScreenAndFinishAnimatingNotification) void windowDidOrderOnScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidChangeOcclusionStateNotification) void windowDidChangeOcclusionState();
+ Q_NOTIFICATION_HANDLER(NSWindowDidChangeScreenNotification) void windowDidChangeScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowWillCloseNotification) void windowWillClose();
+
bool windowShouldClose();
- void windowWillClose();
bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const;
void setSynchedWindowStateFromWindow();
@@ -237,19 +259,33 @@ public:
static QPoint bottomLeftClippedByNSWindowOffsetStatic(QWindow *window);
QPoint bottomLeftClippedByNSWindowOffset() const;
+
+ enum RecreationReason {
+ RecreationNotNeeded = 0,
+ ParentChanged = 0x1,
+ MissingWindow = 0x2,
+ WindowModalityChanged = 0x4,
+ ChildNSWindowChanged = 0x8,
+ ContentViewChanged = 0x10,
+ PanelChanged = 0x20,
+ };
+ Q_DECLARE_FLAGS(RecreationReasons, RecreationReason)
+ Q_FLAG(RecreationReasons)
+
protected:
- void recreateWindow(const QPlatformWindow *parentWindow);
- QCocoaNSWindow *createNSWindow();
- void setNSWindow(QCocoaNSWindow *window);
+ bool isChildNSWindow() const;
+ bool isContentView() const;
- bool shouldUseNSPanel();
+ void foreachChildNSWindow(void (^block)(QCocoaWindow *));
+
+ void recreateWindowIfNeeded();
+ QCocoaNSWindow *createNSWindow(bool shouldBeChildNSWindow, bool shouldBePanel);
QRect nativeWindowGeometry() const;
QCocoaWindow *parentCocoaWindow() const;
void syncWindowState(Qt::WindowState newState);
void reinsertChildWindow(QCocoaWindow *child);
void removeChildWindow(QCocoaWindow *child);
- bool isNativeWindowTypeInconsistent();
// private:
public: // for QNSView
@@ -266,10 +302,6 @@ public: // for QNSView
bool m_viewIsEmbedded; // true if the m_view is actually embedded in a "foreign" NSView hiearchy
bool m_viewIsToBeEmbedded; // true if the m_view is intended to be embedded in a "foreign" NSView hiearchy
- QCocoaWindow *m_parentCocoaWindow;
- bool m_isNSWindowChild; // this window is a non-top level QWindow with a NSWindow.
- QList<QCocoaWindow *> m_childWindows;
-
Qt::WindowFlags m_windowFlags;
bool m_effectivelyMaximized;
Qt::WindowState m_synchedWindowState;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index e377d8f83d..dfaed9923e 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -130,8 +130,7 @@ static void qt_closePopups()
[forwardView mouseDragged:theEvent];
}
}
-
- if (!pw->m_isNSWindowChild && theEvent.type == NSLeftMouseDown) {
+ if (pw->window()->isTopLevel() && theEvent.type == NSLeftMouseDown) {
pw->m_forwardWindow.clear();
}
}
@@ -202,13 +201,14 @@ static void qt_closePopups()
@synthesize helper = _helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw
{
self = [super initWithContentRect:contentRect
styleMask:windowStyle
backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is
+ defer:NO screen:screen]; // Deferring window creation breaks OpenGL (the GL context is
// set up before the window is shown and needs a proper window)
if (self) {
@@ -222,7 +222,7 @@ static void qt_closePopups()
// Prevent child NSWindows from becoming the key window in
// order keep the active apperance of the top-level window.
QCocoaWindow *pw = self.helper.platformWindow;
- if (!pw || pw->m_isNSWindowChild)
+ if (!pw || !pw->window()->isTopLevel())
return NO;
if (pw->shouldRefuseKeyWindowAndFirstResponder())
@@ -241,7 +241,7 @@ static void qt_closePopups()
// Windows with a transient parent (such as combobox popup windows)
// cannot become the main window:
QCocoaWindow *pw = self.helper.platformWindow;
- if (!pw || pw->m_isNSWindowChild || pw->window()->transientParent())
+ if (!pw || !pw->window()->isTopLevel() || pw->window()->transientParent())
canBecomeMain = NO;
return canBecomeMain;
@@ -284,13 +284,14 @@ static void qt_closePopups()
@synthesize helper = _helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw
{
self = [super initWithContentRect:contentRect
styleMask:windowStyle
backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is
+ defer:NO screen:screen]; // Deferring window creation breaks OpenGL (the GL context is
// set up before the window is shown and needs a proper window)
if (self) {
@@ -343,6 +344,63 @@ static void qt_closePopups()
@end
+static void qRegisterNotificationCallbacks()
+{
+ static const QLatin1String notificationHandlerPrefix(Q_NOTIFICATION_PREFIX);
+
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+
+ const QMetaObject *metaObject = QMetaType::metaObjectForType(qRegisterMetaType<QCocoaWindow*>());
+ Q_ASSERT(metaObject);
+
+ for (int i = 0; i < metaObject->methodCount(); ++i) {
+ QMetaMethod method = metaObject->method(i);
+ const QString methodTag = QString::fromLatin1(method.tag());
+ if (!methodTag.startsWith(notificationHandlerPrefix))
+ continue;
+
+ const QString notificationName = methodTag.mid(notificationHandlerPrefix.size());
+ [center addObserverForName:notificationName.toNSString() object:nil queue:nil
+ usingBlock:^(NSNotification *notification) {
+
+ NSView *view = nullptr;
+ if ([notification.object isKindOfClass:[NSWindow class]]) {
+ NSWindow *window = notification.object;
+ // Only top level NSWindows should notify their QNSViews
+ if (window.parentWindow)
+ return;
+
+ if (!window.contentView)
+ return;
+
+ view = window.contentView;
+ } else if ([notification.object isKindOfClass:[NSView class]]) {
+ view = notification.object;
+ } else {
+ qCWarning(lcQpaCocoaWindow) << "Unhandled notifcation"
+ << notification.name << "for" << notification.object;
+ return;
+ }
+ Q_ASSERT(view);
+
+ QCocoaWindow *cocoaWindow = nullptr;
+ if (QNSView *qnsView = qnsview_cast(view))
+ cocoaWindow = qnsView.platformWindow;
+
+ // FIXME: Could be a foreign window, look up by iterating top level QWindows
+
+ if (!cocoaWindow)
+ return;
+
+ if (!method.invoke(cocoaWindow, Qt::DirectConnection)) {
+ qCWarning(lcQpaCocoaWindow) << "Failed to invoke NSNotification callback for"
+ << notification.name << "on" << cocoaWindow;
+ }
+ }];
+ }
+}
+Q_CONSTRUCTOR_FUNCTION(qRegisterNotificationCallbacks)
+
const int QCocoaWindow::NoAlertRequest = -1;
QCocoaWindow::QCocoaWindow(QWindow *tlw)
@@ -351,8 +409,6 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_nsWindow(0)
, m_viewIsEmbedded(false)
, m_viewIsToBeEmbedded(false)
- , m_parentCocoaWindow(0)
- , m_isNSWindowChild(false)
, m_effectivelyMaximized(false)
, m_synchedWindowState(Qt::WindowActive)
, m_windowModality(Qt::NonModal)
@@ -405,7 +461,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
[m_view setWantsLayer:enable];
}
setGeometry(tlw->geometry());
- recreateWindow(QPlatformWindow::parent());
+ recreateWindowIfNeeded();
tlw->setGeometry(geometry());
if (tlw->isTopLevel())
setWindowIcon(tlw->icon());
@@ -420,12 +476,10 @@ QCocoaWindow::~QCocoaWindow()
[m_nsWindow makeFirstResponder:nil];
[m_nsWindow setContentView:nil];
[m_nsWindow.helper detachFromPlatformWindow];
- if (m_isNSWindowChild) {
- if (m_parentCocoaWindow)
- m_parentCocoaWindow->removeChildWindow(this);
- } else if ([m_view superview]) {
+ if (m_view.window.parentWindow)
+ [m_view.window.parentWindow removeChildWindow:m_view.window];
+ else if ([m_view superview])
[m_view removeFromSuperview];
- }
removeMonitor();
@@ -440,10 +494,9 @@ QCocoaWindow::~QCocoaWindow()
QCocoaIntegration::instance()->popupWindowStack()->removeAll(this);
}
- foreach (QCocoaWindow *child, m_childWindows) {
- [m_nsWindow removeChildWindow:child->m_nsWindow];
- child->m_parentCocoaWindow = 0;
- }
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
+ [m_nsWindow removeChildWindow:childWindow->m_nsWindow];
+ });
[m_view release];
[m_nsWindow release];
@@ -491,7 +544,7 @@ QRect QCocoaWindow::geometry() const
NSRect screenRect = [[m_view window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
NSPoint screenPoint = screenRect.origin;
QPoint position = qt_mac_flipPoint(screenPoint).toPoint();
- QSize size = QRectF::fromCGRect([m_view bounds]).toRect().size();
+ QSize size = QRectF::fromCGRect(NSRectToCGRect([m_view bounds])).toRect().size();
return QRect(position, size);
}
@@ -512,9 +565,9 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
return;
}
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
QPlatformWindow::setGeometry(rect);
- NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSWindow *parentNSWindow = m_view.window.parentWindow;
NSRect parentWindowFrame = [parentNSWindow contentRectForFrameRect:parentNSWindow.frame];
clipWindow(parentWindowFrame);
@@ -536,14 +589,14 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
void QCocoaWindow::clipChildWindows()
{
- foreach (QCocoaWindow *childWindow, m_childWindows) {
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->clipWindow(m_nsWindow.frame);
- }
+ });
}
void QCocoaWindow::clipWindow(const NSRect &clipRect)
{
- if (!m_isNSWindowChild)
+ if (!isChildNSWindow())
return;
NSRect clippedWindowRect = NSZeroRect;
@@ -568,15 +621,15 @@ void QCocoaWindow::clipWindow(const NSRect &clipRect)
m_hiddenByClipping = false;
if (!m_hiddenByAncestor) {
[m_nsWindow orderFront:nil];
- m_parentCocoaWindow->reinsertChildWindow(this);
+ static_cast<QCocoaWindow *>(QPlatformWindow::parent())->reinsertChildWindow(this);
}
}
}
// recurse
- foreach (QCocoaWindow *childWindow, m_childWindows) {
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->clipWindow(clippedWindowRect);
- }
+ });
}
void QCocoaWindow::hide(bool becauseOfAncestor)
@@ -593,8 +646,9 @@ void QCocoaWindow::hide(bool becauseOfAncestor)
if (!visible) // Could have been clipped before
return;
- foreach (QCocoaWindow *childWindow, m_childWindows)
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->hide(true);
+ });
[m_nsWindow orderOut:nil];
}
@@ -604,20 +658,21 @@ void QCocoaWindow::show(bool becauseOfAncestor)
if ([m_nsWindow isVisible])
return;
- if (m_parentCocoaWindow && ![m_parentCocoaWindow->m_nsWindow isVisible]) {
+ if (m_view.window.parentWindow && !m_view.window.parentWindow.visible) {
m_hiddenByAncestor = true; // Parent still hidden, don't show now
} else if ((becauseOfAncestor == m_hiddenByAncestor) // Was NEITHER explicitly hidden
&& !m_hiddenByClipping) { // ... NOR clipped
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
m_hiddenByAncestor = false;
setCocoaGeometry(windowGeometry());
}
if (!m_hiddenByClipping) { // setCocoaGeometry() can change the clipping status
[m_nsWindow orderFront:nil];
- if (m_isNSWindowChild)
- m_parentCocoaWindow->reinsertChildWindow(this);
- foreach (QCocoaWindow *childWindow, m_childWindows)
+ if (isChildNSWindow())
+ static_cast<QCocoaWindow *>(QPlatformWindow::parent())->reinsertChildWindow(this);
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->show(true);
+ });
}
}
}
@@ -626,7 +681,7 @@ void QCocoaWindow::setVisible(bool visible)
{
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setVisible" << window() << visible;
- if (m_isNSWindowChild && m_hiddenByClipping)
+ if (isChildNSWindow() && m_hiddenByClipping)
return;
m_inSetVisible = true;
@@ -638,8 +693,7 @@ void QCocoaWindow::setVisible(bool visible)
if (visible) {
// We need to recreate if the modality has changed as the style mask will need updating
- if (m_windowModality != window()->modality() || isNativeWindowTypeInconsistent())
- recreateWindow(QPlatformWindow::parent());
+ recreateWindowIfNeeded();
// Register popup windows. The Cocoa platform plugin will forward mouse events
// to them and close them when needed.
@@ -700,8 +754,9 @@ void QCocoaWindow::setVisible(bool visible)
else
[m_nsWindow orderFront:nil];
- foreach (QCocoaWindow *childWindow, m_childWindows)
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->show(true);
+ });
} else {
show();
}
@@ -879,7 +934,7 @@ void QCocoaWindow::setWindowZoomButton(Qt::WindowFlags flags)
void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (m_nsWindow && !m_isNSWindowChild) {
+ if (m_nsWindow && !isChildNSWindow()) {
NSUInteger styleMask = windowStyleMask(flags);
NSInteger level = this->windowLevel(flags);
// While setting style mask we can have -updateGeometry calls on a content
@@ -983,19 +1038,16 @@ void QCocoaWindow::raise()
// ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
if (!m_nsWindow)
return;
- if (m_isNSWindowChild) {
- QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
- siblings.removeOne(this);
- siblings.append(this);
+ if (isChildNSWindow()) {
if (m_hiddenByClipping)
return;
}
if ([m_nsWindow isVisible]) {
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
// -[NSWindow orderFront:] doesn't work with attached windows.
// The only solution is to remove and add the child window.
// This will place it on top of all the other NSWindows.
- NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSWindow *parentNSWindow = m_view.window.parentWindow;
[parentNSWindow removeChildWindow:m_nsWindow];
[parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
} else {
@@ -1021,20 +1073,17 @@ void QCocoaWindow::lower()
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::lower" << window();
if (!m_nsWindow)
return;
- if (m_isNSWindowChild) {
- QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
- siblings.removeOne(this);
- siblings.prepend(this);
+ if (isChildNSWindow()) {
if (m_hiddenByClipping)
return;
}
if ([m_nsWindow isVisible]) {
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
// -[NSWindow orderBack:] doesn't work with attached windows.
// The only solution is to remove and add all the child windows except this one.
// This will keep the current window at the bottom while adding the others on top of it,
// hopefully in the same order (this is not documented anywhere in the Cocoa documentation).
- NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSWindow *parentNSWindow = m_view.window.parentWindow;
NSArray *children = [parentNSWindow.childWindows copy];
for (NSWindow *child in children)
if (m_nsWindow != child) {
@@ -1095,7 +1144,7 @@ void QCocoaWindow::propagateSizeHints()
QSize sizeIncrement = windowSizeIncrement();
if (sizeIncrement.isEmpty())
sizeIncrement = QSize(1, 1);
- [m_nsWindow setResizeIncrements:sizeIncrement.toCGSize()];
+ [m_nsWindow setResizeIncrements:NSSizeFromCGSize(sizeIncrement.toCGSize())];
QRect rect = geometry();
QSize baseSize = windowBaseSize();
@@ -1158,7 +1207,7 @@ void QCocoaWindow::setParent(const QPlatformWindow *parentWindow)
// recreate the window for compatibility
bool unhideAfterRecreate = parentWindow && !m_viewIsToBeEmbedded && ![m_view isHidden];
- recreateWindow(parentWindow);
+ recreateWindowIfNeeded();
if (unhideAfterRecreate)
[m_view setHidden:NO];
setCocoaGeometry(geometry());
@@ -1182,6 +1231,8 @@ void QCocoaWindow::setEmbeddedInForeignView(bool embedded)
m_nsWindow = 0;
}
+// ----------------------- NSWindow notifications -----------------------
+
void QCocoaWindow::windowWillMove()
{
// Close any open popups on window move
@@ -1190,7 +1241,7 @@ void QCocoaWindow::windowWillMove()
void QCocoaWindow::windowDidMove()
{
- if (m_isNSWindowChild)
+ if (isChildNSWindow())
return;
[qnsview_cast(m_view) updateGeometry];
@@ -1201,13 +1252,30 @@ void QCocoaWindow::windowDidResize()
if (!m_nsWindow)
return;
- if (m_isNSWindowChild)
+ if (isChildNSWindow())
return;
clipChildWindows();
[qnsview_cast(m_view) updateGeometry];
}
+void QCocoaWindow::viewDidChangeFrame()
+{
+ [qnsview_cast(m_view) updateGeometry];
+}
+
+/*!
+ Callback for NSViewGlobalFrameDidChangeNotification.
+
+ Posted whenever an NSView object that has attached surfaces (that is,
+ NSOpenGLContext objects) moves to a different screen, or other cases
+ where the NSOpenGLContext object needs to be updated.
+*/
+void QCocoaWindow::viewDidChangeGlobalFrame()
+{
+ updateExposedGeometry();
+}
+
void QCocoaWindow::windowDidEndLiveResize()
{
if (m_synchedWindowState == Qt::WindowMaximized && ![m_nsWindow isZoomed]) {
@@ -1216,6 +1284,104 @@ void QCocoaWindow::windowDidEndLiveResize()
}
}
+void QCocoaWindow::windowDidBecomeKey()
+{
+ if (window()->type() == Qt::ForeignWindow)
+ return;
+
+ if (m_windowUnderMouse) {
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [qnsview_cast(m_view) convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleEnterEvent(m_enterLeaveTargetWindow, windowPoint, screenPoint);
+ }
+
+ if (!windowIsPopupType() && !qnsview_cast(m_view).isMenuView)
+ QWindowSystemInterface::handleWindowActivated(window());
+}
+
+void QCocoaWindow::windowDidResignKey()
+{
+ if (window()->type() == Qt::ForeignWindow)
+ return;
+
+ // Key window will be non-nil if another window became key, so do not
+ // set the active window to zero here -- the new key window's
+ // NSWindowDidBecomeKeyNotification hander will change the active window.
+ NSWindow *keyWindow = [NSApp keyWindow];
+ if (!keyWindow || keyWindow == m_view.window) {
+ // No new key window, go ahead and set the active window to zero
+ if (!windowIsPopupType() && !qnsview_cast(m_view).isMenuView)
+ QWindowSystemInterface::handleWindowActivated(0);
+ }
+}
+
+void QCocoaWindow::windowDidMiniaturize()
+{
+ [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowMinimized];
+}
+
+void QCocoaWindow::windowDidDeminiaturize()
+{
+ [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowNoState];
+}
+
+void QCocoaWindow::windowDidEnterFullScreen()
+{
+ [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowFullScreen];
+}
+
+void QCocoaWindow::windowDidExitFullScreen()
+{
+ [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowNoState];
+}
+
+void QCocoaWindow::windowDidOrderOffScreen()
+{
+ obscureWindow();
+}
+
+void QCocoaWindow::windowDidOrderOnScreen()
+{
+ exposeWindow();
+}
+
+void QCocoaWindow::windowDidChangeOcclusionState()
+{
+ // Several unit tests expect paint and/or expose events for windows that are
+ // sometimes (unpredictably) occluded and some unit tests depend on QWindow::isExposed.
+ // Don't send Expose/Obscure events when running under QTestLib.
+ static const bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING");
+ if (!onTestLib) {
+ if ((NSUInteger)[m_view.window occlusionState] & NSWindowOcclusionStateVisible) {
+ exposeWindow();
+ } else {
+ // Send Obscure events on window occlusion to stop animations.
+ obscureWindow();
+ }
+ }
+}
+
+void QCocoaWindow::windowDidChangeScreen()
+{
+ if (!window())
+ return;
+
+ if (QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen))
+ QWindowSystemInterface::handleWindowScreenChanged(window(), cocoaScreen->screen());
+
+ updateExposedGeometry();
+}
+
+void QCocoaWindow::windowWillClose()
+{
+ // Close any open popups on window closing.
+ if (window() && !windowIsPopupType(window()->type()))
+ qt_closePopups();
+}
+
+// ----------------------- NSWindowDelegate callbacks -----------------------
+
bool QCocoaWindow::windowShouldClose()
{
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::windowShouldClose" << window();
@@ -1229,12 +1395,7 @@ bool QCocoaWindow::windowShouldClose()
return accepted;
}
-void QCocoaWindow::windowWillClose()
-{
- // Close any open popups on window closing.
- if (window() && !windowIsPopupType(window()->type()))
- qt_closePopups();
-}
+// --------------------------------------------------------------------------
void QCocoaWindow::setSynchedWindowStateFromWindow()
{
@@ -1264,62 +1425,141 @@ QCocoaGLContext *QCocoaWindow::currentContext() const
}
#endif
-void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
+/*!
+ Checks if the window is a non-top level QWindow with a NSWindow.
+
+ \sa _q_platform_MacUseNSWindow, QT_MAC_USE_NSWINDOW
+*/
+bool QCocoaWindow::isChildNSWindow() const
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::recreateWindow" << window()
+ return m_view.window.parentWindow != nil;
+}
+
+/*!
+ Checks if the window is the content view of its immediate NSWindow.
+
+ Being the content view of a NSWindow means the QWindow is
+ the highest accessible NSView object in the window's view
+ hierarchy.
+
+ This can only happen in two cases, either if the QWindow is
+ itself a top level window, or if it's a child NSWindow.
+
+ \sa isChildNSWindow
+*/
+bool QCocoaWindow::isContentView() const
+{
+ return m_view.window.contentView == m_view;
+}
+
+/*!
+ Iterates child NSWindows that have a corresponding QCocoaWindow.
+*/
+void QCocoaWindow::foreachChildNSWindow(void (^block)(QCocoaWindow *))
+{
+ NSArray *windows = m_view.window.childWindows;
+ [windows enumerateObjectsUsingBlock:^(NSWindow *window, NSUInteger index, BOOL *stop) {
+ Q_UNUSED(index);
+ Q_UNUSED(stop);
+ if (QNSView *view = qnsview_cast(window.contentView))
+ block(view.platformWindow);
+ }];
+}
+
+/*!
+ Recreates (or removes) the NSWindow for this QWindow, if needed.
+
+ A QWindow may need a corresponding NSWindow, depending on whether
+ or not it's a top level or not (or explicitly set to be a child
+ NSWindow), whether it is a NSPanel or not, etc.
+*/
+void QCocoaWindow::recreateWindowIfNeeded()
+{
+ QPlatformWindow *parentWindow = QPlatformWindow::parent();
+ qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::recreateWindowIfNeeded" << window()
<< "parent" << (parentWindow ? parentWindow->window() : 0);
- bool wasNSWindowChild = m_isNSWindowChild;
- BOOL requestNSWindowChild = qt_mac_resolveOption(NO, window(), "_q_platform_MacUseNSWindow",
- "QT_MAC_USE_NSWINDOW");
- m_isNSWindowChild = parentWindow && requestNSWindowChild;
- bool needsNSWindow = m_isNSWindowChild || !parentWindow;
+ RecreationReasons recreateReason = RecreationNotNeeded;
+
+ QCocoaWindow *oldParentCocoaWindow = nullptr;
+ if (QNSView *qnsView = qnsview_cast(m_view.superview))
+ oldParentCocoaWindow = qnsView.platformWindow;
+
+ if (parentWindow != oldParentCocoaWindow)
+ recreateReason |= ParentChanged;
+
+ if (!m_view.window)
+ recreateReason |= MissingWindow;
+
+ // If the modality has changed the style mask will need updating
+ if (m_windowModality != window()->modality())
+ recreateReason |= WindowModalityChanged;
+
+ const bool shouldBeChildNSWindow = parentWindow && qt_mac_resolveOption(NO,
+ window(), "_q_platform_MacUseNSWindow", "QT_MAC_USE_NSWINDOW");
+
+ if (isChildNSWindow() != shouldBeChildNSWindow)
+ recreateReason |= ChildNSWindowChanged;
+
+ const bool shouldBeContentView = !parentWindow || shouldBeChildNSWindow;
+ if (isContentView() != shouldBeContentView)
+ recreateReason |= ContentViewChanged;
- QCocoaWindow *oldParentCocoaWindow = m_parentCocoaWindow;
- m_parentCocoaWindow = const_cast<QCocoaWindow *>(static_cast<const QCocoaWindow *>(parentWindow));
- if (m_parentCocoaWindow && m_isNSWindowChild) {
- QWindow *parentQWindow = m_parentCocoaWindow->window();
+ Qt::WindowType type = window()->type();
+ const bool isPanel = isContentView() && [m_view.window isKindOfClass:[QNSPanel class]];
+ const bool shouldBePanel = shouldBeContentView && !shouldBeChildNSWindow &&
+ ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog);
+
+ if (isPanel != shouldBePanel)
+ recreateReason |= PanelChanged;
+
+ if (recreateReason == RecreationNotNeeded) {
+ qCDebug(lcQpaCocoaWindow) << "No need to recreate NSWindow";
+ return;
+ }
+
+ qCDebug(lcQpaCocoaWindow) << "Recreating NSWindow due to" << recreateReason;
+
+ QCocoaWindow *parentCocoaWindow = static_cast<QCocoaWindow *>(parentWindow);
+
+ if (shouldBeChildNSWindow) {
+ QWindow *parentQWindow = parentWindow->window();
+ // Ensure that all parents in the hierarchy are also child NSWindows
if (!parentQWindow->property("_q_platform_MacUseNSWindow").toBool()) {
parentQWindow->setProperty("_q_platform_MacUseNSWindow", QVariant(true));
- m_parentCocoaWindow->recreateWindow(m_parentCocoaWindow->m_parentCocoaWindow);
+ parentCocoaWindow->recreateWindowIfNeeded();
}
}
- bool usesNSPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
-
- // No child QNSWindow should notify its QNSView
- 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)
- if ((m_nsWindow && !needsNSWindow) || (usesNSPanel != shouldUseNSPanel())) {
+ if ((isContentView() && !shouldBeContentView) || (recreateReason & PanelChanged)) {
[m_nsWindow closeAndRelease];
- if (wasNSWindowChild && oldParentCocoaWindow)
- oldParentCocoaWindow->removeChildWindow(this);
+ if (isChildNSWindow())
+ [m_view.window.parentWindow removeChildWindow:m_view.window];
m_nsWindow = 0;
}
- if (needsNSWindow) {
+ if (shouldBeContentView) {
bool noPreviousWindow = m_nsWindow == 0;
if (noPreviousWindow)
- m_nsWindow = createNSWindow();
-
- // Only non-child QNSWindows should notify their QNSViews
- // (but don't register more than once).
- 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];
-
- if (oldParentCocoaWindow) {
- if (!m_isNSWindowChild || oldParentCocoaWindow != m_parentCocoaWindow)
- oldParentCocoaWindow->removeChildWindow(this);
+ m_nsWindow = createNSWindow(shouldBeChildNSWindow, shouldBePanel);
+
+ if (m_view.window.parentWindow) {
+ if (!shouldBeChildNSWindow || (recreateReason & ParentChanged))
+ [m_view.window.parentWindow removeChildWindow:m_view.window];
m_forwardWindow = oldParentCocoaWindow;
}
- setNSWindow(m_nsWindow);
+ // Move view to new NSWindow if needed
+ if (m_nsWindow.contentView != m_view) {
+ [m_view setPostsFrameChangedNotifications:NO];
+ [m_view retain];
+ if (m_view.superview) // m_view comes from another NSWindow
+ [m_view removeFromSuperview];
+ [m_nsWindow setContentView:m_view];
+ [m_view release];
+ [m_view setPostsFrameChangedNotifications:YES];
+ }
}
if (m_viewIsToBeEmbedded) {
@@ -1330,7 +1570,13 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
setWindowFlags(window()->flags());
setWindowTitle(window()->title());
setWindowState(window()->windowState());
- } else if (m_isNSWindowChild) {
+ } else if (shouldBeChildNSWindow) {
+ if (!m_hiddenByClipping) {
+ [parentCocoaWindow->m_nsWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
+ parentCocoaWindow->reinsertChildWindow(this);
+ }
+
+ // Set properties after the window has been made a child NSWindow
m_nsWindow.styleMask = NSBorderlessWindowMask;
m_nsWindow.hasShadow = NO;
m_nsWindow.level = NSNormalWindowLevel;
@@ -1340,22 +1586,12 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
m_nsWindow.collectionBehavior = collectionBehavior;
setCocoaGeometry(windowGeometry());
-
- QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
- if (siblings.contains(this)) {
- if (!m_hiddenByClipping)
- m_parentCocoaWindow->reinsertChildWindow(this);
- } else {
- if (!m_hiddenByClipping)
- [m_parentCocoaWindow->m_nsWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
- siblings.append(this);
- }
} else {
// Child windows have no NSWindow, link the NSViews instead.
if ([m_view superview])
[m_view removeFromSuperview];
- [m_parentCocoaWindow->m_view addSubview:m_view];
+ [parentCocoaWindow->m_view addSubview:m_view];
QRect rect = windowGeometry();
// Prevent setting a (0,0) window size; causes opengl context
// "Invalid Drawable" warnings.
@@ -1381,11 +1617,17 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
void QCocoaWindow::reinsertChildWindow(QCocoaWindow *child)
{
- int childIndex = m_childWindows.indexOf(child);
+ const QObjectList &childWindows = window()->children();
+ int childIndex = childWindows.indexOf(child->window());
Q_ASSERT(childIndex != -1);
- for (int i = childIndex; i < m_childWindows.size(); i++) {
- NSWindow *nsChild = m_childWindows[i]->m_nsWindow;
+ for (int i = childIndex; i < childWindows.size(); ++i) {
+ QWindow *window = static_cast<QWindow *>(childWindows.at(i));
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (!cocoaWindow)
+ continue;
+
+ NSWindow *nsChild = cocoaWindow->m_nsWindow;
if (i != childIndex)
[m_nsWindow removeChildWindow:nsChild];
[m_nsWindow addChildWindow:nsChild ordered:NSWindowAbove];
@@ -1399,26 +1641,39 @@ void QCocoaWindow::requestActivateWindow()
[window makeKeyWindow];
}
-bool QCocoaWindow::shouldUseNSPanel()
-{
- Qt::WindowType type = window()->type();
-
- return !m_isNSWindowChild &&
- ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog);
-}
-
-QCocoaNSWindow * QCocoaWindow::createNSWindow()
+QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBeChildNSWindow, bool shouldBePanel)
{
QMacAutoReleasePool pool;
QRect rect = initialGeometry(window(), windowGeometry(), defaultWindowWidth, defaultWindowHeight);
- NSRect frame = qt_mac_flipRect(rect);
+
+ QScreen *targetScreen = nullptr;
+ for (QScreen *screen : QGuiApplication::screens()) {
+ if (screen->geometry().contains(rect.topLeft())) {
+ targetScreen = screen;
+ break;
+ }
+ }
+
+ if (!targetScreen) {
+ qCWarning(lcQpaCocoaWindow) << "Window position outside any known screen, using primary screen";
+ targetScreen = QGuiApplication::primaryScreen();
+ }
+
+ rect.translate(-targetScreen->geometry().topLeft());
+ QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(targetScreen->handle());
+ NSRect frame = cocoaScreen->mapToNative(rect).toCGRect();
+
+ // Note: The macOS window manager has a bug, where if a screen is rotated, it will not allow
+ // a window to be created within the area of the screen that has a Y coordinate (I quadrant)
+ // higher than the height of the screen in its non-rotated state, unless the window is
+ // created with the NSWindowStyleMaskBorderless style mask.
Qt::WindowType type = window()->type();
Qt::WindowFlags flags = window()->flags();
NSUInteger styleMask;
- if (m_isNSWindowChild) {
+ if (shouldBeChildNSWindow) {
styleMask = NSBorderlessWindowMask;
} else {
styleMask = windowStyleMask(flags);
@@ -1427,32 +1682,28 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
// Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen)
// and dialogs
- if (shouldUseNSPanel()) {
- QNSPanel *window;
- window = [[QNSPanel alloc] initWithContentRect:frame
- styleMask: styleMask
- qPlatformWindow:this];
+ if (shouldBePanel) {
+ QNSPanel *panel = [[QNSPanel alloc] initWithContentRect:frame screen:cocoaScreen->nsScreen()
+ styleMask: styleMask qPlatformWindow:this];
+
if ((type & Qt::Popup) == Qt::Popup)
- [window setHasShadow:YES];
+ [panel setHasShadow:YES];
// Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set.
QVariant showWithoutActivating = QPlatformWindow::window()->property("_q_macAlwaysShowToolWindow");
bool shouldHideOnDeactivate = ((type & Qt::Tool) == Qt::Tool) &&
!(showWithoutActivating.isValid() && showWithoutActivating.toBool());
- [window setHidesOnDeactivate: shouldHideOnDeactivate];
+ [panel setHidesOnDeactivate: shouldHideOnDeactivate];
// Make popup windows show on the same desktop as the parent full-screen window.
- [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
+ [panel setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
if ((type & Qt::Popup) == Qt::Popup)
- [window setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow];
+ [panel setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow];
- createdWindow = window;
+ createdWindow = panel;
} else {
- QNSWindow *window;
- window = [[QNSWindow alloc] initWithContentRect:frame
- styleMask: styleMask
- qPlatformWindow:this];
- createdWindow = window;
+ createdWindow = [[QNSWindow alloc] initWithContentRect:frame screen:cocoaScreen->nsScreen()
+ styleMask: styleMask qPlatformWindow:this];
}
if ([createdWindow respondsToSelector:@selector(setRestorable:)])
@@ -1479,36 +1730,6 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
return createdWindow;
}
-void QCocoaWindow::setNSWindow(QCocoaNSWindow *window)
-{
- if (window.contentView != m_view) {
- [m_view setPostsFrameChangedNotifications:NO];
- [m_view retain];
- if (m_view.superview) // m_view comes from another NSWindow
- [m_view removeFromSuperview];
- [window setContentView:m_view];
- [m_view release];
- [m_view setPostsFrameChangedNotifications:YES];
- }
-}
-
-void QCocoaWindow::removeChildWindow(QCocoaWindow *child)
-{
- m_childWindows.removeOne(child);
- [m_nsWindow removeChildWindow:child->m_nsWindow];
-}
-
-bool QCocoaWindow::isNativeWindowTypeInconsistent()
-{
- if (!m_nsWindow)
- return false;
-
- const bool isPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
- const bool usePanel = shouldUseNSPanel();
-
- return isPanel != usePanel;
-}
-
void QCocoaWindow::removeMonitor()
{
if (!monitor)
@@ -1520,7 +1741,7 @@ void QCocoaWindow::removeMonitor()
// Returns the current global screen geometry for the nswindow associated with this window.
QRect QCocoaWindow::nativeWindowGeometry() const
{
- if (!m_nsWindow || m_isNSWindowChild)
+ if (!m_nsWindow || isChildNSWindow())
return geometry();
NSRect rect = [m_nsWindow frame];
@@ -1797,12 +2018,8 @@ void QCocoaWindow::exposeWindow()
// time, and we won't get a NSWindowDidChangeScreenNotification
// on show. The case where the window is initially displayed
// on a non-primary screen needs special handling here.
- NSUInteger screenIndex = [[NSScreen screens] indexOfObject:m_nsWindow.screen];
- if (screenIndex != NSNotFound) {
- QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
- if (cocoaScreen)
- window()->setScreen(cocoaScreen->screen());
- }
+ if (QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenForNSScreen(m_nsWindow.screen))
+ window()->setScreen(cocoaScreen->screen());
if (!m_isExposed) {
m_isExposed = true;
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index abaff39e81..d911b804cc 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -74,7 +74,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
QStringList *currentCustomDragTypes;
bool m_sendUpAsRightButton;
Qt::KeyboardModifiers currentWheelModifiers;
- bool m_subscribesForGlobalFrameNotifications;
#ifndef QT_NO_OPENGL
QCocoaGLContext *m_glContext;
bool m_shouldSetGLContextinDrawRect;
@@ -102,7 +101,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)drawBackingStoreUsingCoreGraphics:(NSRect)dirtyRect;
- (void)updateGeometry;
- (void)notifyWindowStateChanged:(Qt::WindowState)newState;
-- (void)windowNotification : (NSNotification *) windowNotification;
- (void)notifyWindowWillZoom:(BOOL)willZoom;
- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification;
- (void)viewDidHide;
@@ -153,6 +151,11 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
@end
+@interface QT_MANGLE_NAMESPACE(QNSView) (QtExtras)
+@property (nonatomic, readonly) QCocoaWindow *platformWindow;
+@property (nonatomic, readonly) BOOL isMenuView;
+@end
+
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSView);
#endif //QNSVIEW_H
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 6181997923..73fe5d8526 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -149,7 +149,6 @@ static bool _q_dontOverrideCtrlLMB = false;
m_acceptedMouseDowns = Qt::NoButton;
m_frameStrutButtons = Qt::NoButton;
m_sendKeyEvent = false;
- m_subscribesForGlobalFrameNotifications = false;
#ifndef QT_NO_OPENGL
m_glContext = 0;
m_shouldSetGLContextinDrawRect = false;
@@ -181,7 +180,6 @@ static bool _q_dontOverrideCtrlLMB = false;
CGImageRelease(m_maskImage);
[m_trackingArea release];
m_maskImage = 0;
- m_subscribesForGlobalFrameNotifications = false;
[m_inputSource release];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[m_mouseMoveHelper release];
@@ -217,11 +215,6 @@ static bool _q_dontOverrideCtrlLMB = false;
#endif
[self registerDragTypes];
- [self setPostsFrameChangedNotifications : YES];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(updateGeometry)
- name:NSViewFrameDidChangeNotification
- object:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textInputContextKeyboardSelectionDidChangeNotification:)
@@ -240,27 +233,9 @@ static bool _q_dontOverrideCtrlLMB = false;
//was unable to set view
m_shouldSetGLContextinDrawRect = true;
}
-
- if (!m_subscribesForGlobalFrameNotifications) {
- // NSOpenGLContext expects us to repaint (or update) the view when
- // it changes position on screen. Since this happens unnoticed for
- // the view when the parent view moves, we need to register a special
- // notification that lets us handle this case:
- m_subscribesForGlobalFrameNotifications = true;
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(globalFrameChanged:)
- name:NSViewGlobalFrameDidChangeNotification
- object:self];
- }
}
#endif
-- (void) globalFrameChanged:(NSNotification*)notification
-{
- Q_UNUSED(notification);
- m_platformWindow->updateExposedGeometry();
-}
-
- (void)viewDidMoveToSuperview
{
if (!(m_platformWindow->m_viewIsToBeEmbedded))
@@ -281,22 +256,6 @@ static bool _q_dontOverrideCtrlLMB = false;
m_backingStore = Q_NULLPTR;
}
-- (void)viewWillMoveToWindow:(NSWindow *)newWindow
-{
- // ### Merge "normal" window code path with this one for 5.1.
- if (!(m_platformWindow->window()->type() & Qt::SubWindow))
- return;
-
- if (newWindow) {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(windowNotification:)
- name:nil // Get all notifications
- object:newWindow];
- }
- if ([self window])
- [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]];
-}
-
- (QWindow *)topLevelWindow
{
QWindow *focusWindow = m_platformWindow->window();
@@ -316,7 +275,7 @@ static bool _q_dontOverrideCtrlLMB = false;
{
QRect geometry;
- if (m_platformWindow->m_isNSWindowChild) {
+ if (self.window.parentWindow) {
return;
#if 0
//geometry = QRectF::fromCGRect([self frame]).toRect();
@@ -336,10 +295,10 @@ static bool _q_dontOverrideCtrlLMB = false;
geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height);
} else if (m_platformWindow->m_viewIsToBeEmbedded) {
// embedded child window, use the frame rect ### merge with case below
- geometry = QRectF::fromCGRect([self bounds]).toRect();
+ geometry = QRectF::fromCGRect(NSRectToCGRect([self bounds])).toRect();
} else {
// child window, use the frame rect
- geometry = QRectF::fromCGRect([self frame]).toRect();
+ geometry = QRectF::fromCGRect(NSRectToCGRect([self frame])).toRect();
}
if (m_platformWindow->m_nsWindow && geometry == m_platformWindow->geometry())
@@ -395,64 +354,6 @@ static bool _q_dontOverrideCtrlLMB = false;
m_platformWindow->setSynchedWindowStateFromWindow();
}
-- (void)windowNotification : (NSNotification *) windowNotification
-{
- //qDebug() << "windowNotification" << QString::fromNSString([windowNotification name]);
-
- NSString *notificationName = [windowNotification name];
- if (notificationName == NSWindowDidBecomeKeyNotification) {
- if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
- QWindowSystemInterface::handleWindowActivated(m_platformWindow->window());
- } else if (notificationName == NSWindowDidResignKeyNotification) {
- // key window will be non-nil if another window became key... do not
- // set the active window to zero here, the new key window's
- // NSWindowDidBecomeKeyNotification hander will change the active window
- NSWindow *keyWindow = [NSApp keyWindow];
- if (!keyWindow || keyWindow == windowNotification.object) {
- // no new key window, go ahead and set the active window to zero
- if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
- QWindowSystemInterface::handleWindowActivated(0);
- }
- } else if (notificationName == NSWindowDidMiniaturizeNotification
- || notificationName == NSWindowDidDeminiaturizeNotification) {
- Qt::WindowState newState = notificationName == NSWindowDidMiniaturizeNotification ?
- Qt::WindowMinimized : Qt::WindowNoState;
- [self notifyWindowStateChanged:newState];
- } else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
- m_platformWindow->obscureWindow();
- } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
- m_platformWindow->exposeWindow();
- } else if ([notificationName isEqualToString:NSWindowDidChangeOcclusionStateNotification]) {
- // Several unit tests expect paint and/or expose events for windows that are
- // sometimes (unpredictably) occluded and some unit tests depend on QWindow::isExposed -
- // don't send Expose/Obscure events when running under QTestLib.
- static const bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING");
- if (!onTestLib) {
- if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) {
- m_platformWindow->exposeWindow();
- } else {
- // Send Obscure events on window occlusion to stop animations.
- m_platformWindow->obscureWindow();
- }
- }
- } else if (notificationName == NSWindowDidChangeScreenNotification) {
- if (m_platformWindow->window()) {
- NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];
- if (screenIndex != NSNotFound) {
- QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
- if (cocoaScreen)
- QWindowSystemInterface::handleWindowScreenChanged(m_platformWindow->window(), cocoaScreen->screen());
- m_platformWindow->updateExposedGeometry();
- }
- }
- } else if (notificationName == NSWindowDidEnterFullScreenNotification
- || notificationName == NSWindowDidExitFullScreenNotification) {
- Qt::WindowState newState = notificationName == NSWindowDidEnterFullScreenNotification ?
- Qt::WindowFullScreen : Qt::WindowNoState;
- [self notifyWindowStateChanged:newState];
- }
-}
-
- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification
{
Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification)
@@ -553,7 +454,7 @@ static bool _q_dontOverrideCtrlLMB = false;
- (void) drawRect:(NSRect)dirtyRect
{
- qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_platformWindow->window() << QRectF::fromCGRect(dirtyRect);
+ qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_platformWindow->window() << QRectF::fromCGRect(NSRectToCGRect(dirtyRect));
#ifndef QT_NO_OPENGL
if (m_glContext && m_shouldSetGLContextinDrawRect) {
@@ -1347,7 +1248,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (bool)handleGestureAsBeginEnd:(NSEvent *)event
{
- if (QSysInfo::QSysInfo::MacintoshVersion < QSysInfo::MV_10_11)
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::OSXElCapitan)
return false;
if ([event phase] == NSEventPhaseBegan) {
@@ -2214,3 +2115,17 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
}
@end
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (QtExtras)
+
+- (QCocoaWindow*)platformWindow
+{
+ return m_platformWindow.data();;
+}
+
+- (BOOL)isMenuView
+{
+ return m_isMenuView;
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
index f29aa97b68..a465b249c5 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.h
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h
@@ -49,15 +49,10 @@
QCocoaWindow *m_cocoaWindow;
}
-- (id)initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow;
+- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow;
-- (void)windowDidBecomeKey:(NSNotification *)notification;
-- (void)windowDidResize:(NSNotification *)notification;
-- (void)windowDidMove:(NSNotification *)notification;
-- (void)windowWillMove:(NSNotification *)notification;
- (BOOL)windowShouldClose:(NSNotification *)notification;
- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame;
-- (void)windowWillClose:(NSNotification *)notification;
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu;
- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard;
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 7f988ac963..3781a4cc65 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -45,57 +45,12 @@
@implementation QNSWindowDelegate
-- (id) initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow
+- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow
{
- self = [super init];
-
- if (self) {
+ if (self = [super init])
m_cocoaWindow = cocoaWindow;
- }
- return self;
-}
-
-- (void)windowDidBecomeKey:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow->m_windowUnderMouse) {
- QPointF windowPoint;
- QPointF screenPoint;
- [qnsview_cast(m_cocoaWindow->view()) convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindowSystemInterface::handleEnterEvent(m_cocoaWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
- }
-}
-
-- (void)windowDidResize:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowDidResize();
- }
-}
-
-- (void)windowDidEndLiveResize:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowDidEndLiveResize();
- }
-}
-
-- (void)windowWillMove:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowWillMove();
- }
-}
-- (void)windowDidMove:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowDidMove();
- }
+ return self;
}
- (BOOL)windowShouldClose:(NSNotification *)notification
@@ -116,13 +71,6 @@
return YES;
}
-- (void)windowWillClose:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow)
- m_cocoaWindow->windowWillClose();
-}
-
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
{
Q_UNUSED(window);