summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoaintegration.mm
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-10-17 10:19:31 +0200
committerLiang Qi <liang.qi@qt.io>2017-10-17 10:34:24 +0200
commitd0a0a3c0418a0fdd2ed84b2a5f7e6565537715c6 (patch)
treed6aeb4d51caf30ccf23eadb806a09295cbf679cd /src/plugins/platforms/cocoa/qcocoaintegration.mm
parent9f405f98a4247cd263b9c5d35659a4ba89e282de (diff)
parentac35f9c44c0fb3b2f40ae5585c497200b2ba743d (diff)
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts: examples/network/fortuneclient/client.cpp examples/network/fortuneserver/server.cpp src/platformsupport/platformcompositor/qopenglcompositorbackingstore_p.h src/plugins/platforms/cocoa/qcocoabackingstore.h src/plugins/platforms/cocoa/qcocoaintegration.h src/plugins/platforms/cocoa/qcocoascreen.h src/plugins/platforms/ios/qiosbackingstore.h src/plugins/sqldrivers/oci/qsql_oci.cpp src/widgets/kernel/qwidgetwindow.cpp Change-Id: Ia6dd2c52d4a691b671cf9a2ffca70deccece8f10
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoaintegration.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm245
1 files changed, 21 insertions, 224 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 7b1e689388..dd17848109 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -51,10 +51,12 @@
#include "qcocoainputcontext.h"
#include "qcocoamimetypes.h"
#include "qcocoaaccessibility.h"
+#include "qcocoascreen.h"
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatformaccessibility.h>
#include <qpa/qplatforminputcontextfactory_p.h>
+#include <qpa/qplatformoffscreensurface.h>
#include <QtCore/qcoreapplication.h>
#include <QtGui/private/qcoregraphics_p.h>
@@ -78,229 +80,6 @@ QT_BEGIN_NAMESPACE
class QCoreTextFontEngine;
class QFontEngineFT;
-QCocoaScreen::QCocoaScreen(int screenIndex)
- : QPlatformScreen(), m_screenIndex(screenIndex), m_refreshRate(60.0)
-{
- updateGeometry();
- m_cursor = new QCocoaCursor;
-}
-
-QCocoaScreen::~QCocoaScreen()
-{
- delete m_cursor;
-}
-
-NSScreen *QCocoaScreen::nativeScreen() const
-{
- NSArray *screens = [NSScreen screens];
-
- // Stale reference, screen configuration has changed
- if (m_screenIndex < 0 || (NSUInteger)m_screenIndex >= [screens count])
- return nil;
-
- return [screens objectAtIndex:m_screenIndex];
-}
-
-/*!
- 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 = nativeScreen();
- if (!nsScreen)
- return;
-
- // 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(NSRectToCGRect(nsScreen.frame)).toRect();
- m_availableGeometry = QRectF::fromCGRect(NSRectToCGRect(nsScreen.visibleFrame)).toRect();
-
- // 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 = (nsScreen == [[NSScreen screens] firstObject]) ?
- this : QCocoaScreen::primaryScreen();
-
- m_geometry = primaryScreen->mapFromNative(m_geometry).toRect();
- m_availableGeometry = primaryScreen->mapFromNative(m_availableGeometry).toRect();
-
- m_format = QImage::Format_RGB32;
- m_depth = NSBitsPerPixelFromDepth([nsScreen depth]);
-
- NSDictionary *devDesc = [nsScreen deviceDescription];
- CGDirectDisplayID dpy = [[devDesc objectForKey:@"NSScreenNumber"] unsignedIntValue];
- CGSize size = CGDisplayScreenSize(dpy);
- m_physicalSize = QSizeF(size.width, size.height);
- m_logicalDpi.first = 72;
- m_logicalDpi.second = 72;
- CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode(dpy);
- float refresh = CGDisplayModeGetRefreshRate(displayMode);
- CGDisplayModeRelease(displayMode);
- if (refresh > 0)
- m_refreshRate = refresh;
-
- // Get m_name (brand/model of the monitor)
- NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(dpy), kIODisplayOnlyPreferredName);
- NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
- if ([localizedNames count] > 0)
- m_name = QString::fromUtf8([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]);
- [deviceInfo release];
-
- QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
- QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), m_logicalDpi.first, m_logicalDpi.second);
- QWindowSystemInterface::handleScreenRefreshRateChange(screen(), m_refreshRate);
-}
-
-qreal QCocoaScreen::devicePixelRatio() const
-{
- QMacAutoReleasePool pool;
- NSScreen *nsScreen = nativeScreen();
- return qreal(nsScreen ? [nsScreen backingScaleFactor] : 1.0);
-}
-
-QPlatformScreen::SubpixelAntialiasingType QCocoaScreen::subpixelAntialiasingTypeHint() const
-{
- QPlatformScreen::SubpixelAntialiasingType type = QPlatformScreen::subpixelAntialiasingTypeHint();
- if (type == QPlatformScreen::Subpixel_None) {
- // Every OSX machine has RGB pixels unless a peculiar or rotated non-Apple screen is attached
- type = QPlatformScreen::Subpixel_RGB;
- }
- return type;
-}
-
-QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
-{
- NSPoint screenPoint = qt_mac_flipPoint(point);
-
- // Search (hit test) for the top-level window. [NSWidow windowNumberAtPoint:
- // belowWindowWithWindowNumber] may return windows that are not interesting
- // to Qt. The search iterates until a suitable window or no window is found.
- NSInteger topWindowNumber = 0;
- QWindow *window = 0;
- do {
- // Get the top-most window, below any previously rejected window.
- topWindowNumber = [NSWindow windowNumberAtPoint:screenPoint
- belowWindowWithWindowNumber:topWindowNumber];
-
- // Continue the search if the window does not belong to this process.
- NSWindow *nsWindow = [NSApp windowWithWindowNumber:topWindowNumber];
- if (nsWindow == 0)
- continue;
-
- // Continue the search if the window does not belong to Qt.
- if (![nsWindow conformsToProtocol:@protocol(QNSWindowProtocol)])
- continue;
-
- id<QNSWindowProtocol> proto = static_cast<id<QNSWindowProtocol> >(nsWindow);
- QCocoaWindow *cocoaWindow = proto.platformWindow;
- if (!cocoaWindow)
- continue;
- window = cocoaWindow->window();
-
- // Continue the search if the window is not a top-level window.
- if (!window->isTopLevel())
- continue;
-
- // Stop searching. The current window is the correct window.
- break;
- } while (topWindowNumber > 0);
-
- return window;
-}
-
-QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const
-{
- // TODO window should be handled
- Q_UNUSED(window)
-
- const int maxDisplays = 128; // 128 displays should be enough for everyone.
- CGDirectDisplayID displays[maxDisplays];
- CGDisplayCount displayCount;
- CGRect cgRect;
-
- if (width < 0 || height < 0) {
- // get all displays
- cgRect = CGRectInfinite;
- } else {
- cgRect = CGRectMake(x, y, width, height);
- }
- const CGDisplayErr err = CGGetDisplaysWithRect(cgRect, maxDisplays, displays, &displayCount);
-
- if (err && displayCount == 0)
- return QPixmap();
-
- // calculate pixmap size
- QSize windowSize(width, height);
- if (width < 0 || height < 0) {
- QRect windowRect;
- for (uint i = 0; i < displayCount; ++i) {
- const CGRect cgRect = CGDisplayBounds(displays[i]);
- QRect qRect(cgRect.origin.x, cgRect.origin.y, cgRect.size.width, cgRect.size.height);
- windowRect = windowRect.united(qRect);
- }
- if (width < 0)
- windowSize.setWidth(windowRect.width());
- if (height < 0)
- windowSize.setHeight(windowRect.height());
- }
-
- QPixmap windowPixmap(windowSize * devicePixelRatio());
- windowPixmap.fill(Qt::transparent);
-
- for (uint i = 0; i < displayCount; ++i) {
- const CGRect bounds = CGDisplayBounds(displays[i]);
- int w = (width < 0 ? bounds.size.width : width) * devicePixelRatio();
- int h = (height < 0 ? bounds.size.height : height) * devicePixelRatio();
- QRect displayRect = QRect(x, y, w, h);
- displayRect = displayRect.translated(qRound(-bounds.origin.x), qRound(-bounds.origin.y));
- QCFType<CGImageRef> image = CGDisplayCreateImageForRect(displays[i],
- CGRectMake(displayRect.x(), displayRect.y(), displayRect.width(), displayRect.height()));
- QPixmap pix(w, h);
- pix.fill(Qt::transparent);
- CGRect rect = CGRectMake(0, 0, w, h);
- QMacCGContext ctx(&pix);
- qt_mac_drawCGImage(ctx, &rect, image);
-
- QPainter painter(&windowPixmap);
- painter.drawPixmap(0, 0, pix);
- }
- return windowPixmap;
-}
-
-/*!
- The screen used as a reference for global window geometry
-*/
-QCocoaScreen *QCocoaScreen::primaryScreen()
-{
- return static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle());
-}
-
static QCocoaIntegration::Options parseOptions(const QStringList &paramList)
{
QCocoaIntegration::Options options;
@@ -363,7 +142,7 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
// Move the application window to front to make it take focus, also when launching
// from the terminal. On 10.12+ this call has been moved to applicationDidFinishLauching
// to work around issues with loss of focus at startup.
- if (QSysInfo::macVersion() < QSysInfo::MV_10_12) {
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSSierra) {
// Ignoring other apps is necessary (we must ignore the terminal), but makes
// Qt apps play slightly less nice with other apps when lanching from Finder
// (See the activateIgnoringOtherApps docs.)
@@ -553,6 +332,24 @@ QPlatformWindow *QCocoaIntegration::createForeignWindow(QWindow *window, WId nat
return new QCocoaWindow(window, nativeHandle);
}
+class QCocoaOffscreenSurface : public QPlatformOffscreenSurface
+{
+public:
+ QCocoaOffscreenSurface(QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) {}
+
+ QSurfaceFormat format() const override
+ {
+ Q_ASSERT(offscreenSurface());
+ return offscreenSurface()->requestedFormat();
+ }
+ bool isValid() const override { return true; }
+};
+
+QPlatformOffscreenSurface *QCocoaIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
+{
+ return new QCocoaOffscreenSurface(surface);
+}
+
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{