diff options
Diffstat (limited to 'src/plugins/platforms/cocoa')
44 files changed, 336 insertions, 1215 deletions
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 02d8b16110..d9d3cb1627 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -71,7 +71,7 @@ HEADERS += qcocoaintegration.h \ messages.h \ qcocoamimetypes.h -contains(QT_CONFIG, opengl.*) { +qtConfig(opengl.*) { OBJECTIVE_SOURCES += qcocoaglcontext.mm HEADERS += qcocoaglcontext.h diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h index e92bef4011..7bd3c8c76c 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplication.h +++ b/src/plugins/platforms/cocoa/qcocoaapplication.h @@ -95,7 +95,6 @@ @interface NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration)) - (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu; -- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader); - (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel; - (void)QT_MANGLE_NAMESPACE(qt_sendPostedMessage):(NSEvent *)event; diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm index c496134606..c5ae4bc2bf 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplication.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm @@ -71,11 +71,11 @@ ** ****************************************************************************/ -#include <qcocoaapplication.h> +#include "qcocoaapplication.h" -#include <qcocoaintrospection.h> -#include <qcocoaapplicationdelegate.h> -#include <qcocoahelpers.h> +#include "qcocoaintrospection.h" +#include "qcocoaapplicationdelegate.h" +#include "qcocoahelpers.h" #include <qguiapplication.h> #include <qdebug.h> @@ -88,11 +88,6 @@ QT_USE_NAMESPACE [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] setDockMenu:newMenu]; } -- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader) -{ - return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] menuLoader]; -} - - (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel { Q_UNUSED(fontPanel); diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h index 68a028ed8a..59c71017e3 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h @@ -95,14 +95,11 @@ @interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject <NSApplicationDelegate> { bool startedQuit; NSMenu *dockMenu; - QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader; NSObject <NSApplicationDelegate> *reflectionDelegate; bool inLaunch; } + (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate; - (void)setDockMenu:(NSMenu *)newMenu; -- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader)*)menuLoader; -- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader; - (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate; - (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent; - (void) removeAppleEventHandlers; diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index d18df35b80..4874fcf807 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -122,7 +122,6 @@ QT_END_NAMESPACE { sharedCocoaApplicationDelegate = nil; [dockMenu release]; - [qtMenuLoader release]; if (reflectionDelegate) { [[NSApplication sharedApplication] setDelegate:reflectionDelegate]; [reflectionDelegate release]; @@ -169,24 +168,12 @@ QT_END_NAMESPACE return [[dockMenu retain] autorelease]; } -- (void)setMenuLoader:(QCocoaMenuLoader *)menuLoader -{ - [menuLoader retain]; - [qtMenuLoader release]; - qtMenuLoader = menuLoader; -} - -- (QCocoaMenuLoader *)menuLoader -{ - return [[qtMenuLoader retain] autorelease]; -} - - (BOOL) canQuit { [[NSApp mainMenu] cancelTracking]; bool handle_quit = true; - NSMenuItem *quitMenuItem = [[[QCocoaApplicationDelegate sharedDelegate] menuLoader] quitMenuItem]; + NSMenuItem *quitMenuItem = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) sharedMenuLoader] quitMenuItem]; if (!QGuiApplicationPrivate::instance()->modalWindowList.isEmpty() && [quitMenuItem isEnabled]) { int visible = 0; @@ -447,10 +434,4 @@ QT_END_NAMESPACE [NSApp terminate:self]; } -- (void)qtDispatcherToQAction:(id)sender -{ - Q_UNUSED(sender); - [qtMenuLoader qtDispatcherToQPAMenuItem:sender]; -} - @end diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index fa05626d18..562be2be8f 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -40,36 +40,20 @@ #ifndef QBACKINGSTORE_COCOA_H #define QBACKINGSTORE_COCOA_H -#include <AppKit/AppKit.h> - -#include "qcocoawindow.h" -#include "qnsview.h" - -#include <qpa/qplatformbackingstore.h> +#include <QtPlatformSupport/private/qrasterbackingstore_p.h> QT_BEGIN_NAMESPACE -class QCocoaBackingStore : public QPlatformBackingStore +class QCocoaBackingStore : public QRasterBackingStore { public: QCocoaBackingStore(QWindow *window); ~QCocoaBackingStore(); - QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *widget, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; -#ifndef QT_NO_OPENGL - QImage toImage() const Q_DECL_OVERRIDE; -#else - QImage toImage() const; // No QPlatformBackingStore::toImage() for NO_OPENGL builds. -#endif - void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE; - bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; - void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; - qreal getBackingStoreDevicePixelRatio(); + void flush(QWindow *, const QRegion &, const QPoint &) Q_DECL_OVERRIDE; private: - QImage m_qImage; - QSize m_requestedSize; + QImage::Format format() const Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index b060d6a082..af5418315c 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -38,13 +38,13 @@ ****************************************************************************/ #include "qcocoabackingstore.h" -#include <QtGui/QPainter> -#include "qcocoahelpers.h" + +#include "qcocoawindow.h" QT_BEGIN_NAMESPACE QCocoaBackingStore::QCocoaBackingStore(QWindow *window) - : QPlatformBackingStore(window) + : QRasterBackingStore(window) { } @@ -54,71 +54,21 @@ QCocoaBackingStore::~QCocoaBackingStore() [cocoaWindow->m_qtView clearBackingStore:this]; } -QPaintDevice *QCocoaBackingStore::paintDevice() -{ - QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle()); - int windowDevicePixelRatio = int(cocoaWindow->devicePixelRatio()); - - // Receate the backing store buffer if the effective buffer size has changed, - // either due to a window resize or devicePixelRatio change. - QSize effectiveBufferSize = m_requestedSize * windowDevicePixelRatio; - if (m_qImage.size() != effectiveBufferSize) { - QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient) - ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; - m_qImage = QImage(effectiveBufferSize, format); - m_qImage.setDevicePixelRatio(windowDevicePixelRatio); - if (format == QImage::Format_ARGB32_Premultiplied) - m_qImage.fill(Qt::transparent); - } - return &m_qImage; -} - -void QCocoaBackingStore::flush(QWindow *win, const QRegion ®ion, const QPoint &offset) +QImage::Format QCocoaBackingStore::format() const { - if (!m_qImage.isNull()) { - if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(win->handle())) - [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset]; - } -} + if (static_cast<QCocoaWindow *>(window()->handle())->m_drawContentBorderGradient) + return QImage::Format_ARGB32_Premultiplied; -QImage QCocoaBackingStore::toImage() const -{ - return m_qImage; + return QRasterBackingStore::format(); } -void QCocoaBackingStore::resize(const QSize &size, const QRegion &) +void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { - m_requestedSize = size; -} + if (m_image.isNull()) + return; -bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy) -{ - extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); - const qreal devicePixelRatio = m_qImage.devicePixelRatio(); - QPoint qpoint(dx * devicePixelRatio, dy * devicePixelRatio); - const QVector<QRect> qrects = area.rects(); - for (int i = 0; i < qrects.count(); ++i) { - const QRect &qrect = QRect(qrects.at(i).topLeft() * devicePixelRatio, qrects.at(i).size() * devicePixelRatio); - qt_scrollRectInImage(m_qImage, qrect, qpoint); - } - return true; -} - -void QCocoaBackingStore::beginPaint(const QRegion ®ion) -{ - if (m_qImage.hasAlphaChannel()) { - QPainter p(&m_qImage); - p.setCompositionMode(QPainter::CompositionMode_Source); - const QVector<QRect> rects = region.rects(); - const QColor blank = Qt::transparent; - for (QVector<QRect>::const_iterator it = rects.begin(), end = rects.end(); it != end; ++it) - p.fillRect(*it, blank); - } -} - -qreal QCocoaBackingStore::getBackingStoreDevicePixelRatio() -{ - return m_qImage.devicePixelRatio(); + if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle())) + [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset]; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.h b/src/plugins/platforms/cocoa/qcocoaclipboard.h index 52fec61f39..cab2cfaa91 100644 --- a/src/plugins/platforms/cocoa/qcocoaclipboard.h +++ b/src/plugins/platforms/cocoa/qcocoaclipboard.h @@ -41,6 +41,9 @@ #define QCOCOACLIPBOARD_H #include <qpa/qplatformclipboard.h> + +#ifndef QT_NO_CLIPBOARD + #include "qmacclipboard.h" #include <QtCore/QScopedPointer> @@ -71,4 +74,6 @@ private: QT_END_NAMESPACE -#endif +#endif // QT_NO_CLIPBOARD + +#endif // QCOCOACLIPBOARD_H diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.mm b/src/plugins/platforms/cocoa/qcocoaclipboard.mm index 7209c93a94..b4745900dc 100644 --- a/src/plugins/platforms/cocoa/qcocoaclipboard.mm +++ b/src/plugins/platforms/cocoa/qcocoaclipboard.mm @@ -39,6 +39,8 @@ #include "qcocoaclipboard.h" +#ifndef QT_NO_CLIPBOARD + QT_BEGIN_NAMESPACE QCocoaClipboard::QCocoaClipboard() @@ -105,3 +107,5 @@ void QCocoaClipboard::handleApplicationStateChanged(Qt::ApplicationState state) #include "moc_qcocoaclipboard.cpp" QT_END_NAMESPACE + +#endif // QT_NO_CLIPBOARD diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index 0319d4ca6d..cc8436dcfe 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -132,7 +132,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); - (void)setDialogHelper:(QCocoaColorDialogHelper *)helper { mHelper = helper; - [mColorPanel setShowsAlpha:mHelper->options()->testOption(QColorDialogOptions::ShowAlphaChannel)]; + if (mHelper->options()->testOption(QColorDialogOptions::NoButtons)) { [self restoreOriginalContentView]; } else if (!mStolenContentView) { @@ -481,6 +481,14 @@ bool QCocoaColorDialogHelper::show(Qt::WindowFlags, Qt::WindowModality windowMod { if (windowModality == Qt::WindowModal) windowModality = Qt::ApplicationModal; + + // Workaround for Apple rdar://25792119: If you invoke + // -setShowsAlpha: multiple times before showing the color + // picker, its height grows irrevocably. Instead, only + // invoke it once, when we show the dialog. + [[NSColorPanel sharedColorPanel] setShowsAlpha: + options()->testOption(QColorDialogOptions::ShowAlphaChannel)]; + sharedColorPanel()->init(this); return sharedColorPanel()->show(windowModality, parent); } diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 0433084436..8e523dfbbf 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -40,6 +40,7 @@ #include "qcocoacursor.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" +#include <QtGui/private/qcoregraphics_p.h> #include <QtGui/QBitmap> diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index bb8d12e3ce..7d11023b78 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -43,6 +43,7 @@ #ifndef QT_NO_WIDGETS #include <QtWidgets/qwidget.h> #endif +#include <QtGui/private/qcoregraphics_p.h> QT_BEGIN_NAMESPACE @@ -131,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 : qt_mac_toNSSize(pmDeviceIndependentSize)]; + [nsimage setSize: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 4eb35f5495..0375dd85f2 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -61,6 +61,8 @@ #include <qvarlengtharray.h> #include <stdlib.h> #include <qabstracteventdispatcher.h> +#include <qsysinfo.h> +#include <qglobal.h> #include <QDir> #include <qpa/qplatformnativeinterface.h> @@ -160,6 +162,11 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); // here to make sure it gets the correct value. [mSavePanel setDelegate:self]; +#if QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_11) + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_11) + mOpenPanel.accessoryViewDisclosed = YES; +#endif + if (mOptions->isLabelExplicitlySet(QFileDialogOptions::Accept)) [mSavePanel setPrompt:[self strip:options->labelText(QFileDialogOptions::Accept)]]; if (mOptions->isLabelExplicitlySet(QFileDialogOptions::FileName)) diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index ec2f7f8cf1..536a2d2d58 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -69,29 +69,6 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list); inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist) { return reinterpret_cast<NSMutableArray *>(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); } -NSImage *qt_mac_cgimage_to_nsimage(CGImageRef iamge); -NSImage *qt_mac_create_nsimage(const QPixmap &pm); -NSImage *qt_mac_create_nsimage(const QIcon &icon); -CGImageRef qt_mac_toCGImage(const QImage &qImage); -CGImageRef qt_mac_toCGImageMask(const QImage &qImage); -QImage qt_mac_toQImage(CGImageRef image); -QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size); - -NSSize qt_mac_toNSSize(const QSize &qtSize); -NSRect qt_mac_toNSRect(const QRect &rect); -QRect qt_mac_toQRect(const NSRect &rect); - -QColor qt_mac_toQColor(const NSColor *color); -QColor qt_mac_toQColor(CGColorRef color); - -QBrush qt_mac_toQBrush(CGColorRef color); -QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal); - -// Creates a mutable shape, it's the caller's responsibility to release. -HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion); - -OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); - NSDragOperation qt_mac_mapDropAction(Qt::DropAction action); NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions); Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions); @@ -99,9 +76,6 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions); // Misc void qt_mac_transformProccessToForegroundApplication(); -CGColorSpaceRef qt_mac_genericColorSpace(); -CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget); -CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice); QString qt_mac_applicationName(); int qt_mac_flipYCoordinate(int y); @@ -114,10 +88,6 @@ NSRect qt_mac_flipRect(const QRect &rect); Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); -bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret); -bool qt_mac_execute_apple_script(const char *script, AEDesc *ret); -bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret); - // strip out '&' characters, and convert "&&" to a single '&', in menu // text - since menu text is sometimes decorated with these for Windows // accelerators. @@ -151,8 +121,6 @@ public: } }; -CGContextRef qt_mac_cg_context(QPaintDevice *pdev); - template<typename T> T qt_mac_resolveOption(const T &fallback, const QByteArray &environment) { diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 606b2e7032..0c7c30579e 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -47,6 +47,7 @@ #include <qpa/qplatformscreen.h> #include <private/qguiapplication_p.h> #include <private/qwindow_p.h> +#include <QtGui/private/qcoregraphics_p.h> #ifndef QT_NO_WIDGETS #include <QtWidgets/QWidget> @@ -56,25 +57,6 @@ #include <Carbon/Carbon.h> -@interface NSGraphicsContext (QtAdditions) - -+ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState; - -@end - -@implementation NSGraphicsContext (QtAdditions) - -+ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState -{ -#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_NA) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_10) - return [self graphicsContextWithCGContext:graphicsPort flipped:initialFlippedState]; -#endif - return [self graphicsContextWithGraphicsPort:graphicsPort flipped:initialFlippedState]; -} - -@end - QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaCocoaWindow, "qt.qpa.cocoa.window"); @@ -101,291 +83,6 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list) return result; } -static void qt_mac_deleteImage(void *image, const void *, size_t) -{ - delete static_cast<QImage *>(image); -} - -// Creates a CGDataProvider with the data from the given image. -// The data provider retains a copy of the image. -CGDataProviderRef qt_mac_CGDataProvider(const QImage &image) -{ - return CGDataProviderCreateWithData(new QImage(image), image.bits(), - image.byteCount(), qt_mac_deleteImage); -} - -CGImageRef qt_mac_toCGImage(const QImage &inImage) -{ - if (inImage.isNull()) - return 0; - - QImage image = inImage; - - uint cgflags = kCGImageAlphaNone; - switch (image.format()) { - case QImage::Format_ARGB32: - cgflags = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; - break; - case QImage::Format_RGB32: - cgflags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; - break; - case QImage::Format_RGB888: - cgflags = kCGImageAlphaNone | kCGBitmapByteOrder32Big; - break; - case QImage::Format_RGBA8888_Premultiplied: - cgflags = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big; - break; - case QImage::Format_RGBA8888: - cgflags = kCGImageAlphaLast | kCGBitmapByteOrder32Big; - break; - case QImage::Format_RGBX8888: - cgflags = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big; - break; - default: - // Everything not recognized explicitly is converted to ARGB32_Premultiplied. - image = inImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); - // no break; - case QImage::Format_ARGB32_Premultiplied: - cgflags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; - break; - } - - QCFType<CGDataProviderRef> dataProvider = qt_mac_CGDataProvider(image); - return CGImageCreate(image.width(), image.height(), 8, 32, - image.bytesPerLine(), - qt_mac_genericColorSpace(), - cgflags, dataProvider, 0, false, kCGRenderingIntentDefault); -} - -CGImageRef qt_mac_toCGImageMask(const QImage &image) -{ - QCFType<CGDataProviderRef> dataProvider = qt_mac_CGDataProvider(image); - return CGImageMaskCreate(image.width(), image.height(), 8, image.depth(), - image.bytesPerLine(), dataProvider, NULL, false); -} - -NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image) -{ - NSImage *newImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize]; - return newImage; -} - -NSImage *qt_mac_create_nsimage(const QPixmap &pm) -{ - if (pm.isNull()) - return 0; - QImage image = pm.toImage(); - CGImageRef cgImage = qt_mac_toCGImage(image); - NSImage *nsImage = qt_mac_cgimage_to_nsimage(cgImage); - CGImageRelease(cgImage); - return nsImage; -} - -NSImage *qt_mac_create_nsimage(const QIcon &icon) -{ - if (icon.isNull()) - return nil; - - NSImage *nsImage = [[NSImage alloc] init]; - foreach (QSize size, icon.availableSizes()) { - QPixmap pm = icon.pixmap(size); - QImage image = pm.toImage(); - CGImageRef cgImage = qt_mac_toCGImage(image); - NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage]; - [nsImage addRepresentation:imageRep]; - [imageRep release]; - CGImageRelease(cgImage); - } - return nsImage; -} - -HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion) -{ - HIMutableShapeRef shape = HIShapeCreateMutable(); - QVector<QRect> rects = region.rects(); - if (!rects.isEmpty()) { - int n = rects.count(); - const QRect *qt_r = rects.constData(); - while (n--) { - CGRect cgRect = CGRectMake(qt_r->x(), qt_r->y(), qt_r->width(), qt_r->height()); - HIShapeUnionWithRect(shape, &cgRect); - ++qt_r; - } - } - return shape; -} - -NSSize qt_mac_toNSSize(const QSize &qtSize) -{ - return NSMakeSize(qtSize.width(), qtSize.height()); -} - -NSRect qt_mac_toNSRect(const QRect &rect) -{ - return NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); -} - -QRect qt_mac_toQRect(const NSRect &rect) -{ - return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); -} - -QColor qt_mac_toQColor(const NSColor *color) -{ - QColor qtColor; - NSString *colorSpace = [color colorSpaceName]; - if (colorSpace == NSDeviceCMYKColorSpace) { - CGFloat cyan, magenta, yellow, black, alpha; - [color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha]; - qtColor.setCmykF(cyan, magenta, yellow, black, alpha); - } else { - NSColor *tmpColor; - tmpColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace]; - CGFloat red, green, blue, alpha; - [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha]; - qtColor.setRgbF(red, green, blue, alpha); - } - return qtColor; -} - -QColor qt_mac_toQColor(CGColorRef color) -{ - QColor qtColor; - CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color)); - const CGFloat *components = CGColorGetComponents(color); - if (model == kCGColorSpaceModelRGB) { - qtColor.setRgbF(components[0], components[1], components[2], components[3]); - } else if (model == kCGColorSpaceModelCMYK) { - qtColor.setCmykF(components[0], components[1], components[2], components[3]); - } else if (model == kCGColorSpaceModelMonochrome) { - qtColor.setRgbF(components[0], components[0], components[0], components[1]); - } else { - // Colorspace we can't deal with. - qWarning("Qt: qt_mac_toQColor: cannot convert from colorspace model: %d", model); - Q_ASSERT(false); - } - return qtColor; -} - -QBrush qt_mac_toQBrush(CGColorRef color) -{ - QBrush qtBrush; - CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color)); - if (model == kCGColorSpaceModelPattern) { - // Colorspace we can't deal with; the color is drawn directly using a callback. - qWarning("Qt: qt_mac_toQBrush: cannot convert from colorspace model: %d", model); - Q_ASSERT(false); - } else { - qtBrush.setStyle(Qt::SolidPattern); - qtBrush.setColor(qt_mac_toQColor(color)); - } - return qtBrush; -} - -static bool qt_mac_isSystemColorOrInstance(const NSColor *color, NSString *colorNameComponent, NSString *className) -{ - // We specifically do not want isKindOfClass: here - if ([color.className isEqualToString:className]) // NSPatternColorSpace - return true; - if ([color.catalogNameComponent isEqualToString:@"System"] && - [color.colorNameComponent isEqualToString:colorNameComponent] && - [color.colorSpaceName isEqualToString:NSNamedColorSpace]) - return true; - return false; -} - -QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup) -{ - QBrush qtBrush; - - // QTBUG-49773: This calls NSDrawMenuItemBackground to render a 1 by n gradient; could use HITheme - if ([color.className isEqualToString:@"NSMenuItemHighlightColor"]) { - qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMenuItemHighlightColor"); - return qtBrush; - } - - // Not a catalog color or a manifestation of System.windowBackgroundColor; - // only retrieved from NSWindow.backgroundColor directly - if ([color.className isEqualToString:@"NSMetalPatternColor"]) { - // NSTexturedBackgroundWindowMask, could theoretically handle this without private API by - // creating a window with the appropriate properties and then calling NSWindow.backgroundColor.patternImage, - // which returns a texture sized 1 by (window height, including frame), backed by a CGPattern - // which follows the window key state... probably need to allow QBrush to store a function pointer - // like CGPattern does - qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMetalPatternColor"); - return qtBrush; - } - - // No public API to get these colors/stops; - // both accurately obtained through runtime object inspection on OS X 10.11 - // (the NSColor object has NSGradient i-vars for both color groups) - if (qt_mac_isSystemColorOrInstance(color, @"_sourceListBackgroundColor", @"NSSourceListBackgroundColor")) { - QLinearGradient gradient; - if (colorGroup == QPalette::Active) { - gradient.setColorAt(0, QColor(233, 237, 242)); - gradient.setColorAt(0.5, QColor(225, 229, 235)); - gradient.setColorAt(1, QColor(209, 216, 224)); - } else { - gradient.setColorAt(0, QColor(248, 248, 248)); - gradient.setColorAt(0.5, QColor(240, 240, 240)); - gradient.setColorAt(1, QColor(235, 235, 235)); - } - return QBrush(gradient); - } - - // A couple colors are special... they are actually instances of NSGradientPatternColor, which - // override set/setFill/setStroke to instead initialize an internal color - // ([NSColor colorWithCalibratedWhite:0.909804 alpha:1.000000]) while still returning the - // ruled lines pattern image (from OS X 10.4) to the user from -[NSColor patternImage] - // (and providing no public API to get the underlying color without this insanity) - if (qt_mac_isSystemColorOrInstance(color, @"controlColor", @"NSGradientPatternColor") || - qt_mac_isSystemColorOrInstance(color, @"windowBackgroundColor", @"NSGradientPatternColor")) { - static QColor newColor; - if (!newColor.isValid()) { -#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { - newColor = qt_mac_toQColor(color.CGColor); - } else -#endif - { - NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil - pixelsWide:1 - pixelsHigh:1 - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bytesPerRow:4 - bitsPerPixel:32]; - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep]]; - NSEraseRect(NSMakeRect(0, 0, 1, 1)); - [color drawSwatchInRect:NSMakeRect(0, 0, 1, 1)]; - [NSGraphicsContext restoreGraphicsState]; - NSUInteger pixel[4]; - [offscreenRep getPixel:pixel atX:0 y:0]; - [offscreenRep release]; - newColor = QColor(pixel[0], pixel[1], pixel[2], pixel[3]); - } - } - - qtBrush.setStyle(Qt::SolidPattern); - qtBrush.setColor(newColor); - return qtBrush; - } - - if (NSColor *patternColor = [color colorUsingColorSpaceName:NSPatternColorSpace]) { - NSImage *patternImage = patternColor.patternImage; - const QSizeF sz(patternImage.size.width, patternImage.size.height); - qtBrush.setTexture(qt_mac_toQPixmap(patternImage, sz)); // QTBUG-49774 - } else { - qtBrush.setStyle(Qt::SolidPattern); - qtBrush.setColor(qt_mac_toQColor(color)); - } - return qtBrush; -} - struct dndenum_mapper { NSDragOperation mac_code; @@ -495,97 +192,6 @@ void qt_mac_transformProccessToForegroundApplication() [[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular]; } } -static CGColorSpaceRef m_genericColorSpace = 0; -static QHash<CGDirectDisplayID, CGColorSpaceRef> m_displayColorSpaceHash; -static bool m_postRoutineRegistered = false; - -CGColorSpaceRef qt_mac_genericColorSpace() -{ -#if 0 - if (!m_genericColorSpace) { - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - } else - { - m_genericColorSpace = CGColorSpaceCreateDeviceRGB(); - } - if (!m_postRoutineRegistered) { - m_postRoutineRegistered = true; - qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces); - } - } - return m_genericColorSpace; -#else - // Just return the main display colorspace for the moment. - return qt_mac_displayColorSpace(0); -#endif -} - -/* - Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc. - to support multiple displays correctly. -*/ -CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget) -{ - CGColorSpaceRef colorSpace; - - CGDirectDisplayID displayID; - if (widget == 0) { - displayID = CGMainDisplayID(); - } else { - displayID = CGMainDisplayID(); - /* - ### get correct display - const QRect &qrect = widget->window()->geometry(); - CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height()); - CGDisplayCount throwAway; - CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway); - if (dErr != kCGErrorSuccess) - return macDisplayColorSpace(0); // fall back on main display - */ - } - if ((colorSpace = m_displayColorSpaceHash.value(displayID))) - return colorSpace; - - colorSpace = CGDisplayCopyColorSpace(displayID); - if (colorSpace == 0) - colorSpace = CGColorSpaceCreateDeviceRGB(); - - m_displayColorSpaceHash.insert(displayID, colorSpace); - if (!m_postRoutineRegistered) { - m_postRoutineRegistered = true; - void qt_mac_cleanUpMacColorSpaces(); - qAddPostRoutine(qt_mac_cleanUpMacColorSpaces); - } - return colorSpace; -} - -void qt_mac_cleanUpMacColorSpaces() -{ - if (m_genericColorSpace) { - CFRelease(m_genericColorSpace); - m_genericColorSpace = 0; - } - QHash<CGDirectDisplayID, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin(); - while (it != m_displayColorSpaceHash.constEnd()) { - if (it.value()) - CFRelease(it.value()); - ++it; - } - m_displayColorSpaceHash.clear(); -} - -CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice) -{ -#ifdef QT_NO_WIDGETS - Q_UNUSED(paintDevice) - return qt_mac_displayColorSpace(0); -#else - bool isWidget = (paintDevice->devType() == QInternal::Widget); - return qt_mac_displayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice): 0); -#endif - -} QString qt_mac_applicationName() { @@ -650,28 +256,6 @@ NSRect qt_mac_flipRect(const QRect &rect) return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height()); } -OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage) -{ - // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev) - OSStatus err = noErr; - - require_action(inContext != NULL, InvalidContext, err = paramErr); - require_action(inBounds != NULL, InvalidBounds, err = paramErr); - require_action(inImage != NULL, InvalidImage, err = paramErr); - - CGContextSaveGState( inContext ); - CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds)); - CGContextScaleCTM(inContext, 1, -1); - - CGContextDrawImage(inContext, *inBounds, inImage); - - CGContextRestoreGState(inContext); -InvalidImage: -InvalidBounds: -InvalidContext: - return err; -} - Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) { if (buttonNum == 0) @@ -687,146 +271,9 @@ Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) return Qt::NoButton; } -bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) { - OSStatus err; - AEDesc scriptTextDesc; - ComponentInstance theComponent = 0; - OSAID scriptID = kOSANullScript, resultID = kOSANullScript; - - // set up locals to a known state - AECreateDesc(typeNull, 0, 0, &scriptTextDesc); - scriptID = kOSANullScript; - resultID = kOSANullScript; - - // open the scripting component - theComponent = OpenDefaultComponent(kOSAComponentType, typeAppleScript); - if (!theComponent) { - err = paramErr; - goto bail; - } - - // put the script text into an aedesc - err = AECreateDesc(typeUTF8Text, script, script_len, &scriptTextDesc); - if (err != noErr) - goto bail; - - // compile the script - err = OSACompile(theComponent, &scriptTextDesc, kOSAModeNull, &scriptID); - if (err != noErr) - goto bail; - - // run the script - err = OSAExecute(theComponent, scriptID, kOSANullScript, kOSAModeNull, &resultID); - - // collect the results - if any - if (ret) { - AECreateDesc(typeNull, 0, 0, ret); - if (err == errOSAScriptError) - OSAScriptError(theComponent, kOSAErrorMessage, typeChar, ret); - else if (err == noErr && resultID != kOSANullScript) - OSADisplay(theComponent, resultID, typeChar, kOSAModeNull, ret); - } -bail: - AEDisposeDesc(&scriptTextDesc); - if (scriptID != kOSANullScript) - OSADispose(theComponent, scriptID); - if (resultID != kOSANullScript) - OSADispose(theComponent, resultID); - if (theComponent) - CloseComponent(theComponent); - return err == noErr; -} - -bool qt_mac_execute_apple_script(const char *script, AEDesc *ret) -{ - return qt_mac_execute_apple_script(script, qstrlen(script), ret); -} - -bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret) -{ - const QByteArray l = script.toUtf8(); return qt_mac_execute_apple_script(l.constData(), l.size(), ret); -} - QString qt_mac_removeAmpersandEscapes(QString s) { return QPlatformTheme::removeMnemonics(s).trimmed(); } -/*! \internal - - Returns the CoreGraphics CGContextRef of the paint device. 0 is - returned if it can't be obtained. It is the caller's responsibility to - CGContextRelease the context when finished using it. - - \warning This function is only available on \macos. - \warning This function is duplicated in qmacstyle_mac.mm - */ -CGContextRef qt_mac_cg_context(QPaintDevice *pdev) -{ - // In Qt 5, QWidget and QPixmap (and QImage) paint devices are all QImages under the hood. - QImage *image = 0; - if (pdev->devType() == QInternal::Image) { - image = static_cast<QImage *>(pdev); - } else if (pdev->devType() == QInternal::Pixmap) { - - const QPixmap *pm = static_cast<const QPixmap*>(pdev); - QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data(); - if (data && data->classId() == QPlatformPixmap::RasterClass) { - image = data->buffer(); - } else { - qDebug("qt_mac_cg_context: Unsupported pixmap class"); - } - } else if (pdev->devType() == QInternal::Widget) { - // TODO test: image = static_cast<QImage *>(static_cast<const QWidget *>(pdev)->backingStore()->paintDevice()); - qDebug("qt_mac_cg_context: not implemented: Widget class"); - } - - if (!image) - return 0; // Context type not supported. - - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev); - uint flags = kCGImageAlphaPremultipliedFirst; - flags |= kCGBitmapByteOrder32Host; - CGContextRef ret = 0; - ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - CGContextTranslateCTM(ret, 0, image->height()); - CGContextScaleCTM(ret, 1, -1); - return ret; -} - -QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size) -{ - const NSSize pixmapSize = NSMakeSize(size.width(), size.height()); - QPixmap pixmap(pixmapSize.width, pixmapSize.height); - pixmap.fill(Qt::transparent); - [image setSize:pixmapSize]; - const NSRect iconRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height); - QMacCGContext ctx(&pixmap); - if (!ctx) - return QPixmap(); - NSGraphicsContext *gc = [NSGraphicsContext qt_graphicsContextWithCGContext:ctx flipped:YES]; - if (!gc) - return QPixmap(); - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:gc]; - [image drawInRect:iconRect fromRect:iconRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil]; - [NSGraphicsContext restoreGraphicsState]; - return pixmap; -} - -QImage qt_mac_toQImage(CGImageRef image) -{ - const size_t w = CGImageGetWidth(image), - h = CGImageGetHeight(image); - QImage ret(w, h, QImage::Format_ARGB32_Premultiplied); - ret.fill(Qt::transparent); - CGRect rect = CGRectMake(0, 0, w, h); - CGContextRef ctx = qt_mac_cg_context(&ret); - qt_mac_drawCGImage(ctx, &rect, image); - CGContextRelease(ctx); - return ret; -} - - QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 9b0b5959a4..85ea2d8ba9 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -130,7 +130,9 @@ public: #ifndef QT_NO_ACCESSIBILITY QCocoaAccessibility *accessibility() const Q_DECL_OVERRIDE; #endif +#ifndef QT_NO_CLIPBOARD QCocoaClipboard *clipboard() const Q_DECL_OVERRIDE; +#endif QCocoaDrag *drag() const Q_DECL_OVERRIDE; QStringList themeNames() const Q_DECL_OVERRIDE; @@ -169,7 +171,9 @@ private: #endif QScopedPointer<QPlatformTheme> mPlatformTheme; QList<QCocoaScreen *> mScreens; +#ifndef QT_NO_CLIPBOARD QCocoaClipboard *mCocoaClipboard; +#endif QScopedPointer<QCocoaDrag> mCocoaDrag; QScopedPointer<QCocoaNativeInterface> mNativeInterface; QScopedPointer<QCocoaServices> mServices; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index f02dad675e..f3f720654e 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -58,6 +58,8 @@ #include <qpa/qplatforminputcontextfactory_p.h> #include <QtCore/qcoreapplication.h> +#include <QtGui/private/qcoregraphics_p.h> + #include <IOKit/graphics/IOGraphicsLib.h> static void initResources() @@ -199,8 +201,6 @@ QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const return window; } -extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); - QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const { // TODO window should be handled @@ -251,9 +251,8 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height QPixmap pix(w, h); pix.fill(Qt::transparent); CGRect rect = CGRectMake(0, 0, w, h); - CGContextRef ctx = qt_mac_cg_context(&pix); + QMacCGContext ctx(&pix); qt_mac_drawCGImage(ctx, &rect, image); - CGContextRelease(ctx); QPainter painter(&windowPixmap); painter.drawPixmap(0, 0, pix); @@ -283,7 +282,9 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) #ifndef QT_NO_ACCESSIBILITY , mAccessibility(new QCocoaAccessibility) #endif +#ifndef QT_NO_CLIPBOARD , mCocoaClipboard(new QCocoaClipboard) +#endif , mCocoaDrag(new QCocoaDrag) , mNativeInterface(new QCocoaNativeInterface) , mServices(new QCocoaServices) @@ -331,10 +332,8 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) [cocoaApplication setDelegate:newDelegate]; // Load the application menu. This menu contains Preferences, Hide, Quit. - QCocoaMenuLoader *qtMenuLoader = [[QCocoaMenuLoader alloc] init]; - qt_mac_loadMenuNib(qtMenuLoader); + QCocoaMenuLoader *qtMenuLoader = [QCocoaMenuLoader sharedMenuLoader]; [cocoaApplication setMenu:[qtMenuLoader menu]]; - [newDelegate setMenuLoader:qtMenuLoader]; } // The presentation options such as whether or not the dock and/or menu bar is @@ -368,11 +367,13 @@ QCocoaIntegration::~QCocoaIntegration() [[NSApplication sharedApplication] setDelegate: 0]; } +#ifndef QT_NO_CLIPBOARD // Delete the clipboard integration and destroy mime type converters. // Deleting the clipboard integration flushes promised pastes using // the mime converters - the ordering here is important. delete mCocoaClipboard; QMacInternalPasteboardMime::destroyMimeTypes(); +#endif // Delete screens in reverse order to avoid crash in case of multiple screens while (!mScreens.isEmpty()) { @@ -533,10 +534,12 @@ QCocoaAccessibility *QCocoaIntegration::accessibility() const } #endif +#ifndef QT_NO_CLIPBOARD QCocoaClipboard *QCocoaIntegration::clipboard() const { return mCocoaClipboard; } +#endif QCocoaDrag *QCocoaIntegration::drag() const { diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.h b/src/plugins/platforms/cocoa/qcocoakeymapper.h index 93ebc5b9dc..4ba615efeb 100644 --- a/src/plugins/platforms/cocoa/qcocoakeymapper.h +++ b/src/plugins/platforms/cocoa/qcocoakeymapper.h @@ -40,7 +40,7 @@ #ifndef QCOCOAKEYMAPPER_H #define QCOCOAKEYMAPPER_H -#include <qcocoahelpers.h> +#include "qcocoahelpers.h" #include <AppKit/AppKit.h> #include <Carbon/Carbon.h> diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 40d593cf0f..4260b17772 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -74,11 +74,6 @@ NSString *qt_mac_removePrivateUnicode(NSString* string) return string; } -static inline QCocoaMenuLoader *getMenuLoader() -{ - return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)]; -} - QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(QCocoaMenuDelegate) : NSObject <NSMenuDelegate> { @@ -414,7 +409,7 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) } bool wasMerged = cocoaItem->isMerged(); - NSMenu *oldMenu = wasMerged ? [getMenuLoader() applicationMenu] : m_nativeMenu; + NSMenu *oldMenu = wasMerged ? [[QCocoaMenuLoader sharedMenuLoader] applicationMenu] : m_nativeMenu; NSMenuItem *oldItem = [oldMenu itemWithTag:(NSInteger) cocoaItem]; if (cocoaItem->sync() != oldItem) { diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 1c50c3b032..26af0d3f63 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -52,11 +52,6 @@ QT_BEGIN_NAMESPACE static QList<QCocoaMenuBar*> static_menubars; -static inline QCocoaMenuLoader *getMenuLoader() -{ - return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)]; -} - QCocoaMenuBar::QCocoaMenuBar() : m_window(0) { @@ -330,7 +325,7 @@ void QCocoaMenuBar::updateMenuBarImmediately() menu->propagateEnabledState(!disableForModal); } - QCocoaMenuLoader *loader = getMenuLoader(); + QCocoaMenuLoader *loader = [QCocoaMenuLoader sharedMenuLoader]; [loader ensureAppMenuInMenu:mb->nsMenu()]; NSMutableSet *mergedItems = [[NSMutableSet setWithCapacity:0] retain]; diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index d63f21f598..23f788687c 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -90,7 +90,9 @@ public: void setIsSeparator(bool isSeparator) Q_DECL_OVERRIDE; void setFont(const QFont &font) Q_DECL_OVERRIDE; void setRole(MenuRole role) Q_DECL_OVERRIDE; +#ifndef QT_NO_SHORTCUT void setShortcut(const QKeySequence& shortcut) Q_DECL_OVERRIDE; +#endif void setCheckable(bool checkable) Q_DECL_OVERRIDE { Q_UNUSED(checkable) } void setChecked(bool isChecked) Q_DECL_OVERRIDE; void setEnabled(bool isEnabled) Q_DECL_OVERRIDE; @@ -124,7 +126,9 @@ private: QFont m_font; MenuRole m_role; MenuRole m_detectedRole; +#ifndef QT_NO_SHORTCUT QKeySequence m_shortcut; +#endif quintptr m_tag; int m_iconSize; bool m_textSynced:1; diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 3979d7169a..ea094c86ee 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -48,17 +48,12 @@ #include "qt_mac_p.h" #include "qcocoaapplication.h" // for custom application category #include "qcocoamenuloader.h" +#include <QtGui/private/qcoregraphics_p.h> #include <QtCore/QDebug> QT_BEGIN_NAMESPACE -static inline QCocoaMenuLoader *getMenuLoader() -{ - return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)]; -} - - static quint32 constructModifierMask(quint32 accel_key) { quint32 ret = 0; @@ -74,6 +69,7 @@ static quint32 constructModifierMask(quint32 accel_key) return ret; } +#ifndef QT_NO_SHORTCUT // return an autoreleased string given a QKeySequence (currently only looks at the first one). NSString *keySequenceToKeyEqivalent(const QKeySequence &accel) { @@ -92,6 +88,7 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel) { return constructModifierMask(accel[0]); } +#endif QCocoaMenuItem::QCocoaMenuItem() : m_native(NULL), @@ -189,10 +186,12 @@ void QCocoaMenuItem::setRole(MenuRole role) m_role = role; } +#ifndef QT_NO_SHORTCUT void QCocoaMenuItem::setShortcut(const QKeySequence& shortcut) { m_shortcut = shortcut; } +#endif void QCocoaMenuItem::setChecked(bool isChecked) { @@ -234,7 +233,7 @@ NSMenuItem *QCocoaMenuItem::sync() if ((m_role != NoRole && !m_textSynced) || m_merged) { NSMenuItem *mergeItem = nil; - QCocoaMenuLoader *loader = getMenuLoader(); + QCocoaMenuLoader *loader = [QCocoaMenuLoader sharedMenuLoader]; switch (m_role) { case ApplicationSpecificRole: mergeItem = [loader appSpecificMenuItem:reinterpret_cast<NSInteger>(this)]; @@ -320,11 +319,13 @@ NSMenuItem *QCocoaMenuItem::sync() [m_native setView:m_itemView]; QString text = mergeText(); +#ifndef QT_NO_SHORTCUT QKeySequence accel = mergeAccel(); // Show multiple key sequences as part of the menu text. if (accel.count() > 1) text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")"); +#endif QString finalString = QPlatformTheme::removeMnemonics(text); bool useAttributedTitle = false; @@ -346,10 +347,13 @@ NSMenuItem *QCocoaMenuItem::sync() [m_native setTitle: QCFString::toNSString(finalString)]; } +#ifndef QT_NO_SHORTCUT if (accel.count() == 1) { [m_native setKeyEquivalent:keySequenceToKeyEqivalent(accel)]; [m_native setKeyEquivalentModifierMask:keySequenceModifierMask(accel)]; - } else { + } else +#endif + { [m_native setKeyEquivalent:@""]; [m_native setKeyEquivalentModifierMask:NSCommandKeyMask]; } @@ -372,7 +376,7 @@ QT_END_NAMESPACE QString QCocoaMenuItem::mergeText() { - QCocoaMenuLoader *loader = getMenuLoader(); + QCocoaMenuLoader *loader = [QCocoaMenuLoader sharedMenuLoader]; if (m_native == [loader aboutMenuItem]) { return qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()); } else if (m_native== [loader aboutQtMenuItem]) { @@ -390,9 +394,10 @@ QString QCocoaMenuItem::mergeText() return m_text; } +#ifndef QT_NO_SHORTCUT QKeySequence QCocoaMenuItem::mergeAccel() { - QCocoaMenuLoader *loader = getMenuLoader(); + QCocoaMenuLoader *loader = [QCocoaMenuLoader sharedMenuLoader]; if (m_native == [loader preferencesMenuItem]) return QKeySequence(QKeySequence::Preferences); else if (m_native == [loader quitMenuItem]) @@ -402,6 +407,7 @@ QKeySequence QCocoaMenuItem::mergeAccel() return m_shortcut; } +#endif void QCocoaMenuItem::syncMerged() { diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h index 6f58b2f24c..95f347646c 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.h +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h @@ -68,6 +68,8 @@ NSMenuItem *hideAllOthersItem; NSMenuItem *showAllItem; } ++ (instancetype)sharedMenuLoader; +- (instancetype)init; - (void)ensureAppMenuInMenu:(NSMenu *)menu; - (void)removeActionsFromAppMenu; - (NSMenu *)applicationMenu; @@ -92,10 +94,4 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuLoader); -QT_BEGIN_NAMESPACE - -void qt_mac_loadMenuNib(QCocoaMenuLoader *qtMenuLoader); - -QT_END_NAMESPACE - #endif // QCOCOAMENULOADER_P_H diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index e440a9080c..22e90f8dc8 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -55,86 +55,127 @@ QT_FORWARD_DECLARE_CLASS(QCFString) QT_FORWARD_DECLARE_CLASS(QString) +@implementation QCocoaMenuLoader -QT_BEGIN_NAMESPACE - -/* - Loads and instantiates the main app menu from the menu nib file(s). - - The main app menu contains the Quit, Hide About, Preferences entries, and - The reason for having the nib file is that those can not be created - programmatically. To ease deployment the nib files are stored in Qt resources - and written to QDir::temp() before loading. (Earlier Qt versions used - to require having the nib file in the Qt GUI framework.) -*/ -void qt_mac_loadMenuNib(QCocoaMenuLoader *qtMenuLoader) ++ (instancetype)sharedMenuLoader { - // Create qt_menu.nib dir in temp. - QDir temp = QDir::temp(); - temp.mkdir("qt_menu.nib"); - QString nibDir = temp.canonicalPath() + QLatin1String("/") + QLatin1String("qt_menu.nib/"); - if (!QDir(nibDir).exists()) { - qWarning("qt_mac_loadMenuNib: could not create nib directory in temp"); - return; - } - - // Copy nib files from resources to temp. - QDir nibResource(":/qt-project.org/mac/qt_menu.nib/"); - if (!nibResource.exists()) { - qWarning("qt_mac_loadMenuNib: could not load nib from resources"); - return; - } - foreach (const QFileInfo &file, nibResource.entryInfoList()) { - QFileInfo destinationFile(nibDir + QLatin1String("/") + file.fileName()); - if (destinationFile.exists() && destinationFile.size() != file.size()) - QFile::remove(destinationFile.absoluteFilePath()); + static QCocoaMenuLoader *shared = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + shared = [[self alloc] init]; + }); + return shared; +} - QFile::copy(file.absoluteFilePath(), destinationFile.absoluteFilePath()); +- (instancetype)init +{ + if ((self = [super init])) { + NSString *appName = qt_mac_applicationName().toNSString(); + + // Menubar as menu. Title as set in the NIB file + theMenu = [[NSMenu alloc] initWithTitle:@"Main Menu"]; + + // Application menu. Since 10.6, the first menu + // is always identified as the application menu. + NSMenuItem *appItem = [[[NSMenuItem alloc] init] autorelease]; + appItem.title = appName; + [theMenu addItem:appItem]; + appMenu = [[NSMenu alloc] initWithTitle:appName]; + appItem.submenu = appMenu; + + // About Application + aboutItem = [[NSMenuItem alloc] initWithTitle:[@"About " stringByAppendingString:appName] + action:@selector(orderFrontStandardAboutPanel:) + keyEquivalent:@""]; + aboutItem.target = self; + // Disable until a QAction is associated + aboutItem.enabled = NO; + aboutItem.hidden = YES; + [appMenu addItem:aboutItem]; + + // About Qt (shameless self-promotion) + aboutQtItem = [[NSMenuItem alloc] init]; + aboutQtItem.title = @"About Qt"; + // Disable until a QAction is associated + aboutQtItem.enabled = NO; + aboutQtItem.hidden = YES; + [appMenu addItem:aboutQtItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Preferences + preferencesItem = [[NSMenuItem alloc] initWithTitle:@"Preferences…" + action:@selector(qtDispatcherToQPAMenuItem:) + keyEquivalent:@","]; + preferencesItem.target = self; + // Disable until a QAction is associated + preferencesItem.enabled = NO; + preferencesItem.hidden = YES; + [appMenu addItem:preferencesItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Services item and menu + servicesItem = [[NSMenuItem alloc] init]; + servicesItem.title = @"Services"; + NSMenu *servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"] autorelease]; + servicesItem.submenu = servicesMenu; + [NSApplication sharedApplication].servicesMenu = servicesMenu; + [appMenu addItem:servicesItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Hide Application + hideItem = [[NSMenuItem alloc] initWithTitle:[@"Hide " stringByAppendingString:appName] + action:@selector(hide:) + keyEquivalent:@"h"]; + hideItem.target = self; + [appMenu addItem:hideItem]; + + // Hide Others + hideAllOthersItem = [[NSMenuItem alloc] initWithTitle:@"Hide Others" + action:@selector(hideOtherApplications:) + keyEquivalent:@"h"]; + hideAllOthersItem.target = self; + hideAllOthersItem.keyEquivalentModifierMask = NSCommandKeyMask | NSAlternateKeyMask; + [appMenu addItem:hideAllOthersItem]; + + // Show All + showAllItem = [[NSMenuItem alloc] initWithTitle:@"Show All" + action:@selector(unhideAllApplications:) + keyEquivalent:@""]; + showAllItem.target = self; + [appMenu addItem:showAllItem]; + + [appMenu addItem:[NSMenuItem separatorItem]]; + + // Quit Application + quitItem = [[NSMenuItem alloc] initWithTitle:[@"Quit " stringByAppendingString:appName] + action:@selector(terminate:) + keyEquivalent:@"q"]; + quitItem.target = self; + [appMenu addItem:quitItem]; } - // Load and instantiate nib file from temp - NSURL *nibUrl = [NSURL fileURLWithPath : QCFString::toNSString(nibDir)]; - NSNib *nib = [[NSNib alloc] initWithContentsOfURL : nibUrl]; - [nib autorelease]; - if(!nib) { - qWarning("qt_mac_loadMenuNib: could not load nib from temp"); - return; - } - bool ok = [nib instantiateNibWithOwner : qtMenuLoader topLevelObjects : nil]; - if (!ok) { - qWarning("qt_mac_loadMenuNib: could not instantiate nib"); - } + return self; } -QT_END_NAMESPACE +- (void)dealloc +{ + [theMenu release]; + [appMenu release]; + [aboutItem release]; + [aboutQtItem release]; + [preferencesItem release]; + [servicesItem release]; + [hideItem release]; + [hideAllOthersItem release]; + [showAllItem release]; + [quitItem release]; -@implementation QCocoaMenuLoader + [lastAppSpecificItem release]; -- (void)awakeFromNib -{ - servicesItem = [[appMenu itemWithTitle:@"Services"] retain]; - hideAllOthersItem = [[appMenu itemWithTitle:@"Hide Others"] retain]; - showAllItem = [[appMenu itemWithTitle:@"Show All"] retain]; - - // Get the names in the nib to match the app name set by Qt. - const NSString *appName = qt_mac_applicationName().toNSString(); - [quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication" - withString:const_cast<NSString *>(appName)]]; - [hideItem setTitle:[[hideItem title] stringByReplacingOccurrencesOfString:@"NewApplication" - withString:const_cast<NSString *>(appName)]]; - [aboutItem setTitle:[[aboutItem title] stringByReplacingOccurrencesOfString:@"NewApplication" - withString:const_cast<NSString *>(appName)]]; - // Disable the items that don't do anything. If someone associates a QAction with them - // They should get synced back in. - [preferencesItem setEnabled:NO]; - [preferencesItem setHidden:YES]; - - // should set this in the NIB - [preferencesItem setTarget: self]; - [preferencesItem setAction: @selector(qtDispatcherToQPAMenuItem:)]; - - [aboutItem setEnabled:NO]; - [aboutItem setHidden:YES]; + [super dealloc]; } - (void)ensureAppMenuInMenu:(NSMenu *)menu @@ -179,18 +220,6 @@ QT_END_NAMESPACE [item setTag:0]; } -- (void)dealloc -{ - [servicesItem release]; - [hideAllOthersItem release]; - [showAllItem release]; - - [lastAppSpecificItem release]; - [theMenu release]; - [appMenu release]; - [super dealloc]; -} - - (NSMenu *)menu { return [[theMenu retain] autorelease]; diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm index e7a3aab845..c109eb7bf4 100644 --- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm +++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm @@ -40,6 +40,7 @@ #include "qcocoamimetypes.h" #include <QtPlatformSupport/private/qmacmime_p.h> #include "qcocoahelpers.h" +#include <QtGui/private/qcoregraphics_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index 8562246817..3ff37a8463 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -64,6 +64,8 @@ #include <qpa/qplatformprintersupport.h> #endif +#include <QtGui/private/qcoregraphics_p.h> + #include <QtPlatformHeaders/qcocoawindowfunctions.h> #include <AppKit/AppKit.h> diff --git a/src/plugins/platforms/cocoa/qcocoaresources.qrc b/src/plugins/platforms/cocoa/qcocoaresources.qrc index 9e0640db7d..4255bfba9d 100644 --- a/src/plugins/platforms/cocoa/qcocoaresources.qrc +++ b/src/plugins/platforms/cocoa/qcocoaresources.qrc @@ -9,9 +9,4 @@ <qresource prefix="/qt-project.org/mac/style"> <file>images/leopard-unified-toolbar-on.png</file> </qresource> -<qresource prefix="/qt-project.org/mac/"> -<file>qt_menu.nib/classes.nib</file> -<file>qt_menu.nib/info.nib</file> -<file>qt_menu.nib/keyedobjects.nib</file> -</qresource> </RCC> diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index be5fa61b8b..9ddad7fc7a 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -43,6 +43,7 @@ #include <QtCore/private/qcore_mac_p.h> #include <QtGui/qfont.h> +#include <QtGui/private/qcoregraphics_p.h> #include <Carbon/Carbon.h> diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 0cbdc5d9c8..9a543e893e 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -75,6 +75,9 @@ #define QT_MAC_SYSTEMTRAY_USE_GROWL #include "qcocoasystemtrayicon.h" + +#ifndef QT_NO_SYSTEMTRAYICON + #include <qtemporaryfile.h> #include <qimagewriter.h> #include <qdebug.h> @@ -83,6 +86,7 @@ #include "qt_mac_p.h" #include "qcocoahelpers.h" +#include <QtGui/private/qcoregraphics_p.h> #import <AppKit/AppKit.h> @@ -91,11 +95,8 @@ QT_USE_NAMESPACE @class QT_MANGLE_NAMESPACE(QNSMenu); @class QT_MANGLE_NAMESPACE(QNSImageView); -@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 - <NSUserNotificationCenterDelegate> -#endif - { +@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject <NSUserNotificationCenterDelegate> +{ @public QCocoaSystemTrayIcon *systray; NSStatusItem *item; @@ -109,11 +110,8 @@ QT_USE_NAMESPACE -(QRectF)geometry; - (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton; - (void)doubleClickSelector:(id)sender; - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification; - (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification; -#endif @end @interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView { @@ -142,19 +140,11 @@ class QSystemTrayIconSys public: QSystemTrayIconSys(QCocoaSystemTrayIcon *sys) { item = [[QNSStatusItem alloc] initWithSysTray:sys]; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { - [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item]; - } -#endif + [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item]; } ~QSystemTrayIconSys() { [[[item item] view] setHidden: YES]; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { - [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil]; - } -#endif + [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil]; [item release]; } QNSStatusItem *item; @@ -296,71 +286,15 @@ bool QCocoaSystemTrayIcon::supportsMessages() const void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &message, const QIcon& icon, MessageIcon, int) { + Q_UNUSED(icon); if (!m_sys) return; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { - NSUserNotification *notification = [[NSUserNotification alloc] init]; - notification.title = [NSString stringWithUTF8String:title.toUtf8().data()]; - notification.informativeText = [NSString stringWithUTF8String:message.toUtf8().data()]; - - [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; + NSUserNotification *notification = [[NSUserNotification alloc] init]; + notification.title = [NSString stringWithUTF8String:title.toUtf8().data()]; + notification.informativeText = [NSString stringWithUTF8String:message.toUtf8().data()]; - return; - } -#endif - -#ifdef QT_MAC_SYSTEMTRAY_USE_GROWL - // Make sure that we have Growl installed on the machine we are running on. - QCFType<CFURLRef> cfurl; - OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, - CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl); - if (status == kLSApplicationNotFoundErr) - return; - QCFType<CFBundleRef> bundle = CFBundleCreate(0, cfurl); - - if (CFStringCompare(CFBundleGetIdentifier(bundle), CFSTR("com.Growl.GrowlHelperApp"), - kCFCompareCaseInsensitive | kCFCompareBackwards) != kCFCompareEqualTo) - return; - QPixmap notificationIconPixmap = icon.pixmap(32, 32); - QTemporaryFile notificationIconFile; - QString notificationType(QLatin1String("Notification")), notificationIcon, notificationApp(qt_mac_applicationName()); - if (notificationApp.isEmpty()) - notificationApp = QLatin1String("Application"); - if (!notificationIconPixmap.isNull() && notificationIconFile.open()) { - QImageWriter writer(¬ificationIconFile, "PNG"); - if (writer.write(notificationIconPixmap.toImage())) - notificationIcon = QLatin1String("image from location \"file://") + notificationIconFile.fileName() + QLatin1String("\""); - } - const QString script(QLatin1String( - "tell application \"System Events\"\n" - "set isRunning to (count of (every process whose bundle identifier is \"com.Growl.GrowlHelperApp\")) > 0\n" - "end tell\n" - "if isRunning\n" - "tell application id \"com.Growl.GrowlHelperApp\"\n" - "-- Make a list of all the notification types (all)\n" - "set the allNotificationsList to {\"") + notificationType + QLatin1String("\"}\n" - - "-- Make a list of the notifications (enabled)\n" - "set the enabledNotificationsList to {\"") + notificationType + QLatin1String("\"}\n" - - "-- Register our script with growl.\n" - "register as application \"") + notificationApp + QLatin1String("\" all notifications allNotificationsList default notifications enabledNotificationsList\n" - - "-- Send a Notification...\n") + - QLatin1String("notify with name \"") + notificationType + - QLatin1String("\" title \"") + title + - QLatin1String("\" description \"") + message + - QLatin1String("\" application name \"") + notificationApp + - QLatin1String("\" ") + notificationIcon + - QLatin1String("\nend tell\nend if")); - qt_mac_execute_apple_script(script, 0); -#else - Q_UNUSED(icon); - Q_UNUSED(title); - Q_UNUSED(message); -#endif + [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; } QT_END_NAMESPACE @@ -499,7 +433,6 @@ QT_END_NAMESPACE emit systray->activated(QPlatformSystemTrayIcon::DoubleClick); } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification { Q_UNUSED(center); Q_UNUSED(notification); @@ -511,7 +444,6 @@ QT_END_NAMESPACE Q_UNUSED(notification); emit systray->messageClicked(); } -#endif @end @@ -536,3 +468,5 @@ private: return qmenu; } @end + +#endif // QT_NO_SYSTEMTRAYICON diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h index 282e527b0b..d47e620fbb 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.h +++ b/src/plugins/platforms/cocoa/qcocoatheme.h @@ -70,9 +70,7 @@ public: const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE; const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE; QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const Q_DECL_OVERRIDE; - QPixmap fileIconPixmap(const QFileInfo &fileInfo, - const QSizeF &size, - QPlatformTheme::IconOptions options = 0) const Q_DECL_OVERRIDE; + QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions options = 0) const override; QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE; QString standardButtonText(int button) const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 831f1cfcf4..d0879ed457 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -56,8 +56,10 @@ #include <QtCore/qfileinfo.h> #include <QtGui/private/qguiapplication_p.h> +#include <QtGui/private/qcoregraphics_p.h> #include <QtGui/qpainter.h> #include <QtPlatformSupport/private/qcoretextfontdatabase_p.h> +#include <QtPlatformSupport/private/qabstractfileiconengine_p.h> #include <qpa/qplatformintegration.h> #include <qpa/qplatformnativeinterface.h> @@ -136,8 +138,10 @@ bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const QPlatformDialogHelper * QCocoaTheme::createPlatformDialogHelper(DialogType dialogType) const { switch (dialogType) { +#ifndef QT_NO_FILEDIALOG case QPlatformTheme::FileDialog: return new QCocoaFileDialogHelper(); +#endif #ifndef QT_NO_COLORDIALOG case QPlatformTheme::ColorDialog: return new QCocoaColorDialogHelper(); @@ -194,7 +198,7 @@ QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height) CGRect rect = CGRectMake(0, 0, width, height); - CGContextRef ctx = qt_mac_cg_context(&ret); + QMacCGContext ctx(&ret); CGAffineTransform old_xform = CGContextGetCTM(ctx); CGContextConcatCTM(ctx, CGAffineTransformInvert(old_xform)); CGContextConcatCTM(ctx, CGAffineTransformIdentity); @@ -202,7 +206,6 @@ QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height) ::RGBColor b; b.blue = b.green = b.red = 255*255; PlotIconRefInContext(ctx, &rect, kAlignNone, kTransformNone, &b, kPlotIconRefNormalFlags, icon); - CGContextRelease(ctx); return ret; } @@ -274,16 +277,42 @@ QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const return QPlatformTheme::standardPixmap(sp, size); } -QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, - QPlatformTheme::IconOptions iconOptions) const +class QCocoaFileIconEngine : public QAbstractFileIconEngine { - Q_UNUSED(iconOptions); - QMacAutoReleasePool pool; +public: + explicit QCocoaFileIconEngine(const QFileInfo &info, + QPlatformTheme::IconOptions opts) : + QAbstractFileIconEngine(info, opts) {} + + static QList<QSize> availableIconSizes() + { + const qreal devicePixelRatio = qGuiApp->devicePixelRatio(); + const int sizes[] = { + qRound(16 * devicePixelRatio), qRound(32 * devicePixelRatio), + qRound(64 * devicePixelRatio), qRound(128 * devicePixelRatio), + qRound(256 * devicePixelRatio) + }; + return QAbstractFileIconEngine::toSizeList(sizes, sizes + sizeof(sizes) / sizeof(sizes[0])); + } + + QList<QSize> availableSizes(QIcon::Mode = QIcon::Normal, QIcon::State = QIcon::Off) const override + { return QCocoaFileIconEngine::availableIconSizes(); } + +protected: + QPixmap filePixmap(const QSize &size, QIcon::Mode, QIcon::State) override + { + QMacAutoReleasePool pool; - NSImage *iconImage = [[NSWorkspace sharedWorkspace] iconForFile:QCFString::toNSString(fileInfo.canonicalFilePath())]; - if (!iconImage) - return QPixmap(); - return qt_mac_toQPixmap(iconImage, size); + NSImage *iconImage = [[NSWorkspace sharedWorkspace] iconForFile:QCFString::toNSString(fileInfo().canonicalFilePath())]; + if (!iconImage) + return QPixmap(); + return qt_mac_toQPixmap(iconImage, size); + } +}; + +QIcon QCocoaTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const +{ + return QIcon(new QCocoaFileIconEngine(fileInfo, iconOptions)); } QVariant QCocoaTheme::themeHint(ThemeHint hint) const @@ -298,17 +327,12 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const case TabFocusBehavior: return QVariant([[NSApplication sharedApplication] isFullKeyboardAccessEnabled] ? int(Qt::TabFocusAllControls) : int(Qt::TabFocusTextControls | Qt::TabFocusListControls)); - case IconPixmapSizes: { - qreal devicePixelRatio = qGuiApp->devicePixelRatio(); - QList<int> sizes; - sizes << 16 * devicePixelRatio - << 32 * devicePixelRatio - << 64 * devicePixelRatio - << 128 * devicePixelRatio; - return QVariant::fromValue(sizes); - } + case IconPixmapSizes: + return QVariant::fromValue(QCocoaFileIconEngine::availableIconSizes()); case QPlatformTheme::PasswordMaskCharacter: return QVariant(QChar(kBulletUnicode)); + case QPlatformTheme::UiEffects: + return QVariant(int(HoverEffect)); default: break; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index d9e94735ac..b016004b23 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -219,6 +219,7 @@ public: void windowDidResize(); void windowDidEndLiveResize(); bool windowShouldClose(); + void windowWillClose(); bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const; void setSynchedWindowStateFromWindow(); @@ -275,6 +276,7 @@ protected: void syncWindowState(Qt::WindowState newState); void reinsertChildWindow(QCocoaWindow *child); void removeChildWindow(QCocoaWindow *child); + bool isNativeWindowTypeInconsistent(); // private: public: // for QNSView diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 91ce91004f..b2fd0580bc 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -52,6 +52,7 @@ #include <private/qwindow_p.h> #include <qpa/qwindowsysteminterface.h> #include <qpa/qplatformscreen.h> +#include <QtGui/private/qcoregraphics_p.h> #include <AppKit/AppKit.h> @@ -78,6 +79,14 @@ static bool isMouseEvent(NSEvent *ev) } } +static void qt_closePopups() +{ + while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) { + QWindowSystemInterface::handleCloseEvent(popup->window()); + QWindowSystemInterface::flushWindowSystemEvents(); + } +} + @implementation QNSWindowHelper @synthesize window = _window; @@ -505,7 +514,7 @@ QRect QCocoaWindow::geometry() const NSRect screenRect = [[m_contentView window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)]; NSPoint screenPoint = screenRect.origin; QPoint position = qt_mac_flipPoint(screenPoint).toPoint(); - QSize size = qt_mac_toQRect([m_contentView bounds]).size(); + QSize size = QRectF::fromCGRect([m_contentView bounds]).toRect().size(); return QRect(position, size); } @@ -652,7 +661,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()) + if (m_windowModality != window()->modality() || isNativeWindowTypeInconsistent()) recreateWindow(parent()); // Register popup windows. The Cocoa platform plugin will forward mouse events @@ -1023,9 +1032,7 @@ void QCocoaWindow::raise() } static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS"); if (raiseProcess) { - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly); + [NSApp activateIgnoringOtherApps:YES]; } } } @@ -1107,11 +1114,10 @@ void QCocoaWindow::propagateSizeHints() // sizeIncrement is observed to take values of (-1, -1) and (0, 0) for windows that should be // resizable and that have no specific size increment set. Cocoa expects (1.0, 1.0) in this case. - const QSize sizeIncrement = windowSizeIncrement(); - if (!sizeIncrement.isEmpty()) - [m_nsWindow setResizeIncrements : qt_mac_toNSSize(sizeIncrement)]; - else - [m_nsWindow setResizeIncrements : NSMakeSize(1.0, 1.0)]; + QSize sizeIncrement = windowSizeIncrement(); + if (sizeIncrement.isEmpty()) + sizeIncrement = QSize(1, 1); + [m_nsWindow setResizeIncrements:sizeIncrement.toCGSize()]; QRect rect = geometry(); QSize baseSize = windowBaseSize(); @@ -1223,10 +1229,7 @@ void QCocoaWindow::setEmbeddedInForeignView(bool embedded) void QCocoaWindow::windowWillMove() { // Close any open popups on window move - while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) { - QWindowSystemInterface::handleCloseEvent(popup->window()); - QWindowSystemInterface::flushWindowSystemEvents(); - } + qt_closePopups(); } void QCocoaWindow::windowDidMove() @@ -1270,6 +1273,13 @@ 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() { if (QWindow *w = window()) @@ -1532,6 +1542,17 @@ void QCocoaWindow::removeChildWindow(QCocoaWindow *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) diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 00d65ea7f8..02ae64a58e 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -85,7 +85,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); bool m_resendKeyEvent; bool m_scrolling; bool m_updatingDrag; - bool m_exposedOnMoveToWindow; NSEvent *m_currentlyInterpretedKeyEvent; bool m_isMenuView; QSet<quint32> m_acceptedKeyDowns; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 0566541945..22a32c7ceb 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -39,8 +39,6 @@ #include <QtCore/qglobal.h> -#include <dlfcn.h> - #include "qnsview.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" @@ -54,6 +52,7 @@ #include <QtCore/QDebug> #include <QtCore/qsysinfo.h> #include <private/qguiapplication_p.h> +#include <private/qcoregraphics_p.h> #include "qcocoabackingstore.h" #ifndef QT_NO_OPENGL #include "qcocoaglcontext.h" @@ -72,9 +71,6 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") static QTouchDevice *touchDevice = 0; -// ### HACK Remove once 10.8 is unsupported -static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; - static bool _q_dontOverrideCtrlLMB = false; @interface NSEvent (Qt_Compile_Leopard_DeviceDelta) @@ -134,10 +130,6 @@ static bool _q_dontOverrideCtrlLMB = false; + (void)initialize { - NSString **notificationNameVar = (NSString **)dlsym(RTLD_NEXT, "NSWindowDidChangeOcclusionStateNotification"); - if (notificationNameVar) - _q_NSWindowDidChangeOcclusionStateNotification = *notificationNameVar; - _q_dontOverrideCtrlLMB = qt_mac_resolveOption(false, "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); } @@ -291,18 +283,6 @@ static bool _q_dontOverrideCtrlLMB = false; - (void)viewDidMoveToWindow { m_backingStore = Q_NULLPTR; - m_isMenuView = [self.window.className isEqualToString:@"NSCarbonMenuWindow"]; - if (self.window) { - // This is the case of QWidgetAction's generated QWidget inserted in an NSMenu. - // 10.9 and newer get the NSWindowDidChangeOcclusionStateNotification - if (!_q_NSWindowDidChangeOcclusionStateNotification && m_isMenuView) { - m_exposedOnMoveToWindow = true; - m_platformWindow->exposeWindow(); - } - } else if (m_exposedOnMoveToWindow) { - m_exposedOnMoveToWindow = false; - m_platformWindow->obscureWindow(); - } } - (void)viewWillMoveToWindow:(NSWindow *)newWindow @@ -343,9 +323,9 @@ static bool _q_dontOverrideCtrlLMB = false; if (m_platformWindow->m_isNSWindowChild) { return; #if 0 - //geometry = qt_mac_toQRect([self frame]); + //geometry = QRectF::fromCGRect([self frame]).toRect(); qDebug() << "nsview updateGeometry" << m_platformWindow->window(); - QRect screenRect = qt_mac_toQRect([m_platformWindow->m_nsWindow convertRectToScreen:[self frame]]); + QRect screenRect = QRectF::fromCGRect([m_platformWindow->m_nsWindow convertRectToScreen:[self frame]]).toRect(); qDebug() << "screenRect" << screenRect; screenRect.moveTop(qt_mac_flipYCoordinate(screenRect.y() + screenRect.height())); @@ -360,10 +340,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_contentViewIsToBeEmbedded) { // embedded child window, use the frame rect ### merge with case below - geometry = qt_mac_toQRect([self bounds]); + geometry = QRectF::fromCGRect([self bounds]).toRect(); } else { // child window, use the frame rect - geometry = qt_mac_toQRect([self frame]); + geometry = QRectF::fromCGRect([self frame]).toRect(); } if (m_platformWindow->m_nsWindow && geometry == m_platformWindow->geometry()) @@ -432,7 +412,7 @@ static bool _q_dontOverrideCtrlLMB = false; // 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) { + 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); @@ -446,14 +426,7 @@ static bool _q_dontOverrideCtrlLMB = false; m_platformWindow->obscureWindow(); } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) { m_platformWindow->exposeWindow(); - } else if (_q_NSWindowDidChangeOcclusionStateNotification - && [notificationName isEqualToString:_q_NSWindowDidChangeOcclusionStateNotification]) { -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 -// ### HACK Remove the enum declaration, the warning disabling and the cast further down once 10.8 is unsupported -QT_WARNING_PUSH -QT_WARNING_DISABLE_CLANG("-Wobjc-method-access") - enum { NSWindowOcclusionStateVisible = 1UL << 1 }; -#endif + } 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. @@ -466,9 +439,6 @@ QT_WARNING_DISABLE_CLANG("-Wobjc-method-access") m_platformWindow->obscureWindow(); } } -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 -QT_WARNING_POP -#endif } else if (notificationName == NSWindowDidChangeScreenNotification) { if (m_window) { NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen]; @@ -525,8 +495,8 @@ QT_WARNING_POP qCDebug(lcQpaCocoaWindow) << "[QNSView flushBackingStore:]" << m_window << region.rectCount() << region.boundingRect() << offset; m_backingStore = backingStore; - m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio(); - foreach (QRect rect, region.rects()) + m_backingStoreOffset = offset * m_backingStore->paintDevice()->devicePixelRatio(); + for (const QRect &rect : region) [self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; } @@ -587,7 +557,7 @@ QT_WARNING_POP - (void) drawRect:(NSRect)dirtyRect { - qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_window << qt_mac_toQRect(dirtyRect); + qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_window << QRectF::fromCGRect(dirtyRect); #ifndef QT_NO_OPENGL if (m_glContext && m_shouldSetGLContextinDrawRect) { @@ -607,7 +577,7 @@ QT_WARNING_POP // The backing store source rect will be larger on retina displays. // Scale dirtyRect by the device pixel ratio: - const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio(); + const qreal devicePixelRatio = m_backingStore->paintDevice()->devicePixelRatio(); CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio, dirtyRect.origin.y * devicePixelRatio, dirtyRect.size.width * devicePixelRatio, @@ -1396,7 +1366,6 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) [event magnification], windowPoint, screenPoint); } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 - (void)smartMagnifyWithEvent:(NSEvent *)event { static bool zoomIn = true; @@ -1409,7 +1378,6 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint); zoomIn = !zoomIn; } -#endif - (void)rotateWithEvent:(NSEvent *)event { @@ -1525,16 +1493,12 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) NSEventPhase phase = [theEvent phase]; Qt::ScrollPhase ph = Qt::ScrollUpdate; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 - if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) { - // On 10.8 and above, MayBegin is likely to happen. We treat it the same as an actual begin. - if (phase == NSEventPhaseMayBegin) { - m_scrolling = true; - ph = Qt::ScrollBegin; - } - } -#endif - if (phase == NSEventPhaseBegan) { + + // MayBegin is likely to happen. We treat it the same as an actual begin. + if (phase == NSEventPhaseMayBegin) { + m_scrolling = true; + ph = Qt::ScrollBegin; + } else if (phase == NSEventPhaseBegan) { // If MayBegin did not happen, Began is the actual beginning. if (!m_scrolling) ph = Qt::ScrollBegin; diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h index ac1e8d62eb..46e8d40efb 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.h +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h @@ -57,6 +57,7 @@ - (void)windowWillMove:(NSNotification *)notification; - (BOOL)windowShouldClose:(NSNotification *)notification; - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame; +- (void)windowWillClose:(NSNotification *)notification; @end diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index faa53b06ef..b96a9491e8 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -115,4 +115,11 @@ return YES; } +- (void)windowWillClose:(NSNotification *)notification +{ + Q_UNUSED(notification); + if (m_cocoaWindow) + m_cocoaWindow->windowWillClose(); +} + @end diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 395c25c915..7e241e3ae6 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -63,6 +63,7 @@ #include <private/qpainter_p.h> #include <private/qpainterpath_p.h> #include <private/qtextengine_p.h> +#include <private/qcoregraphics_p.h> #include "qcocoahelpers.h" @@ -74,87 +75,6 @@ QT_BEGIN_NAMESPACE QCoreGraphicsPaintEngine utility functions *****************************************************************************/ -static void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform) -{ - CGAffineTransform old_xform = CGAffineTransformIdentity; - if (orig_xform) { //setup xforms - old_xform = CGContextGetCTM(hd); - CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform)); - CGContextConcatCTM(hd, *orig_xform); - } - - //do the clipping - CGContextBeginPath(hd); - if (rgn.isEmpty()) { - CGContextAddRect(hd, CGRectMake(0, 0, 0, 0)); - } else { - QVector<QRect> rects = rgn.rects(); - const int count = rects.size(); - for (int i = 0; i < count; i++) { - const QRect &r = rects[i]; - CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height()); - CGContextAddRect(hd, mac_r); - } - } - CGContextClip(hd); - - if (orig_xform) {//reset xforms - CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd))); - CGContextConcatCTM(hd, old_xform); - } -} - -// Implemented for qt_mac_p.h -QMacCGContext::QMacCGContext(QPainter *p) -{ - QPaintEngine *pe = p->paintEngine(); -#ifndef QT_NO_PRINTER - if (pe->type() == QPaintEngine::MacPrinter) - pe = static_cast<QMacPrintEngine*>(pe)->paintEngine(); -#endif - pe->syncState(); - context = 0; - if (pe->type() == QPaintEngine::CoreGraphics) - context = static_cast<QCoreGraphicsPaintEngine*>(pe)->handle(); - - int devType = p->device()->devType(); - if (pe->type() == QPaintEngine::Raster - && (devType == QInternal::Widget || devType == QInternal::Pixmap || devType == QInternal::Image)) { - - CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice()); - uint flags = kCGImageAlphaPremultipliedFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - flags |= kCGBitmapByteOrder32Host; -#endif - const QImage *image = (const QImage *) pe->paintDevice(); - - context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorspace, flags); - - CGContextTranslateCTM(context, 0, image->height()); - CGContextScaleCTM(context, 1, -1); - - if (devType == QInternal::Widget) { - QRegion clip = p->paintEngine()->systemClip(); - QTransform native = p->deviceTransform(); - - if (p->hasClipping()) { - QRegion r = p->clipRegion(); - r.translate(native.dx(), native.dy()); - if (clip.isEmpty()) - clip = r; - else - clip &= r; - } - qt_mac_clip_cg(context, clip, 0); - - CGContextTranslateCTM(context, native.dx(), native.dy()); - } - } else { - CGContextRetain(context); - } -} - void qt_mac_cgimage_data_free(void *, const void *memoryToFree, size_t) { free(const_cast<void *>(memoryToFree)); @@ -456,7 +376,7 @@ static void qt_mac_draw_pattern(void *info, CGContextRef c) const QColor c0(0, 0, 0, 0), c1(255, 255, 255, 255); QPixmap pm(w*QMACPATTERN_MASK_MULTIPLIER, h*QMACPATTERN_MASK_MULTIPLIER); pm.fill(c0); - CGContextRef pm_ctx = qt_mac_cg_context(&pm); + QMacCGContext pm_ctx(&pm); CGContextSetFillColorWithColor(c, cgColorForQColor(c1, pat->pdev)); CGRect rect = CGRectMake(0, 0, w, h); for (int x = 0; x < QMACPATTERN_MASK_MULTIPLIER; ++x) { @@ -546,7 +466,8 @@ QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev) d->cosmeticPenSize = 1; d->current.clipEnabled = false; d->pixelSize = QPoint(1,1); - d->hd = qt_mac_cg_context(pdev); + QMacCGContext ctx(pdev); + d->hd = CGContextRetain(ctx); if (d->hd) { d->saveGraphicsState(); d->orig_xform = CGContextGetCTM(d->hd); diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index 3d0c91c36c..0b5b06c44f 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -200,7 +200,7 @@ int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const val = (int)resolution.vRes; break; } - //otherwise fall through + Q_FALLTHROUGH(); } case QPaintDevice::PdmDpiY: val = (int)d->resolution.vRes; diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h index e3cad3fd57..ee98275b63 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h +++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h @@ -149,6 +149,9 @@ public: PMPageFormat format() const { return static_cast<PMPageFormat>([printInfo PMPageFormat]); } PMPrintSession session() const { return static_cast<PMPrintSession>([printInfo PMPrintSession]); } PMPrintSettings settings() const { return static_cast<PMPrintSettings>([printInfo PMPrintSettings]); } + + QPaintEngine *aggregateEngine() Q_DECL_OVERRIDE { return paintEngine; } + Qt::HANDLE nativeHandle() Q_DECL_OVERRIDE { return q_func()->handle(); } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h index 03eae1b2e7..ce17919e8c 100644 --- a/src/plugins/platforms/cocoa/qt_mac_p.h +++ b/src/plugins/platforms/cocoa/qt_mac_p.h @@ -90,60 +90,6 @@ public: } }; -class Q_WIDGETS_EXPORT QMacWindowChangeEvent -{ -private: - static QList<QMacWindowChangeEvent*> *change_events; -public: - QMacWindowChangeEvent() { - } - virtual ~QMacWindowChangeEvent() { - } - static inline void exec(bool ) { - } -protected: - virtual void windowChanged() = 0; - virtual void flushWindowChanged() = 0; -}; - -class QMacCGContext -{ - CGContextRef context; -public: - QMacCGContext(QPainter *p); //qpaintengine_mac.mm - inline QMacCGContext() { context = 0; } - inline QMacCGContext(QPaintDevice *pdev) { - extern CGContextRef qt_mac_cg_context(QPaintDevice *); - context = qt_mac_cg_context(pdev); - } - inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) { - context = cg; - if(!takeOwnership) - CGContextRetain(context); - } - inline QMacCGContext(const QMacCGContext ©) : context(0) { *this = copy; } - inline ~QMacCGContext() { - if(context) - CGContextRelease(context); - } - inline bool isNull() const { return context; } - inline operator CGContextRef() { return context; } - inline QMacCGContext &operator=(const QMacCGContext ©) { - if(context) - CGContextRelease(context); - context = copy.context; - CGContextRetain(context); - return *this; - } - inline QMacCGContext &operator=(CGContextRef cg) { - if(context) - CGContextRelease(context); - context = cg; - CGContextRetain(context); //we do not take ownership - return *this; - } -}; - class QMacInternalPasteboardMime; class QMimeData; diff --git a/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib b/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib deleted file mode 100644 index 78941153c2..0000000000 --- a/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>IBClasses</key> - <array> - <dict> - <key>ACTIONS</key> - <dict> - <key>hide</key> - <string>id</string> - <key>hideOtherApplications</key> - <string>id</string> - <key>orderFrontStandardAboutPanel</key> - <string>id</string> - <key>qtDispatcherToQPAMenuItem</key> - <string>id</string> - <key>terminate</key> - <string>id</string> - <key>unhideAllApplications</key> - <string>id</string> - </dict> - <key>CLASS</key> - <string>QCocoaMenuLoader</string> - <key>LANGUAGE</key> - <string>ObjC</string> - <key>OUTLETS</key> - <dict> - <key>aboutItem</key> - <string>NSMenuItem</string> - <key>aboutQtItem</key> - <string>NSMenuItem</string> - <key>appMenu</key> - <string>NSMenu</string> - <key>hideItem</key> - <string>NSMenuItem</string> - <key>preferencesItem</key> - <string>NSMenuItem</string> - <key>quitItem</key> - <string>NSMenuItem</string> - <key>theMenu</key> - <string>NSMenu</string> - </dict> - <key>SUPERCLASS</key> - <string>NSResponder</string> - </dict> - <dict> - <key>CLASS</key> - <string>FirstResponder</string> - <key>LANGUAGE</key> - <string>ObjC</string> - <key>SUPERCLASS</key> - <string>NSObject</string> - </dict> - </array> - <key>IBVersion</key> - <string>1</string> -</dict> -</plist> diff --git a/src/plugins/platforms/cocoa/qt_menu.nib/info.nib b/src/plugins/platforms/cocoa/qt_menu.nib/info.nib deleted file mode 100644 index 02e5cca562..0000000000 --- a/src/plugins/platforms/cocoa/qt_menu.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>IBFramework Version</key> - <string>672</string> - <key>IBOldestOS</key> - <integer>5</integer> - <key>IBOpenObjects</key> - <array> - <integer>57</integer> - </array> - <key>IBSystem Version</key> - <string>9L31a</string> - <key>targetFramework</key> - <string>IBCocoaFramework</string> -</dict> -</plist> diff --git a/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib b/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib Binary files differdeleted file mode 100644 index 67207ca628..0000000000 --- a/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib +++ /dev/null |