diff options
Diffstat (limited to 'src/plugins/platforms/cocoa')
16 files changed, 510 insertions, 208 deletions
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index bfa147f948..5573b19fcd 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -7,23 +7,29 @@ OBJECTIVE_SOURCES = main.mm \ qcocoawindowsurface.mm \ qcocoawindow.mm \ qnsview.mm \ - qcocoaeventloopintegration.mm \ qcocoaautoreleasepool.mm \ - qnswindowdelegate.mm + qnswindowdelegate.mm \ + qcocoaglcontext.mm \ + qcocoanativeinterface.mm + OBJECTIVE_HEADERS = qcocoaintegration.h \ qcocoawindowsurface.h \ qcocoawindow.h \ qnsview.h \ - qcocoaeventloopintegration.h \ qcocoaautoreleasepool.h \ - qnswindowdelegate.h + qnswindowdelegate.h \ + qcocoaglcontext.h \ + qcocoanativeinterface.h + +DEFINES += QT_BUILD_COCOA_LIB #add libz for freetype. LIBS += -lz LIBS += -framework cocoa -include(../fontdatabases/coretext/coretext.pri) +QT += core-private gui-private platformsupport-private + +CONFIG += qpa/basicunixfontdatabase target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target - diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm deleted file mode 100644 index ac0b75e9ea..0000000000 --- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qcocoaeventloopintegration.h" - -#import <Cocoa/Cocoa.h> - -#include "qcocoaautoreleasepool.h" - -#include <QtCore/QElapsedTimer> - -#include <QDebug> -#include <QApplication> - -void wakeupCallback ( void * ) { - QPlatformEventLoopIntegration::processEvents(); -} - -void timerCallback( CFRunLoopTimerRef timer, void *info) -{ - QPlatformEventLoopIntegration::processEvents(); - QCocoaEventLoopIntegration *eventLoopIntegration = - static_cast<QCocoaEventLoopIntegration *>(info); - qint64 nextTime = eventLoopIntegration->nextTimerEvent(); - CFAbsoluteTime nexttime = CFAbsoluteTimeGetCurrent(); - nexttime = nexttime + (double(nextTime)/1000); - CFRunLoopTimerSetNextFireDate(timer,nexttime); -} - -QCocoaEventLoopIntegration::QCocoaEventLoopIntegration() : - QPlatformEventLoopIntegration() -{ - [NSApplication sharedApplication]; - m_sourceContext.version = 0; - m_sourceContext.info = this; - m_sourceContext.retain = 0; - m_sourceContext.release = 0; - m_sourceContext.copyDescription = 0; - m_sourceContext.equal = 0; - m_sourceContext.hash = 0; - m_sourceContext.schedule = 0; - m_sourceContext.cancel = 0; - m_sourceContext.perform = wakeupCallback; - - m_source = CFRunLoopSourceCreate(0,0,&m_sourceContext); - CFRunLoopAddSource(CFRunLoopGetMain(),m_source,kCFRunLoopCommonModes); - - m_timerContext.version = 0; - m_timerContext.info = this; - m_timerContext.retain = 0; - m_timerContext.release = 0; - m_timerContext.copyDescription = 0; - CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent (); - CFTimeInterval interval = 30; - - CFRunLoopTimerRef m_timerSource = CFRunLoopTimerCreate(0,fireDate,interval,0,0,timerCallback,&m_timerContext); - CFRunLoopAddTimer(CFRunLoopGetMain(),m_timerSource,kCFRunLoopCommonModes); -} - -void QCocoaEventLoopIntegration::startEventLoop() -{ - [[NSApplication sharedApplication] run]; -} - -void QCocoaEventLoopIntegration::quitEventLoop() -{ - [[NSApplication sharedApplication] terminate:nil]; -} - -void QCocoaEventLoopIntegration::qtNeedsToProcessEvents() -{ - CFRunLoopSourceSignal(m_source); -} - diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h new file mode 100644 index 0000000000..01d931b662 --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -0,0 +1,54 @@ +#ifndef QCOCOAGLCONTEXT_H +#define QCOCOAGLCONTEXT_H + +#include <QtCore/QWeakPointer> +#include <QtGui/QPlatformGLContext> +#include <QtGui/QGuiGLContext> +#include <QtGui/QWindow> + +#include <Cocoa/Cocoa.h> + +QT_BEGIN_NAMESPACE + +class QCocoaGLSurface : public QPlatformGLSurface +{ +public: + QCocoaGLSurface(const QGuiGLFormat &format, QWindow *window) + : QPlatformGLSurface(format) + , window(window) + { + } + + QWindow *window; +}; + +class QCocoaGLContext : public QPlatformGLContext +{ +public: + QCocoaGLContext(const QGuiGLFormat &format, QPlatformGLContext *share); + + QGuiGLFormat format() const; + + void swapBuffers(const QPlatformGLSurface &surface); + + bool makeCurrent(const QPlatformGLSurface &surface); + void doneCurrent(); + + void (*getProcAddress(const QByteArray &procName)) (); + + void update(); + + static NSOpenGLPixelFormat *createNSOpenGLPixelFormat(); + NSOpenGLContext *nsOpenGLContext() const; + +private: + void setActiveWindow(QWindow *window); + + NSOpenGLContext *m_context; + QGuiGLFormat m_format; + QWeakPointer<QWindow> m_currentWindow; +}; + +QT_END_NAMESPACE + +#endif // QCOCOAGLCONTEXT_H diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm new file mode 100644 index 0000000000..f9cda1bb37 --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -0,0 +1,105 @@ +#include "qcocoaglcontext.h" +#include "qcocoawindow.h" +#include <qdebug.h> +#include <QtCore/private/qcore_mac_p.h> + +#import <Cocoa/Cocoa.h> + +QCocoaGLContext::QCocoaGLContext(const QGuiGLFormat &format, QPlatformGLContext *share) + : m_format(format) +{ + NSOpenGLPixelFormat *pixelFormat = createNSOpenGLPixelFormat(); + NSOpenGLContext *actualShare = share ? static_cast<QCocoaGLContext *>(share)->m_context : 0; + + m_context = [NSOpenGLContext alloc]; + [m_context initWithFormat:pixelFormat shareContext:actualShare]; +} + +// Match up with createNSOpenGLPixelFormat! +QGuiGLFormat QCocoaGLContext::format() const +{ + return m_format; +} + +void QCocoaGLContext::swapBuffers(const QPlatformGLSurface &surface) +{ + QWindow *window = static_cast<const QCocoaGLSurface &>(surface).window; + setActiveWindow(window); + + [m_context flushBuffer]; +} + +bool QCocoaGLContext::makeCurrent(const QPlatformGLSurface &surface) +{ + QWindow *window = static_cast<const QCocoaGLSurface &>(surface).window; + setActiveWindow(window); + + [m_context makeCurrentContext]; + return true; +} + +void QCocoaGLContext::setActiveWindow(QWindow *window) +{ + if (window == m_currentWindow.data()) + return; + + if (m_currentWindow) + static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0); + + Q_ASSERT(window->handle()); + + m_currentWindow = window; + + QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle()); + cocoaWindow->setCurrentContext(this); + + NSView *view = cocoaWindow->windowSurfaceView(); + [m_context setView:view]; +} + +void QCocoaGLContext::doneCurrent() +{ + if (m_currentWindow) + static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0); + + m_currentWindow.clear(); + + [NSOpenGLContext clearCurrentContext]; +} + +void (*QCocoaGLContext::getProcAddress(const QByteArray &procName)) () +{ + CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, + CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, false); + CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault, url); + CFStringRef procNameCF = QCFString::toCFStringRef(QString::fromAscii(procName.constData())); + void *proc = CFBundleGetFunctionPointerForName(bundle, procNameCF); + CFRelease(url); + CFRelease(bundle); + CFRelease(procNameCF); + return (void (*) ())proc; +} + +void QCocoaGLContext::update() +{ + [m_context update]; +} + +NSOpenGLPixelFormat *QCocoaGLContext::createNSOpenGLPixelFormat() +{ + NSOpenGLPixelFormatAttribute attrs[] = + { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, 32, + 0 + }; + + NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + return pixelFormat; +} + +NSOpenGLContext *QCocoaGLContext::nsOpenGLContext() const +{ + return m_context; +} + diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 120bee46b7..59008b4e3f 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -77,15 +77,15 @@ public: bool hasCapability(QPlatformIntegration::Capability cap) const; QPixmapData *createPixmapData(QPixmapData::PixelType type) const; - QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const; - QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const; + QWindowSurface *createWindowSurface(QWindow *widget, WId winId) const; QList<QPlatformScreen *> screens() const { return mScreens; } QPlatformFontDatabase *fontDatabase() const; - QPlatformEventLoopIntegration *createEventLoopIntegration() const; - + QPlatformNativeInterface *nativeInterface() const; private: QList<QPlatformScreen *> mScreens; QPlatformFontDatabase *mFontDb; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 086f7b62e9..dfe225ff2e 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -43,11 +43,9 @@ #include "qcocoawindow.h" #include "qcocoawindowsurface.h" -#include "qcocoaeventloopintegration.h" +#include "qcocoanativeinterface.h" -#include "qcoretextfontdatabase.h" - -#include <QtGui/QApplication> +#include "qbasicunixfontdatabase.h" #include <private/qpixmap_raster_p.h> @@ -74,7 +72,7 @@ QCocoaScreen::~QCocoaScreen() } QCocoaIntegration::QCocoaIntegration() - : mFontDb(new QCoreTextFontDatabase()) + : mFontDb(new QBasicUnixFontDatabase()) { mPool = new QCocoaAutoReleasePool; @@ -98,6 +96,7 @@ bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) cons { switch (cap) { case ThreadedPixmaps: return true; + case OpenGL : return true; default: return QPlatformIntegration::hasCapability(cap); } } @@ -109,15 +108,19 @@ QPixmapData *QCocoaIntegration::createPixmapData(QPixmapData::PixelType type) co return new QRasterPixmapData(type); } -QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWidget *widget, WId winId) const +QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const { - Q_UNUSED(winId); - return new QCocoaWindow(widget); + return new QCocoaWindow(window); } -QWindowSurface *QCocoaIntegration::createWindowSurface(QWidget *widget, WId winId) const +QPlatformGLContext *QCocoaIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const { - return new QCocoaWindowSurface(widget,winId); + return new QCocoaGLContext(glFormat, share); +} + +QWindowSurface *QCocoaIntegration::createWindowSurface(QWindow *window, WId winId) const +{ + return new QCocoaWindowSurface(window, winId); } QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const @@ -125,8 +128,9 @@ QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const return mFontDb; } -QPlatformEventLoopIntegration *QCocoaIntegration::createEventLoopIntegration() const +QPlatformNativeInterface *QCocoaIntegration::nativeInterface() const { - return new QCocoaEventLoopIntegration(); + return new QCocoaNativeInterface(); } + QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index 5765483fc7..f8216d8e61 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -39,27 +39,17 @@ ** ****************************************************************************/ -#ifndef QCOCAEVENTLOOPINTEGRATION_H -#define QCOCAEVENTLOOPINTEGRATION_H +#ifndef QCOCOANATIVEINTERFACE_H +#define QCOCOANATIVEINTERFACE_H -#include <Cocoa/Cocoa.h> +#include <QtGui/QPlatformNativeInterface> -#include <QPlatformEventLoopIntegration> +class QWidget; - -class QCocoaEventLoopIntegration : public QPlatformEventLoopIntegration +class QCocoaNativeInterface : public QPlatformNativeInterface { public: - QCocoaEventLoopIntegration(); - void startEventLoop(); - void quitEventLoop(); - void qtNeedsToProcessEvents(); - -private: - CFRunLoopSourceContext m_sourceContext; - CFRunLoopTimerContext m_timerContext; - CFRunLoopSourceRef m_source; + void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window); }; -#endif // QCOCAEVENTLOOPINTEGRATION_H - +#endif // QCOCOANATIVEINTERFACE_H diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm new file mode 100644 index 0000000000..87d0ec4a0c --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcocoanativeinterface.h" +#include "qcocoaglcontext.h" +#include "qcocoawindow.h" +#include <qbytearray.h> +#include <qwindow.h> +#include "qplatformwindow_qpa.h" +#include "qguiglformat_qpa.h" +#include "qplatformglcontext_qpa.h" +#include "qguiglcontext_qpa.h" +#include <qdebug.h> + +void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) +{ + if (resourceString == "nsopenglcontext") { + + static_cast<QCocoaWindow *>(window->handle())->currentContext()->nsOpenGLContext(); + } + return 0; +} diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 9e7e68b7d2..9d7d37c2ee 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -46,27 +46,41 @@ #include <QPlatformWindow> +#include "qcocoaglcontext.h" +#include "qnsview.h" + QT_BEGIN_NAMESPACE class QCocoaWindow : public QPlatformWindow { public: - QCocoaWindow(QWidget *tlw); + QCocoaWindow(QWindow *tlw); ~QCocoaWindow(); void setGeometry(const QRect &rect); - void setVisible(bool visible); + void setWindowTitle(const QString &title); + void raise(); + void lower(); WId winId() const; - NSView *contentView() const; - void setContentView(NSView *contentView); + NSView *windowSurfaceView() const; + void windowDidMove(); void windowDidResize(); + QPlatformGLSurface *createGLSurface() const; + + void setCurrentContext(QCocoaGLContext *context); + QCocoaGLContext *currentContext() const; + private: + friend class QCocoaWindowSurface; NSWindow *m_nsWindow; + QNSView *m_contentView; + NSView *m_windowSurfaceView; + QCocoaGLContext *m_glContext; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index a2fdce3520..874790a128 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -41,17 +41,17 @@ #include "qcocoawindow.h" #include "qnswindowdelegate.h" #include "qcocoaautoreleasepool.h" - -#include <QWidget> - -#include <QtGui/QApplication> +#include "qcocoaglcontext.h" +#include "qnsview.h" +#include <QtCore/private/qcore_mac_p.h> #include <QWindowSystemInterface> #include <QDebug> -QCocoaWindow::QCocoaWindow(QWidget *tlw) +QCocoaWindow::QCocoaWindow(QWindow *tlw) : QPlatformWindow(tlw) + , m_glContext(0) { QCocoaAutoReleasePool pool; const QRect geo = tlw->geometry(); @@ -65,12 +65,26 @@ QCocoaWindow::QCocoaWindow(QWidget *tlw) QNSWindowDelegate *delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this]; [m_nsWindow setDelegate:delegate]; - [m_nsWindow makeKeyAndOrderFront:nil]; [m_nsWindow setAcceptsMouseMovedEvents:YES]; + + m_contentView = [[QNSView alloc] initWithQWindow:tlw]; + + if (tlw->surfaceType() == QWindow::OpenGLSurface) { + NSRect glFrame = NSMakeRect(0, 0, geo.width(), geo.height()); + m_windowSurfaceView = [[NSOpenGLView alloc] initWithFrame : glFrame pixelFormat : QCocoaGLContext::createNSOpenGLPixelFormat() ]; + [m_contentView setAutoresizesSubviews : YES]; + [m_windowSurfaceView setAutoresizingMask : (NSViewWidthSizable | NSViewHeightSizable)]; + [m_contentView addSubview : m_windowSurfaceView]; + } else { + m_windowSurfaceView = m_contentView; + } + + [m_nsWindow setContentView:m_contentView]; } QCocoaWindow::~QCocoaWindow() { + } void QCocoaWindow::setGeometry(const QRect &rect) @@ -79,16 +93,41 @@ void QCocoaWindow::setGeometry(const QRect &rect) NSRect bounds = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); [[m_nsWindow contentView]setFrameSize:bounds.size]; + + if (m_glContext) + m_glContext->update(); } void QCocoaWindow::setVisible(bool visible) { - Q_UNUSED(visible); + if (visible) { + [m_nsWindow makeKeyAndOrderFront:nil]; + } else { + [m_nsWindow orderOut:nil]; + } +} + +void QCocoaWindow::setWindowTitle(const QString &title) +{ + CFStringRef windowTitle = QCFString::toCFStringRef(title); + [m_nsWindow setTitle: reinterpret_cast<const NSString *>(windowTitle)]; + CFRelease(windowTitle); +} + +void QCocoaWindow::raise() +{ + // ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm) + [m_nsWindow orderFront]; +} + +void QCocoaWindow::lower() +{ + [m_nsWindow orderBack]; } WId QCocoaWindow::winId() const { - return WId([m_nsWindow windowNumber]); + return WId(m_nsWindow); } NSView *QCocoaWindow::contentView() const @@ -96,9 +135,15 @@ NSView *QCocoaWindow::contentView() const return [m_nsWindow contentView]; } -void QCocoaWindow::setContentView(NSView *contentView) +NSView *QCocoaWindow::windowSurfaceView() const +{ + return m_windowSurfaceView; +} + +void QCocoaWindow::windowDidMove() { - [m_nsWindow setContentView:contentView]; + if (m_glContext) + m_glContext->update(); } void QCocoaWindow::windowDidResize() @@ -106,5 +151,25 @@ void QCocoaWindow::windowDidResize() //jlind: XXX This isn't ideal. Eventdispatcher does not run when resizing... NSRect rect = [[m_nsWindow contentView]frame]; QRect geo(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); - QWindowSystemInterface::handleGeometryChange(widget(),geo); + QWindowSystemInterface::handleGeometryChange(window(),geo); + + if (m_glContext) + m_glContext->update(); +} + +QPlatformGLSurface *QCocoaWindow::createGLSurface() const +{ + Q_ASSERT(window()->surfaceType() == QWindow::OpenGLSurface); + return new QCocoaGLSurface(window()->glFormat(), window()); } + +void QCocoaWindow::setCurrentContext(QCocoaGLContext *context) +{ + m_glContext = context; +} + +QCocoaGLContext *QCocoaWindow::currentContext() const +{ + return m_glContext; +} + diff --git a/src/plugins/platforms/cocoa/qcocoawindowsurface.h b/src/plugins/platforms/cocoa/qcocoawindowsurface.h index 95eea2b7ea..01c6ccde3e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindowsurface.h +++ b/src/plugins/platforms/cocoa/qcocoawindowsurface.h @@ -54,18 +54,16 @@ QT_BEGIN_NAMESPACE class QCocoaWindowSurface : public QWindowSurface { public: - QCocoaWindowSurface(QWidget *window, WId wid); + QCocoaWindowSurface(QWindow *window, WId wid); ~QCocoaWindowSurface(); QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + void flush(QWindow *widget, const QRegion ®ion, const QPoint &offset); void resize (const QSize &size); private: - QCocoaWindow *m_cocoaWindow; QImage *m_image; - QNSView *m_contentView; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindowsurface.mm b/src/plugins/platforms/cocoa/qcocoawindowsurface.mm index 16bb327196..9a4b42b31e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindowsurface.mm +++ b/src/plugins/platforms/cocoa/qcocoawindowsurface.mm @@ -42,7 +42,6 @@ #include "qcocoawindowsurface.h" #include <QtCore/qdebug.h> - #include <QtGui/QPainter> QT_BEGIN_NAMESPACE @@ -56,17 +55,16 @@ QRect flipedRect(const QRect &sourceRect,int height) return flippedRect; } -QCocoaWindowSurface::QCocoaWindowSurface(QWidget *window, WId wId) +QCocoaWindowSurface::QCocoaWindowSurface(QWindow *window, WId wId) : QWindowSurface(window) { - m_cocoaWindow = static_cast<QCocoaWindow *>(window->platformWindow()); + Q_UNUSED(wId); + m_cocoaWindow = static_cast<QCocoaWindow *>(window->handle()); const QRect geo = window->geometry(); NSRect rect = NSMakeRect(geo.x(),geo.y(),geo.width(),geo.height()); - m_contentView = [[QNSView alloc] initWithWidget:window]; - m_cocoaWindow->setContentView(m_contentView); - m_image = new QImage(window->size(),QImage::Format_ARGB32); + m_image = new QImage(window->geometry().size(),QImage::Format_ARGB32); } QCocoaWindowSurface::~QCocoaWindowSurface() @@ -79,7 +77,7 @@ QPaintDevice *QCocoaWindowSurface::paintDevice() return m_image; } -void QCocoaWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) +void QCocoaWindowSurface::flush(QWindow *widget, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(widget); Q_UNUSED(offset); @@ -87,7 +85,7 @@ void QCocoaWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QP QRect geo = region.boundingRect(); NSRect rect = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height()); - [m_contentView displayRect:rect]; + [m_cocoaWindow->m_windowSurfaceView displayRect:rect]; } void QCocoaWindowSurface::resize(const QSize &size) @@ -96,8 +94,7 @@ void QCocoaWindowSurface::resize(const QSize &size) delete m_image; m_image = new QImage(size,QImage::Format_ARGB32_Premultiplied); NSSize newSize = NSMakeSize(size.width(),size.height()); - [m_contentView setImage:m_image]; - + [m_cocoaWindow->m_windowSurfaceView setImage:m_image]; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 69a11134bd..0b96928d5b 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -48,17 +48,18 @@ @interface QNSView : NSView { CGImageRef m_cgImage; - QWidget *m_widget; + QWindow *m_window; Qt::MouseButtons m_buttons; } - (id)init; -- (id)initWithWidget:(QWidget *)widget; +- (id)initWithQWindow:(QWindow *)window; - (void)setImage:(QImage *)image; - (void)drawRect:(NSRect)dirtyRect; - (BOOL)isFlipped; +- (BOOL)acceptsFirstResponder; - (void)handleMouseEvent:(NSEvent *)theEvent; - (void)mouseDown:(NSEvent *)theEvent; @@ -74,6 +75,12 @@ - (void)otherMouseDragged:(NSEvent *)theEvent; - (void)otherMouseUp:(NSEvent *)theEvent; +- (int) convertKeyCode : (QChar)keyCode; +- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags; +- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType; +- (void)keyDown:(NSEvent *)theEvent; +- (void)keyUp:(NSEvent *)theEvent; + @end #endif //QNSVIEW_H diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 037cbdb5d6..5d7fd05b1f 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -52,16 +52,16 @@ self = [super init]; if (self) { m_cgImage = 0; - m_widget = 0; + m_window = 0; m_buttons = Qt::NoButton; } return self; } -- (id)initWithWidget:(QWidget *)widget { +- (id)initWithQWindow:(QWindow *)widget { self = [self init]; if (self) { - m_widget = widget; + m_window = widget; } return self; } @@ -130,48 +130,55 @@ return YES; } +- (BOOL)acceptsFirstResponder +{ + return YES; +} + - (void)handleMouseEvent:(NSEvent *)theEvent; { - NSPoint point = [self convertPoint: [theEvent locationInWindow] fromView: nil]; - QPoint qt_localPoint(point.x,point.y); + NSPoint windowPoint = [self convertPoint: [theEvent locationInWindow] fromView: nil]; + QPoint qt_windowPoint(windowPoint.x, windowPoint.y); NSTimeInterval timestamp = [theEvent timestamp]; ulong qt_timestamp = timestamp * 1000; - QWindowSystemInterface::handleMouseEvent(m_widget,qt_timestamp,qt_localPoint,QPoint(),m_buttons); + // ### Should the points be windowPoint and screenPoint? + QWindowSystemInterface::handleMouseEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, m_buttons); +} +- (void)mouseDown:(NSEvent *)theEvent +{ + m_buttons |= Qt::LeftButton; + [self handleMouseEvent:theEvent]; +} + +- (void)mouseDragged:(NSEvent *)theEvent +{ + if (!(m_buttons & Qt::LeftButton)) + qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton"); + [self handleMouseEvent:theEvent]; +} + +- (void)mouseUp:(NSEvent *)theEvent +{ + m_buttons &= QFlag(~int(Qt::LeftButton)); + [self handleMouseEvent:theEvent]; } - - (void)mouseDown:(NSEvent *)theEvent - { - m_buttons |= Qt::LeftButton; - [self handleMouseEvent:theEvent]; - } - - (void)mouseDragged:(NSEvent *)theEvent - { - if (!(m_buttons & Qt::LeftButton)) - qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton"); - [self handleMouseEvent:theEvent]; - } - - (void)mouseUp:(NSEvent *)theEvent - { - m_buttons &= QFlag(~int(Qt::LeftButton)); - [self handleMouseEvent:theEvent]; - } - (void)mouseMoved:(NSEvent *)theEvent { - qDebug() << "mouseMove"; [self handleMouseEvent:theEvent]; } - (void)mouseEntered:(NSEvent *)theEvent { Q_UNUSED(theEvent); - QWindowSystemInterface::handleEnterEvent(m_widget); + QWindowSystemInterface::handleEnterEvent(m_window); } - (void)mouseExited:(NSEvent *)theEvent { Q_UNUSED(theEvent); - QWindowSystemInterface::handleLeaveEvent(m_widget); + QWindowSystemInterface::handleLeaveEvent(m_window); } - (void)rightMouseDown:(NSEvent *)theEvent { @@ -206,6 +213,84 @@ [self handleMouseEvent:theEvent]; } +- (int) convertKeyCode : (QChar)keyChar +{ + if (keyChar.isLower()) + keyChar = keyChar.toUpper(); + int keyCode = keyChar.unicode(); + + int qtKeyCode = Qt::Key(keyCode); // default case, overrides below + switch (keyCode) { + case NSEnterCharacter: qtKeyCode = Qt::Key_Enter; break; + case NSBackspaceCharacter: qtKeyCode = Qt::Key_Backspace; break; + case NSTabCharacter: qtKeyCode = Qt::Key_Tab; break; + case NSNewlineCharacter: qtKeyCode = Qt::Key_Return; break; + case NSCarriageReturnCharacter: qtKeyCode = Qt::Key_Return; break; + case NSBackTabCharacter: qtKeyCode = Qt::Key_Backtab; break; + case 27 : qtKeyCode = Qt::Key_Escape; break; + case NSDeleteCharacter : qtKeyCode = Qt::Key_Backspace; break; // Cocoa sends us delete when pressing backspace. + case NSUpArrowFunctionKey: qtKeyCode = Qt::Key_Up; break; + case NSDownArrowFunctionKey: qtKeyCode = Qt::Key_Down; break; + case NSLeftArrowFunctionKey: qtKeyCode = Qt::Key_Left; break; + case NSRightArrowFunctionKey: qtKeyCode = Qt::Key_Right; break; + case NSInsertFunctionKey: qtKeyCode = Qt::Key_Insert; break; + case NSDeleteFunctionKey: qtKeyCode = Qt::Key_Delete; break; + case NSHomeFunctionKey: qtKeyCode = Qt::Key_Home; break; + case NSEndFunctionKey: qtKeyCode = Qt::Key_End; break; + case NSPageUpFunctionKey: qtKeyCode = Qt::Key_PageUp; break; + case NSPageDownFunctionKey: qtKeyCode = Qt::Key_PageDown; break; + case NSPrintScreenFunctionKey: qtKeyCode = Qt::Key_Print; break; + case NSScrollLockFunctionKey: qtKeyCode = Qt::Key_ScrollLock; break; + case NSPauseFunctionKey: qtKeyCode = Qt::Key_Pause; break; + case NSSysReqFunctionKey: qtKeyCode = Qt::Key_SysReq; break; + case NSMenuFunctionKey: qtKeyCode = Qt::Key_Menu; break; + case NSHelpFunctionKey: qtKeyCode = Qt::Key_Help; break; + default : break; + } + + // handle all function keys (F1-F35) + if (keyCode >= NSF1FunctionKey && keyCode <= NSF35FunctionKey) + qtKeyCode = Qt::Key_F1 + (keyCode - NSF1FunctionKey); + return qtKeyCode; +} + +- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags +{ + Qt::KeyboardModifiers qtMods =Qt::NoModifier; + if (modifierFlags & NSShiftKeyMask) + qtMods |= Qt::ShiftModifier; + if (modifierFlags & NSControlKeyMask) + qtMods |= Qt::MetaModifier; + if (modifierFlags & NSAlternateKeyMask) + qtMods |= Qt::AltModifier; + if (modifierFlags & NSCommandKeyMask) + qtMods |= Qt::ControlModifier; + if (modifierFlags & NSNumericPadKeyMask) + qtMods |= Qt::KeypadModifier; + return qtMods; +} + +- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType +{ + NSTimeInterval timestamp = [theEvent timestamp]; + ulong qt_timestamp = timestamp * 1000; + QString characters = QString::fromUtf8([[theEvent characters] UTF8String]); + Qt::KeyboardModifiers modifiers = [self convertKeyModifiers : [theEvent modifierFlags]]; + QChar ch([[theEvent charactersIgnoringModifiers] characterAtIndex:0]); + int keyCode = [self convertKeyCode : ch]; + + QWindowSystemInterface::handleKeyEvent(m_window, qt_timestamp, QEvent::Type(eventType), keyCode, modifiers, characters); +} + +- (void)keyDown:(NSEvent *)theEvent +{ + [self handleKeyEvent : theEvent eventType :int(QEvent::KeyPress)]; +} + +- (void)keyUp:(NSEvent *)theEvent +{ + [self handleKeyEvent : theEvent eventType :int(QEvent::KeyRelease)]; +} @end diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h index cf296c4a8b..5cd226a71d 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.h +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h @@ -46,6 +46,26 @@ #include "qcocoawindow.h" +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 +@protocol NSWindowDelegate <NSObject> +//- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize; +//- (void)windowDidMiniaturize:(NSNotification*)notification; +- (void)windowDidResize:(NSNotification *)notification; +- (void)windowWillClose:(NSNotification *)notification; +//- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)defaultFrame; +- (void)windowDidMove:(NSNotification *)notification; +//- (BOOL)windowShouldClose:(id)window; +//- (void)windowDidDeminiaturize:(NSNotification *)notification; +//- (void)windowDidBecomeMain:(NSNotification*)notification; +//- (void)windowDidResignMain:(NSNotification*)notification; +//- (void)windowDidBecomeKey:(NSNotification*)notification; +//- (void)windowDidResignKey:(NSNotification*)notification; +//- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu; +//- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard; +//- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame; +@end +#endif + @interface QNSWindowDelegate : NSObject <NSWindowDelegate> { QCocoaWindow *m_cocoaWindow; @@ -54,6 +74,7 @@ - (id)initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow; - (void)windowDidResize:(NSNotification *)notification; +- (void)windowDidMove:(NSNotification *)notification; - (void)windowWillClose:(NSNotification *)notification; @end diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index 887b08f6d2..6521db5cf7 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -64,10 +64,18 @@ } } +- (void)windowDidMove:(NSNotification *)notification +{ + Q_UNUSED(notification); + if (m_cocoaWindow) { + m_cocoaWindow->windowDidMove(); + } +} + - (void)windowWillClose:(NSNotification *)notification { Q_UNUSED(notification); - QWindowSystemInterface::handleCloseEvent(m_cocoaWindow->widget()); + QWindowSystemInterface::handleCloseEvent(m_cocoaWindow->window()); } @end |