summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp17
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.h6
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.h16
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm93
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm21
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.mm28
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h31
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm55
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintrospection.h84
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintrospection.mm125
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm20
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm4
-rwxr-xr-xsrc/plugins/platforms/cocoa/qcocoasystemtrayicon.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm50
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.mm5
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm24
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm47
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp14
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp131
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp14
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp10
-rw-r--r--src/plugins/platforms/xcb/README8
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp95
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h14
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp14
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp19
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp93
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro117
-rw-r--r--src/plugins/platforms/xcb/xcb-static/xcb-static.pro70
-rw-r--r--src/plugins/platforms/xcb/xcb.pro115
-rw-r--r--src/plugins/printsupport/cocoa/cocoa.pro2
-rw-r--r--src/plugins/printsupport/cups/cups.pro2
-rw-r--r--src/plugins/printsupport/windows/windows.pro2
50 files changed, 1066 insertions, 362 deletions
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
index 9bdb1decde..a45c199419 100644
--- a/src/plugins/accessible/widgets/simplewidgets.cpp
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -653,6 +653,8 @@ void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t)
{
if (t == QAccessible::TextInterface)
return static_cast<QAccessibleTextInterface*>(this);
+ if (t == QAccessible::EditableTextInterface)
+ return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
}
@@ -784,6 +786,21 @@ void QAccessibleLineEdit::scrollToSubstring(int startIndex, int endIndex)
lineEdit()->setCursorPosition(startIndex);
}
+void QAccessibleLineEdit::deleteText(int startOffset, int endOffset)
+{
+ lineEdit()->setText(lineEdit()->text().remove(startOffset, endOffset - startOffset));
+}
+
+void QAccessibleLineEdit::insertText(int offset, const QString &text)
+{
+ lineEdit()->setText(lineEdit()->text().insert(offset, text));
+}
+
+void QAccessibleLineEdit::replaceText(int startOffset, int endOffset, const QString &text)
+{
+ lineEdit()->setText(lineEdit()->text().replace(startOffset, endOffset - startOffset, text));
+}
+
#endif // QT_NO_LINEEDIT
#ifndef QT_NO_PROGRESSBAR
diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h
index 7891e13c20..2e1bca88b4 100644
--- a/src/plugins/accessible/widgets/simplewidgets.h
+++ b/src/plugins/accessible/widgets/simplewidgets.h
@@ -137,7 +137,7 @@ private:
#endif
#ifndef QT_NO_LINEEDIT
-class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface
+class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface, public QAccessibleEditableTextInterface
{
public:
explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString());
@@ -168,6 +168,10 @@ public:
int characterCount() const;
void scrollToSubstring(int startIndex, int endIndex);
+ // QAccessibleEditableTextInterface
+ void deleteText(int startOffset, int endOffset);
+ void insertText(int offset, const QString &text);
+ void replaceText(int startOffset, int endOffset, const QString &text);
protected:
QLineEdit *lineEdit() const;
};
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index 3ea5dc2d1c..ce46c46b0e 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -37,6 +37,7 @@ OBJECTIVE_SOURCES += main.mm \
qcocoainputcontext.mm \
qcocoaservices.mm \
qcocoasystemtrayicon.mm \
+ qcocoaintrospection.mm \
HEADERS += qcocoaintegration.h \
qcocoatheme.h \
@@ -70,6 +71,7 @@ HEADERS += qcocoaintegration.h \
qcocoainputcontext.h \
qcocoaservices.h \
qcocoasystemtrayicon.h \
+ qcocoaintrospection.h \
RESOURCES += qcocoaresources.qrc
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
index ad2267c6bf..e2a64331ac 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
@@ -44,6 +44,18 @@
#include <Cocoa/Cocoa.h>
#include <QtGui>
+#include <qpa/qplatformaccessibility.h>
+
+class QCococaAccessibility : public QPlatformAccessibility
+{
+public:
+ QCococaAccessibility();
+ ~QCococaAccessibility();
+ void notifyAccessibilityUpdate(QAccessibleEvent *event);
+ void setRootObject(QObject *o);
+ void initialize();
+ void cleanup();
+};
namespace QCocoaAccessible {
@@ -52,9 +64,9 @@ namespace QCocoaAccessible {
Cocoa accessibility is implemented in the following files:
+ - qcocoaaccessibility (this file) : QCocoaAccessibility "plugin", conversion and helper functions.
- qnsviewaccessibility : Root accessibility implementation for QNSView
- qcocoaaccessibilityelement : Cocoa accessibility protocol wrapper for QAccessibleInterface
- - qcocoaaccessibility (this file) : Conversion and helper functions.
The accessibility implementation wraps QAccessibleInterfaces in QCocoaAccessibleElements, which
implements the cocoa accessibility protocol. The root QAccessibleInterface (the one returned
@@ -70,6 +82,8 @@ bool shouldBeIgnrored(QAccessibleInterface *interface);
NSString *getTranslatedAction(const QString &qtAction);
NSMutableArray *createTranslatedActionsList(const QStringList &qtActions);
QString translateAction(NSString *nsAction);
+bool hasValueAttribute(QAccessibleInterface *interface);
+id getValueAttribute(QAccessibleInterface *interface);
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 4b897fc211..66cb979031 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -39,6 +39,60 @@
**
****************************************************************************/
#include "qcocoaaccessibility.h"
+#include "qcocoaaccessibilityelement.h"
+#include <qaccessible.h>
+#include <qaccessible2.h>
+#include <private/qcore_mac_p.h>
+
+QCococaAccessibility::QCococaAccessibility()
+{
+
+}
+
+QCococaAccessibility::~QCococaAccessibility()
+{
+
+}
+
+void QCococaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
+{
+ QObject *object = event->object();
+ if (!object)
+ return;
+
+ QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(object);
+ if (!interface)
+ return;
+
+ switch (event->type()) {
+ case QAccessible::ValueChanged:
+ case QAccessible::TextInserted :
+ case QAccessible::TextRemoved :
+ case QAccessible::TextUpdated : {
+ QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithInterface : interface parent : nil];
+ NSAccessibilityPostNotification(element, NSAccessibilityValueChangedNotification);
+ break; }
+
+ default:
+ delete interface;
+ break;
+ }
+}
+
+void QCococaAccessibility::setRootObject(QObject *o)
+{
+ Q_UNUSED(o)
+}
+
+void QCococaAccessibility::initialize()
+{
+
+}
+
+void QCococaAccessibility::cleanup()
+{
+
+}
namespace QCocoaAccessible {
@@ -218,4 +272,43 @@ QString translateAction(NSString *nsAction)
return QString();
}
+bool hasValueAttribute(QAccessibleInterface *interface)
+{
+ const QAccessible::Role qtrole = interface->role();
+ if (qtrole == QAccessible::EditableText
+ || interface->valueInterface()) {
+ return true;
+ }
+
+ return false;
+}
+
+id getValueAttribute(QAccessibleInterface *interface)
+{
+ const QAccessible::Role qtrole = interface->role();
+ if (qtrole == QAccessible::EditableText) {
+ if (QAccessibleTextInterface *textInterface = interface->textInterface()) {
+ // VoiceOver will read out the entire text string at once when returning
+ // text as a value. For large text edits the size of the returned string
+ // needs to be limited and text range attributes need to be used instead.
+ // NSTextEdit returns the first sentence as the value, Do the same here:
+ int begin = 0;
+ int end = textInterface->characterCount();
+ // ### call to textAfterOffset hangs. Booo!
+ //if (textInterface->characterCount() > 0)
+ // textInterface->textAfterOffset(0, QAccessible2::SentenceBoundary, &begin, &end);
+
+ QString text = textInterface->text(begin, end);
+ //qDebug() << "text" << begin << end << text;
+ return QCFString::toNSString(text);
+ }
+ }
+
+ if (QAccessibleValueInterface *valueInterface = interface->valueInterface()) {
+ return QCFString::toNSString(QString::number(valueInterface->currentValue().toDouble()));
+ }
+
+ return nil;
+}
+
} // namespace QCocoaAccessible
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index c39290357e..cc1d393029 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -96,9 +96,9 @@ static QAccessibleInterface *acast(void *ptr)
// attributes
- (NSArray *)accessibilityAttributeNames {
- static NSArray *attributes = nil;
- if (attributes == nil) {
- attributes = [[NSArray alloc] initWithObjects:
+ static NSArray *defaultAttributes = nil;
+ if (defaultAttributes == nil) {
+ defaultAttributes = [[NSArray alloc] initWithObjects:
NSAccessibilityRoleAttribute,
NSAccessibilityRoleDescriptionAttribute,
NSAccessibilityChildrenAttribute,
@@ -112,6 +112,14 @@ static QAccessibleInterface *acast(void *ptr)
NSAccessibilityEnabledAttribute,
nil];
}
+
+ NSMutableArray *attributes = [[NSMutableArray alloc] initWithCapacity : [defaultAttributes count]];
+ [attributes addObjectsFromArray : defaultAttributes];
+
+ if (QCocoaAccessible::hasValueAttribute(acast(accessibleInterface))) {
+ [attributes addObject : NSAccessibilityValueAttribute];
+ }
+
return attributes;
}
@@ -153,6 +161,13 @@ static QAccessibleInterface *acast(void *ptr)
return QCFString::toNSString(acast(accessibleInterface)->text(QAccessible::Name));
} else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) {
return [NSNumber numberWithBool:!acast(accessibleInterface)->state().disabled];
+ } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
+ // VoiceOver asks for the value attribute for all elements. Return nil
+ // if we don't want the element to have a value attribute.
+ if (!QCocoaAccessible::hasValueAttribute(acast(accessibleInterface)))
+ return nil;
+
+ return QCocoaAccessible::getValueAttribute(acast(accessibleInterface));
}
return nil;
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h
index 783edada77..66700281ac 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.h
@@ -102,13 +102,14 @@
- (BOOL)qt_filterEvent:(NSEvent *)event;
@end
-@interface QNSApplication : NSApplication {
+@interface QT_MANGLE_NAMESPACE(QNSApplication) : NSApplication {
}
@end
QT_BEGIN_NAMESPACE
void qt_redirectNSApplicationSendEvent();
+void qt_resetNSApplicationSendEvent();
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm
index 5b646d8942..a50c480f1f 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm
@@ -75,6 +75,7 @@
#include <qcocoaapplication.h>
+#include <qcocoaintrospection.h>
#include <qcocoaapplicationdelegate.h>
#include <qcocoahelpers.h>
#include <qguiapplication.h>
@@ -107,8 +108,6 @@ QT_USE_NAMESPACE
- (void)qt_sendPostedMessage:(NSEvent *)event
{
- Q_UNUSED(event);
-/*
// WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5!
// That is why we need to split the address in two parts:
quint64 lower = [event data1];
@@ -131,14 +130,14 @@ QT_USE_NAMESPACE
}
delete args;
-*/
}
+static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSEvent");
+
- (BOOL)qt_filterEvent:(NSEvent *)event
{
- Q_UNUSED(event);
-/*
- if (qApp && qApp->macEventFilter(0, reinterpret_cast<EventRef>(event)))
+ if (qApp && qApp->eventDispatcher()->
+ filterNativeEvent(q_macLocalEventType, static_cast<void*>(event), 0))
return true;
if ([event type] == NSApplicationDefined) {
@@ -150,13 +149,13 @@ QT_USE_NAMESPACE
break;
}
}
-*/
+
return false;
}
@end
-@implementation QNSApplication
+@implementation QT_MANGLE_NAMESPACE(QNSApplication)
- (void)qt_sendEvent_original:(NSEvent *)event
{
@@ -190,8 +189,7 @@ QT_BEGIN_NAMESPACE
void qt_redirectNSApplicationSendEvent()
{
-/*
- if ([NSApp isMemberOfClass:[QNSApplication class]]) {
+ if ([NSApp isMemberOfClass:[QT_MANGLE_NAMESPACE(QNSApplication) class]]) {
// No need to change implementation since Qt
// already controls a subclass of NSApplication
return;
@@ -204,10 +202,16 @@ void qt_redirectNSApplicationSendEvent()
qt_cocoa_change_implementation(
[NSApplication class],
@selector(sendEvent:),
- [QNSApplication class],
+ [QT_MANGLE_NAMESPACE(QNSApplication) class],
@selector(qt_sendEvent_replacement:),
@selector(qt_sendEvent_original:));
- */
}
+void qt_resetNSApplicationSendEvent()
+{
+ qt_cocoa_change_back_implementation([NSApplication class],
+ @selector(sendEvent:),
+ @selector(QT_MANGLE_NAMESPACE(qt_sendEvent_original):));
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 3023100d93..d44ff0fae1 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -344,12 +344,6 @@ static void cleanupCocoaApplicationDelegate()
*/
}
-- (void)applicationDidChangeScreenParameters:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- ((QCocoaIntegration*)QGuiApplicationPrivate::platformIntegration())->updateScreens();
-}
-
- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate
{
[oldDelegate retain];
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index eb0eb77905..ef67275208 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -73,15 +73,12 @@ void QCocoaBackingStore::flush(QWindow *widget, const QRegion &region, const QPo
NSRect rect = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height());
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
if (cocoaWindow) {
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
- // Workaround for malfunctioning displayRect on 10.8 where
- // calling it seems to have no effect. Call setImage like
- // resize() does.
- [cocoaWindow->m_contentView setImage:m_image];
- }
-#endif
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ // Workaround for malfunctioning displayRect on 10.8 where
+ // calling it seems to have no effect. Call setImage like
+ // resize() does.
+ [cocoaWindow->m_contentView setImage:m_image];
+ }
[cocoaWindow->m_contentView displayRect:rect];
}
}
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index 45c35cccbf..de98d5219e 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -99,6 +99,7 @@ void qt_mac_transformProccessToForegroundApplication();
QString qt_mac_removeMnemonics(const QString &original);
CGColorSpaceRef qt_mac_genericColorSpace();
CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget);
+CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
QString qt_mac_applicationName();
inline int qt_mac_flipYCoordinate(int y)
@@ -129,6 +130,36 @@ bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret);
// accelerators.
QString qt_mac_removeAmpersandEscapes(QString s);
+enum {
+ QtCocoaEventSubTypeWakeup = SHRT_MAX,
+ QtCocoaEventSubTypePostMessage = SHRT_MAX-1
+};
+
+class QCocoaPostMessageArgs {
+public:
+ id target;
+ SEL selector;
+ int argCount;
+ id arg1;
+ id arg2;
+ QCocoaPostMessageArgs(id target, SEL selector, int argCount=0, id arg1=0, id arg2=0)
+ : target(target), selector(selector), argCount(argCount), arg1(arg1), arg2(arg2)
+ {
+ [target retain];
+ [arg1 retain];
+ [arg2 retain];
+ }
+
+ ~QCocoaPostMessageArgs()
+ {
+ [arg2 release];
+ [arg1 release];
+ [target release];
+ }
+};
+
+CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
+
QT_END_NAMESPACE
#endif //QCOCOAHELPERS_H
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index bd89f26fca..0a8da0a956 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -48,6 +48,10 @@
#include <qpa/qplatformscreen.h>
#include <private/qguiapplication_p.h>
+#ifndef QT_NO_WIDGETS
+#include <QtWidgets/QWidget>
+#endif
+
QT_BEGIN_NAMESPACE
//
@@ -551,6 +555,17 @@ void qt_mac_cleanUpMacColorSpaces()
m_displayColorSpaceHash.clear();
}
+CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice)
+{
+#ifdef QT_NO_WIDGETS
+ 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()
{
QString appName;
@@ -696,4 +711,44 @@ QString qt_mac_removeAmpersandEscapes(QString s)
return 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 Mac OS X.
+ \warning This function is duplicated in qmacstyle_mac.mm
+ */
+CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
+{
+ if (pdev->devType() == QInternal::Pixmap) {
+ const QPixmap *pm = static_cast<const QPixmap*>(pdev);
+ CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
+ uint flags = kCGImageAlphaPremultipliedFirst;
+ flags |= kCGBitmapByteOrder32Host;
+ CGContextRef ret = 0;
+
+ QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data();
+ if (data && data->classId() == QPlatformPixmap::RasterClass) {
+ QImage *image = data->buffer();
+ ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
+ 8, image->bytesPerLine(), colorspace, flags);
+ } else {
+ qDebug() << "qt_mac_cg_context: Unsupported pixmap class";
+ }
+
+ CGContextTranslateCTM(ret, 0, pm->height());
+ CGContextScaleCTM(ret, 1, -1);
+ return ret;
+ } else if (pdev->devType() == QInternal::Widget) {
+ //CGContextRef ret = static_cast<CGContextRef>(static_cast<const QWidget *>(pdev)->macCGHandle());
+ ///CGContextRetain(ret);
+ //return ret;
+ qDebug() << "qt_mac_cg_context: not implemented: Widget class";
+ return 0;
+ }
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 481055aae4..83c3efb2c6 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -53,6 +53,7 @@
#include "qcocoatheme.h"
#include "qcocoainputcontext.h"
#include "qmacmime.h"
+#include "qcocoaaccessibility.h"
#include <qpa/qplatformaccessibility.h>
#include <QtCore/qcoreapplication.h>
@@ -97,9 +98,8 @@ void QCocoaScreen::updateGeometry()
CGDirectDisplayID dpy = [[devDesc objectForKey:@"NSScreenNumber"] unsignedIntValue];
CGSize size = CGDisplayScreenSize(dpy);
m_physicalSize = QSizeF(size.width, size.height);
- NSSize resolution = [[devDesc valueForKey:NSDeviceResolution] sizeValue];
- m_logicalDpi.first = resolution.width;
- m_logicalDpi.second = resolution.height;
+ m_logicalDpi.first = 72;
+ m_logicalDpi.second = 72;
m_refreshRate = CGDisplayModeGetRefreshRate(CGDisplayCopyDisplayMode(dpy));
// Get m_name (brand/model of the monitor)
@@ -110,7 +110,7 @@ void QCocoaScreen::updateGeometry()
[deviceInfo release];
QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry());
- QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), resolution.width, resolution.height);
+ QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), m_logicalDpi.first, m_logicalDpi.second);
QWindowSystemInterface::handleScreenRefreshRateChange(screen(), m_refreshRate);
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), availableGeometry());
}
@@ -181,7 +181,7 @@ QCocoaIntegration::QCocoaIntegration()
, mEventDispatcher(new QCocoaEventDispatcher())
, mInputContext(new QCocoaInputContext)
#ifndef QT_NO_ACCESSIBILITY
- , mAccessibility(new QPlatformAccessibility)
+ , mAccessibility(new QCococaAccessibility)
#endif
, mCocoaClipboard(new QCocoaClipboard)
, mCocoaDrag(new QCocoaDrag)
@@ -193,7 +193,8 @@ QCocoaIntegration::QCocoaIntegration()
qApp->setAttribute(Qt::AA_DontUseNativeMenuBar, false);
- NSApplication *cocoaApplication = [NSApplication sharedApplication];
+ NSApplication *cocoaApplication = [QT_MANGLE_NAMESPACE(QNSApplication) sharedApplication];
+ qt_redirectNSApplicationSendEvent();
if (qEnvironmentVariableIsEmpty("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM")) {
// Applications launched from plain executables (without an app
@@ -234,6 +235,8 @@ QCocoaIntegration::QCocoaIntegration()
QCocoaIntegration::~QCocoaIntegration()
{
+ qt_resetNSApplicationSendEvent();
+
QCocoaAutoReleasePool pool;
if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
// remove the apple event handlers installed by QCocoaApplicationDelegate
diff --git a/src/plugins/platforms/cocoa/qcocoaintrospection.h b/src/plugins/platforms/cocoa/qcocoaintrospection.h
new file mode 100644
index 0000000000..ffe3d96290
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaintrospection.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include <qglobal.h>
+#import <objc/objc-class.h>
+
+QT_BEGIN_NAMESPACE
+
+void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class proxyClass, SEL replacementSel = 0, SEL backupSel = 0);
+void qt_cocoa_change_back_implementation(Class baseClass, SEL originalSel, SEL backupSel);
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaintrospection.mm b/src/plugins/platforms/cocoa/qcocoaintrospection.mm
new file mode 100644
index 0000000000..e1af986487
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaintrospection.mm
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include "qcocoaintrospection.h"
+
+QT_BEGIN_NAMESPACE
+
+void qt_cocoa_change_implementation(Class baseClass, SEL originalSel, Class proxyClass, SEL replacementSel, SEL backupSel)
+{
+#ifndef QT_MAC_USE_COCOA
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
+#endif
+ {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ // The following code replaces the _implementation_ for the selector we want to hack
+ // (originalSel) with the implementation found in proxyClass. Then it creates
+ // a new 'backup' method inside baseClass containing the old, original,
+ // implementation (fakeSel). You can let the proxy implementation of originalSel
+ // call fakeSel if needed (similar approach to calling a super class implementation).
+ // fakeSel must also be implemented in proxyClass, as the signature is used
+ // as template for the method one we add into baseClass.
+ // NB: You will typically never create any instances of proxyClass; we use it
+ // only for stealing its contents and put it into baseClass.
+ if (!replacementSel)
+ replacementSel = originalSel;
+
+ Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
+ Method replacementMethod = class_getInstanceMethod(proxyClass, replacementSel);
+ IMP originalImp = method_setImplementation(originalMethod, method_getImplementation(replacementMethod));
+
+ if (backupSel) {
+ Method backupMethod = class_getInstanceMethod(proxyClass, backupSel);
+ class_addMethod(baseClass, backupSel, originalImp, method_getTypeEncoding(backupMethod));
+ }
+#endif
+ }
+}
+
+void qt_cocoa_change_back_implementation(Class baseClass, SEL originalSel, SEL backupSel)
+{
+#ifndef QT_MAC_USE_COCOA
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
+#endif
+ {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ Method originalMethod = class_getInstanceMethod(baseClass, originalSel);
+ Method backupMethodInBaseClass = class_getInstanceMethod(baseClass, backupSel);
+ method_setImplementation(originalMethod, method_getImplementation(backupMethodInBaseClass));
+#endif
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 36d5c81f34..676f0683fa 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -45,6 +45,13 @@
#include "qcocoaautoreleasepool.h"
#include <QtCore/QtDebug>
+#include "qcocoaapplication.h"
+#include "qcocoamenuloader.h"
+
+static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
+{
+ return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
+}
@interface QT_MANGLE_NAMESPACE(QCocoaMenuDelegate) : NSObject <NSMenuDelegate> {
QCocoaMenu *m_menu;
@@ -215,12 +222,19 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem)
}
bool wasMerged = cocoaItem->isMerged();
- NSMenuItem *oldItem = [m_nativeMenu itemWithTag:(NSInteger) cocoaItem];
+ NSMenu *oldMenu = wasMerged ? [getMenuLoader() applicationMenu] : m_nativeMenu;
+ NSMenuItem *oldItem = [oldMenu itemWithTag:(NSInteger) cocoaItem];
if (cocoaItem->sync() != oldItem) {
// native item was changed for some reason
- if (!wasMerged && oldItem)
- [m_nativeMenu removeItem:oldItem];
+ if (oldItem) {
+ if (wasMerged) {
+ [oldItem setEnabled:NO];
+ [oldItem setHidden:YES];
+ } else {
+ [m_nativeMenu removeItem:oldItem];
+ }
+ }
QCocoaMenuItem* beforeItem = itemOrNull(m_menuItems.indexOf(cocoaItem) + 1);
insertNative(cocoaItem, beforeItem);
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index 8434cb75e9..bae52c91b8 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -219,7 +219,7 @@ QList<QCocoaMenuItem*> QCocoaMenuBar::merged() const
bool QCocoaMenuBar::shouldDisable(QCocoaWindow *active) const
{
- if (active && (active->window()->windowModality() == Qt::NonModal))
+ if (active && (active->window()->modality() == Qt::NonModal))
return false;
if (m_window == active) {
@@ -232,7 +232,7 @@ bool QCocoaMenuBar::shouldDisable(QCocoaWindow *active) const
// the menubar should be disabled. The exception in Qt is that if the
// modal window is the only window on screen, then we enable the menu bar.
foreach (QWindow *w, topWindows) {
- if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) {
+ if (w->isVisible() && w->modality() == Qt::ApplicationModal) {
// check for other visible windows
foreach (QWindow *other, topWindows) {
if ((w != other) && (other->isVisible())) {
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 2cb15b141f..8a08924bda 100755
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -79,7 +79,6 @@
#include "qcocoasystemtrayicon.h"
#include <qtemporaryfile.h>
#include <qimagewriter.h>
-#include <qapplication.h>
#include <qdebug.h>
#include "qcocoamenu.h"
@@ -238,7 +237,7 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess
return;
QPixmap notificationIconPixmap = icon.pixmap(32, 32);
QTemporaryFile notificationIconFile;
- QString notificationType(QLatin1String("Notification")), notificationIcon, notificationApp(QApplication::applicationName());
+ QString notificationType(QLatin1String("Notification")), notificationIcon, notificationApp(qt_mac_applicationName());
if (notificationApp.isEmpty())
notificationApp = QLatin1String("Application");
if (!notificationIconPixmap.isNull() && notificationIconFile.open()) {
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index db3a20c2be..a9ea135b3e 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -66,6 +66,8 @@ class QT_PREPEND_NAMESPACE(QCocoaWindow);
- (BOOL)canBecomeKeyWindow;
@end
+@class QNSWindowDelegate;
+
QT_BEGIN_NAMESPACE
// QCocoaWindow
//
@@ -157,6 +159,7 @@ public: // for QNSView
QNSView *m_contentView;
NSWindow *m_nsWindow;
+ QNSWindowDelegate *m_nsWindowDelegate;
Qt::WindowFlags m_windowFlags;
Qt::WindowState m_synchedWindowState;
Qt::WindowModality m_windowModality;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index de6e7dc43e..d17df81011 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -148,12 +148,10 @@ static bool isMouseEvent(NSEvent *ev)
- (BOOL)canBecomeKeyWindow
{
- // Most panels can be come the key window. Exceptions are:
- if (m_cocoaPlatformWindow->window()->windowType() == Qt::ToolTip)
- return NO;
- if (m_cocoaPlatformWindow->window()->windowType() == Qt::SplashScreen)
- return NO;
- return YES;
+ // Only tool windows should become key for popup types:
+ if (m_cocoaPlatformWindow->window()->type() == Qt::Tool)
+ return YES;
+ return NO;
}
- (void) sendEvent: (NSEvent*) theEvent
@@ -186,6 +184,7 @@ static bool isMouseEvent(NSEvent *ev)
QCocoaWindow::QCocoaWindow(QWindow *tlw)
: QPlatformWindow(tlw)
, m_nsWindow(0)
+ , m_nsWindowDelegate(0)
, m_synchedWindowState(Qt::WindowActive)
, m_windowModality(Qt::NonModal)
, m_inConstructor(true)
@@ -217,6 +216,7 @@ QCocoaWindow::~QCocoaWindow()
clearNSWindow(m_nsWindow);
[m_contentView release];
[m_nsWindow release];
+ [m_nsWindowDelegate release];
}
void QCocoaWindow::setGeometry(const QRect &rect)
@@ -250,7 +250,7 @@ void QCocoaWindow::setVisible(bool visible)
#endif
if (visible) {
// We need to recreate if the modality has changed as the style mask will need updating
- if (m_windowModality != window()->windowModality())
+ if (m_windowModality != window()->modality())
recreateWindow(parent());
QCocoaWindow *parentCocoaWindow = 0;
if (window()->transientParent()) {
@@ -262,8 +262,8 @@ void QCocoaWindow::setVisible(bool visible)
// Register popup windows so that the parent window can
// close them when needed.
- if (window()->windowType() == Qt::Popup) {
- // qDebug() << "transientParent and popup" << window()->windowType() << Qt::Popup << (window()->windowType() & Qt::Popup);
+ if (window()->type() == Qt::Popup) {
+ // qDebug() << "transientParent and popup" << window()->type() << Qt::Popup << (window()->type() & Qt::Popup);
parentCocoaWindow->m_activePopupWindow = window();
}
@@ -279,12 +279,12 @@ void QCocoaWindow::setVisible(bool visible)
syncWindowState(window()->windowState());
if (window()->windowState() != Qt::WindowMinimized) {
- if ((window()->windowModality() == Qt::WindowModal
- || window()->windowType() == Qt::Sheet)
+ if ((window()->modality() == Qt::WindowModal
+ || window()->type() == Qt::Sheet)
&& parentCocoaWindow) {
// show the window as a sheet
[NSApp beginSheet:m_nsWindow modalForWindow:parentCocoaWindow->m_nsWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
- } else if (window()->windowModality() != Qt::NonModal) {
+ } else if (window()->modality() != Qt::NonModal) {
// show the window as application modal
QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
Q_ASSERT(cocoaEventDispatcher != 0);
@@ -298,7 +298,7 @@ void QCocoaWindow::setVisible(bool visible)
}
// We want the events to properly reach the popup
- if (window()->windowType() == Qt::Popup)
+ if (window()->type() == Qt::Popup)
[(NSPanel *)m_nsWindow setWorksWhenModal:YES];
}
}
@@ -364,7 +364,7 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint;
if (flags == Qt::Window) {
styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask);
- } else if ((flags & Qt::Dialog) && (window()->windowModality() != Qt::NonModal)) {
+ } else if ((flags & Qt::Dialog) && (window()->modality() != Qt::NonModal)) {
styleMask = NSTitledWindowMask;
} else if (!(flags & Qt::FramelessWindowHint)) {
if (flags & Qt::WindowMaximizeButtonHint)
@@ -433,7 +433,7 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
NSButton *iconButton = [m_nsWindow standardWindowButton:NSWindowDocumentIconButton];
if (iconButton == nil) {
- NSString *title = QCFString::toNSString(window()->windowTitle());
+ NSString *title = QCFString::toNSString(window()->title());
[m_nsWindow setRepresentedURL:[NSURL fileURLWithPath:title]];
iconButton = [m_nsWindow standardWindowButton:NSWindowDocumentIconButton];
}
@@ -594,7 +594,7 @@ void QCocoaWindow::windowWillClose()
bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const
{
if (type == Qt::Widget)
- type = window()->windowType();
+ type = window()->type();
if (type == Qt::Tool)
return false; // Qt::Tool has the Popup bit set but isn't, at least on Mac.
@@ -619,6 +619,8 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
[m_nsWindow close];
[m_nsWindow release];
m_nsWindow = 0;
+ [m_nsWindowDelegate release];
+ m_nsWindowDelegate = 0;
}
if (!parentWindow) {
@@ -628,8 +630,8 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
// QPlatformWindow subclasses must sync up with QWindow on creation:
propagateSizeHints();
- setWindowFlags(window()->windowFlags());
- setWindowTitle(window()->windowTitle());
+ setWindowFlags(window()->flags());
+ setWindowTitle(window()->title());
setWindowState(window()->windowState());
} else {
// Child windows have no NSWindow, link the NSViews instead.
@@ -644,8 +646,8 @@ NSWindow * QCocoaWindow::createNSWindow()
NSRect frame = qt_mac_flipRect(window()->geometry(), window());
- Qt::WindowType type = window()->windowType();
- Qt::WindowFlags flags = window()->windowFlags();
+ Qt::WindowType type = window()->type();
+ Qt::WindowFlags flags = window()->flags();
NSUInteger styleMask = windowStyleMask(flags);
NSWindow *createdWindow = 0;
@@ -691,14 +693,14 @@ NSWindow * QCocoaWindow::createNSWindow()
NSInteger level = windowLevel(flags);
[createdWindow setLevel:level];
- m_windowModality = window()->windowModality();
+ m_windowModality = window()->modality();
return createdWindow;
}
void QCocoaWindow::setNSWindow(NSWindow *window)
{
- QNSWindowDelegate *delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
- [window setDelegate:delegate];
+ m_nsWindowDelegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
+ [window setDelegate:m_nsWindowDelegate];
[window setAcceptsMouseMovedEvents:YES];
// Prevent Cocoa from releasing the window on close. Qt
@@ -713,7 +715,9 @@ void QCocoaWindow::setNSWindow(NSWindow *window)
name:nil // Get all notifications
object:m_nsWindow];
+ [m_contentView setPostsFrameChangedNotifications: NO];
[window setContentView:m_contentView];
+ [m_contentView setPostsFrameChangedNotifications: YES];
}
void QCocoaWindow::clearNSWindow(NSWindow *window)
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm
index e7c03726d6..e8d12abaed 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.mm
+++ b/src/plugins/platforms/cocoa/qmacclipboard.mm
@@ -193,7 +193,10 @@ QMacPasteboard::hasOSType(int c_flavor) const
const int type_count = CFArrayGetCount(types);
for (int i = 0; i < type_count; ++i) {
CFStringRef flavor = (CFStringRef)CFArrayGetValueAtIndex(types, i);
- const int os_flavor = UTGetOSTypeFromString(UTTypeCopyPreferredTagWithClass(flavor, kUTTagClassOSType));
+ CFStringRef preferredTag = UTTypeCopyPreferredTagWithClass(flavor, kUTTagClassOSType);
+ const int os_flavor = UTGetOSTypeFromString(preferredTag);
+ if (preferredTag)
+ CFRelease(preferredTag);
if (os_flavor == c_flavor) {
#ifdef DEBUG_PASTEBOARD
qDebug(" - Found!");
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index d62913a7af..4fb099341e 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -263,6 +263,7 @@ static CGImageRef qt_mac_toCGImage(QImage *qImage, bool isMask, uchar **dataCopy
kCGRenderingIntentDefault);
CGColorSpaceRelease(cgColourSpaceRef);
}
+ CGDataProviderRelease(cgDataProviderRef);
return cgImage;
}
@@ -339,7 +340,7 @@ static CGImageRef qt_mac_toCGImage(QImage *qImage, bool isMask, uchar **dataCopy
return YES;
}
-- (void)handleMouseEvent:(NSEvent *)theEvent
+- (void)convertFromEvent:(NSEvent *)event toWindowPoint:(QPoint *)qtWindowPoint andScreenPoint:(QPoint *)qtScreenPoint
{
// Calculate the mouse position in the QWindow and Qt screen coordinate system,
// starting from coordinates in the NSWindow coordinate system.
@@ -359,25 +360,29 @@ static CGImageRef qt_mac_toCGImage(QImage *qImage, bool isMask, uchar **dataCopy
// NSView and QWindow are equal coordinate systems: the QWindow covers the
// entire NSView, and we've set the NSView's isFlipped property to true.
- NSPoint nsWindowPoint = [theEvent locationInWindow]; // NSWindow coordinates
+ NSPoint nsWindowPoint = [event locationInWindow]; // NSWindow coordinates
NSPoint nsViewPoint = [self convertPoint: nsWindowPoint fromView: nil]; // NSView/QWindow coordinates
- QPoint qtWindowPoint(nsViewPoint.x, nsViewPoint.y); // NSView/QWindow coordinates
-
- QPoint qtScreenPoint;
+ *qtWindowPoint = QPoint(nsViewPoint.x, nsViewPoint.y); // NSView/QWindow coordinates
NSWindow *window = [self window];
// Use convertRectToScreen if available (added in 10.7).
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if ([window respondsToSelector:@selector(convertRectToScreen:)]) {
NSRect screenRect = [window convertRectToScreen : NSMakeRect(nsWindowPoint.x, nsWindowPoint.y, 0, 0)]; // OS X screen coordinates
- qtScreenPoint = QPoint(screenRect.origin.x, qt_mac_flipYCoordinate(screenRect.origin.y)); // Qt screen coordinates
+ *qtScreenPoint = QPoint(screenRect.origin.x, qt_mac_flipYCoordinate(screenRect.origin.y)); // Qt screen coordinates
} else
#endif
{
NSPoint screenPoint = [window convertBaseToScreen : NSMakePoint(nsWindowPoint.x, nsWindowPoint.y)];
- qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
+ *qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
}
+}
+
+- (void)handleMouseEvent:(NSEvent *)theEvent
+{
+ QPoint qtWindowPoint, qtScreenPoint;
+ [self convertFromEvent:theEvent toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
ulong timestamp = [theEvent timestamp] * 1000;
QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
@@ -462,8 +467,9 @@ static CGImageRef qt_mac_toCGImage(QImage *qImage, bool isMask, uchar **dataCopy
- (void)mouseEntered:(NSEvent *)theEvent
{
- Q_UNUSED(theEvent);
- QWindowSystemInterface::handleEnterEvent(m_window);
+ QPoint windowPoint, screenPoint;
+ [self convertFromEvent:theEvent toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleEnterEvent(m_window, windowPoint, screenPoint);
}
- (void)mouseExited:(NSEvent *)theEvent
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
index 404c03dd30..5b83477881 100644
--- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
@@ -116,13 +116,6 @@ void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig
}
}
-CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice)
-{
- bool isWidget = (paintDevice->devType() == QInternal::Widget);
- return QCoreGraphicsPaintEngine::macDisplayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice)
- : 0);
-}
-
// Implemented for qt_mac_p.h
QMacCGContext::QMacCGContext(QPainter *p)
{
@@ -206,46 +199,6 @@ CGAffineTransform qt_mac_convert_transform_to_cg(const QTransform &t) {
return CGAffineTransformMake(t.m11(), t.m12(), t.m21(), t.m22(), t.dx(), t.dy());
}
-/*! \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 Mac OS X.
- \warning This function is duplicated in qmacstyle_mac.mm
-*/
-CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
-{
- if (pdev->devType() == QInternal::Pixmap) {
- const QPixmap *pm = static_cast<const QPixmap*>(pdev);
- CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
- uint flags = kCGImageAlphaPremultipliedFirst;
- flags |= kCGBitmapByteOrder32Host;
- CGContextRef ret = 0;
-
- QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data();
- if (data && data->classId() == QPlatformPixmap::RasterClass) {
- QImage *image = data->buffer();
- ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
- 8, image->bytesPerLine(), colorspace, flags);
- } else {
- qDebug() << "qt_mac_cg_context: Unsupported pixmap class";
- }
-
- CGContextTranslateCTM(ret, 0, pm->height());
- CGContextScaleCTM(ret, 1, -1);
- return ret;
- } else if (pdev->devType() == QInternal::Widget) {
- //CGContextRef ret = static_cast<CGContextRef>(static_cast<const QWidget *>(pdev)->macCGHandle());
- ///CGContextRetain(ret);
- //return ret;
- qDebug() << "qt_mac_cg_context: not implemented: Widget class";
- return 0;
- }
- return 0;
-}
-
inline static QCFType<CGColorRef> cgColorForQColor(const QColor &col, QPaintDevice *pdev)
{
CGFloat components[] = {
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index adb92741f9..d35ec935fd 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -130,6 +130,7 @@ QQnxIntegration::QQnxIntegration()
#if !defined(QT_NO_CLIPBOARD)
, m_clipboard(0)
#endif
+ , m_navigator(0)
#if !defined(QT_NO_DRAGANDDROP)
, m_drag(new QSimpleDrag())
#endif
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 592586fde0..04fe558541 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -87,7 +87,7 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
QWindowsWindow *rw = QWindowsWindow::baseWindowOf(window);
#ifndef Q_OS_WINCE
- if (rw->format().hasAlpha() && (window->windowFlags() & Qt::FramelessWindowHint)) {
+ if (rw->format().hasAlpha() && (window->flags() & Qt::FramelessWindowHint)) {
const long wl = GetWindowLong(rw->handle(), GWL_EXSTYLE);
if ((wl & WS_EX_LAYERED) == 0)
SetWindowLong(rw->handle(), GWL_EXSTYLE, wl | WS_EX_LAYERED);
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index a0749388f9..aaa5573899 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -374,7 +374,7 @@ void QWindowsContext::setKeyGrabber(QWindow *w)
QString QWindowsContext::registerWindowClass(const QWindow *w, bool isGL)
{
- const Qt::WindowFlags flags = w ? w->windowFlags() : (Qt::WindowFlags)0;
+ const Qt::WindowFlags flags = w ? w->flags() : (Qt::WindowFlags)0;
const Qt::WindowFlags type = flags & Qt::WindowType_Mask;
uint style = 0;
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 323cff1646..76fe5f1a43 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -533,7 +533,7 @@ QWindowsFontEngineData::QWindowsFontEngineData()
QWindowsFontEngineData::~QWindowsFontEngineData()
{
if (hdc)
- ReleaseDC(0, hdc);
+ DeleteDC(hdc);
#if !defined(QT_NO_DIRECTWRITE)
if (directWriteGdiInterop)
directWriteGdiInterop->Release();
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 0e592aee7b..578a0cd20b 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -1110,7 +1110,7 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph,
SetGraphicsMode(hdc, GM_COMPATIBLE);
SelectObject(hdc, old_font);
- ReleaseDC(0, hdc);
+ DeleteDC(hdc);
}
#else // else wince
unsigned int options = 0;
@@ -1166,8 +1166,11 @@ QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xfo
mask_format = QImage::Format_RGB32;
QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format);
- if (mask == 0)
+ if (mask == 0) {
+ if (m_fontEngineData->clearTypeEnabled)
+ DeleteObject(font);
return QImage();
+ }
QImage indexed(mask->width(), mask->height(), QImage::Format_Indexed8);
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index a02f0cd494..f6011ae082 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -354,10 +354,10 @@ QPlatformPixmap *QWindowsIntegration::createPlatformPixmap(QPlatformPixmap::Pixe
QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
{
QWindowsWindow::WindowData requested;
- requested.flags = window->windowFlags();
+ requested.flags = window->flags();
requested.geometry = window->geometry();
const QWindowsWindow::WindowData obtained
- = QWindowsWindow::WindowData::create(window, requested, window->windowTitle());
+ = QWindowsWindow::WindowData::create(window, requested, window->title());
if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
qDebug().nospace()
<< __FUNCTION__ << '<' << window << '\n'
@@ -372,7 +372,7 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
if (!obtained.hwnd)
return 0;
if (requested.flags != obtained.flags)
- window->setWindowFlags(obtained.flags);
+ window->setFlags(obtained.flags);
return new QWindowsWindow(window, obtained);
}
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index c11bd8c53c..5a11aee802 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -481,6 +481,14 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer,
int code = 0;
QChar unicodeBuffer[5];
int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
+ // When Ctrl modifier is used ToUnicode does not return correct values. In order to assign the
+ // right key the control modifier is removed for just that function if the previous call failed.
+ if (res == 0 && kbdBuffer[VK_CONTROL]) {
+ const unsigned char controlState = kbdBuffer[VK_CONTROL];
+ kbdBuffer[VK_CONTROL] = 0;
+ res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
+ kbdBuffer[VK_CONTROL] = controlState;
+ }
if (res)
code = unicodeBuffer[0].toUpper().unicode();
@@ -682,16 +690,16 @@ static void showSystemMenu(QWindow* w)
#define enabled (MF_BYCOMMAND | MF_ENABLED)
#define disabled (MF_BYCOMMAND | MF_GRAYED)
- EnableMenuItem(menu, SC_MINIMIZE, (topLevel->windowFlags() & Qt::WindowMinimizeButtonHint)?enabled:disabled);
+ EnableMenuItem(menu, SC_MINIMIZE, (topLevel->flags() & Qt::WindowMinimizeButtonHint)?enabled:disabled);
bool maximized = IsZoomed(topLevelHwnd);
- EnableMenuItem(menu, SC_MAXIMIZE, ! (topLevel->windowFlags() & Qt::WindowMaximizeButtonHint) || maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_MAXIMIZE, ! (topLevel->flags() & Qt::WindowMaximizeButtonHint) || maximized?disabled:enabled);
EnableMenuItem(menu, SC_RESTORE, maximized?enabled:disabled);
// We should _not_ check with the setFixedSize(x,y) case here, since Windows is not able to check
// this and our menu here would be out-of-sync with the menu produced by mouse-click on the
// System Menu, or right-click on the title bar.
- EnableMenuItem(menu, SC_SIZE, (topLevel->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) || maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_SIZE, (topLevel->flags() & Qt::MSWindowsFixedSizeDialogHint) || maximized?disabled:enabled);
EnableMenuItem(menu, SC_MOVE, maximized?disabled:enabled);
EnableMenuItem(menu, SC_CLOSE, enabled);
// Set bold on close menu item
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 2d60c87438..d202da1d31 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -129,7 +129,9 @@ static inline void compressMouseMove(MSG *msg)
QWindowsMouseHandler::QWindowsMouseHandler() :
m_windowUnderMouse(0),
m_trackedWindow(0),
- m_touchDevice(0)
+ m_touchDevice(0),
+ m_leftButtonDown(false),
+ m_previousCaptureWindow(0)
{
}
@@ -143,6 +145,10 @@ Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
result |= mouseSwapped ? Qt::LeftButton : Qt::RightButton;
if (GetAsyncKeyState(VK_MBUTTON) < 0)
result |= Qt::MidButton;
+ if (GetAsyncKeyState(VK_XBUTTON1) < 0)
+ result |= Qt::XButton1;
+ if (GetAsyncKeyState(VK_XBUTTON2) < 0)
+ result |= Qt::XButton2;
return result;
}
@@ -164,7 +170,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
return false; // Allow further event processing (dragging of windows).
}
-
*result = 0;
if (msg.message == WM_MOUSELEAVE) {
if (QWindowsContext::verboseEvents)
@@ -185,6 +190,36 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
+ const Qt::MouseButtons buttons = keyStateToMouseButtons((int)msg.wParam);
+
+ // If the window was recently resized via mouse doubleclick on the frame or title bar,
+ // we don't get WM_LBUTTONDOWN or WM_LBUTTONDBLCLK for the second click,
+ // but we will get at least one WM_MOUSEMOVE with left button down and the WM_LBUTTONUP,
+ // which will result undesired mouse press and release events.
+ // To avoid those, we ignore any events with left button down if we didn't
+ // get the original WM_LBUTTONDOWN/WM_LBUTTONDBLCLK.
+ if (msg.message == WM_LBUTTONDOWN || msg.message == WM_LBUTTONDBLCLK) {
+ m_leftButtonDown = true;
+ } else {
+ const bool actualLeftDown = buttons & Qt::LeftButton;
+ if (!m_leftButtonDown && actualLeftDown) {
+ // Autocapture the mouse for current window to and ignore further events until release.
+ // Capture is necessary so we don't get WM_MOUSELEAVEs to confuse matters.
+ // This autocapture is released normally when button is released.
+ if (!platformWindow->hasMouseCapture()) {
+ QWindowsWindow::baseWindowOf(window)->applyCursor();
+ platformWindow->setMouseGrabEnabled(true);
+ platformWindow->setFlag(QWindowsWindow::AutoMouseCapture);
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "Automatic mouse capture for missing buttondown event" << window;
+ }
+ m_previousCaptureWindow = window;
+ return true;
+ } else if (m_leftButtonDown && !actualLeftDown) {
+ m_leftButtonDown = false;
+ }
+ }
+
const QPoint globalPosition = QWindowsGeometryHint::mapToGlobal(hwnd, winEventPosition);
QWindow *currentWindowUnderMouse = platformWindow->hasMouseCapture() ?
QWindowsScreen::windowAt(globalPosition) : window;
@@ -194,7 +229,9 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
// any button press until release.
if (!platformWindow->hasMouseCapture()
&& (msg.message == WM_LBUTTONDOWN || msg.message == WM_MBUTTONDOWN
- || msg.message == WM_RBUTTONDOWN)) {
+ || msg.message == WM_RBUTTONDOWN || msg.message == WM_XBUTTONDOWN
+ || msg.message == WM_LBUTTONDBLCLK || msg.message == WM_MBUTTONDBLCLK
+ || msg.message == WM_RBUTTONDBLCLK || msg.message == WM_XBUTTONDBLCLK)) {
platformWindow->setMouseGrabEnabled(true);
platformWindow->setFlag(QWindowsWindow::AutoMouseCapture);
if (QWindowsContext::verboseEvents)
@@ -202,27 +239,20 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
} else if (platformWindow->hasMouseCapture()
&& platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)
&& (msg.message == WM_LBUTTONUP || msg.message == WM_MBUTTONUP
- || msg.message == WM_RBUTTONUP)) {
+ || msg.message == WM_RBUTTONUP || msg.message == WM_XBUTTONUP)
+ && !buttons) {
platformWindow->setMouseGrabEnabled(false);
if (QWindowsContext::verboseEvents)
qDebug() << "Releasing automatic mouse capture " << window;
}
- // Eat mouse move after size grip drag.
- if (msg.message == WM_MOUSEMOVE) {
- if (platformWindow->testFlag(QWindowsWindow::SizeGripOperation)) {
- MSG mouseMsg;
- while (PeekMessage(&mouseMsg, platformWindow->handle(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) ;
- platformWindow->clearFlag(QWindowsWindow::SizeGripOperation);
- return true;
- }
- }
+ const bool hasCapture = platformWindow->hasMouseCapture();
+ const bool currentNotCapturing = hasCapture && currentWindowUnderMouse != window;
#ifndef Q_OS_WINCE
// Enter new window: track to generate leave event.
- // If there is an active capture, we must track the actual capture window instead of window
- // under cursor or leaves will trigger constantly, so always track the window we got
- // native mouse event for.
- if (window != m_trackedWindow) {
+ // If there is an active capture, only track if the current window is capturing,
+ // so we don't get extra leave when cursor leaves the application.
+ if (window != m_trackedWindow && !currentNotCapturing) {
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
@@ -234,38 +264,53 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
#endif // !Q_OS_WINCE
- // Qt expects enter/leave events for windows even when some window is capturing mouse input,
- // except for automatic capture when mouse button is pressed - in that case enter/leave
- // should be sent only after the last button is released.
- // We need to track m_windowUnderMouse separately from m_trackedWindow, as
- // Windows mouse tracking will not trigger WM_MOUSELEAVE for leaving window when
- // mouse capture is set.
- if (!platformWindow->hasMouseCapture()
- || !platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)) {
- if (m_windowUnderMouse != currentWindowUnderMouse) {
- if (m_windowUnderMouse) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "Synthetic leave for " << m_windowUnderMouse;
- QWindowSystemInterface::handleLeaveEvent(m_windowUnderMouse);
- // Clear tracking if we are no longer over application,
- // since we have already sent the leave.
- if (!currentWindowUnderMouse)
- m_trackedWindow = 0;
- }
-
- if (currentWindowUnderMouse) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "Entering " << currentWindowUnderMouse;
- QWindowsWindow::baseWindowOf(currentWindowUnderMouse)->applyCursor();
- QWindowSystemInterface::handleEnterEvent(currentWindowUnderMouse);
+ // No enter or leave events are sent as long as there is an autocapturing window.
+ if (!hasCapture || !platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)) {
+ // Leave is needed if:
+ // 1) There is no capture and we move from a window to another window.
+ // Note: Leaving the application entirely is handled in WM_MOUSELEAVE case.
+ // 2) There is capture and we move out of the capturing window.
+ // 3) There is a new capture and we were over another window.
+ if ((m_windowUnderMouse && m_windowUnderMouse != currentWindowUnderMouse
+ && (!hasCapture || window == m_windowUnderMouse))
+ || (hasCapture && m_previousCaptureWindow != window && m_windowUnderMouse
+ && m_windowUnderMouse != window)) {
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "Synthetic leave for " << m_windowUnderMouse;
+ QWindowSystemInterface::handleLeaveEvent(m_windowUnderMouse);
+ if (currentNotCapturing) {
+ // Clear tracking if capturing and current window is not the capturing window
+ // to avoid leave when mouse actually leaves the application.
+ m_trackedWindow = 0;
+ // We are not officially in any window, but we need to set some cursor to clear
+ // whatever cursor the left window had, so apply the cursor of the capture window.
+ QWindowsWindow::baseWindowOf(window)->applyCursor();
}
}
+ // Enter is needed if:
+ // 1) There is no capture and we move to a new window.
+ // 2) There is capture and we move into the capturing window.
+ // 3) The capture just ended and we are over non-capturing window.
+ if ((currentWindowUnderMouse && m_windowUnderMouse != currentWindowUnderMouse
+ && (!hasCapture || currentWindowUnderMouse == window))
+ || (m_previousCaptureWindow && window != m_previousCaptureWindow && currentWindowUnderMouse
+ && currentWindowUnderMouse != m_previousCaptureWindow)) {
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "Entering " << currentWindowUnderMouse;
+ QWindowsWindow::baseWindowOf(currentWindowUnderMouse)->applyCursor();
+ QWindowSystemInterface::handleEnterEvent(currentWindowUnderMouse,
+ currentWindowUnderMouse->mapFromGlobal(globalPosition),
+ globalPosition);
+ }
+ // We need to track m_windowUnderMouse separately from m_trackedWindow, as
+ // Windows mouse tracking will not trigger WM_MOUSELEAVE for leaving window when
+ // mouse capture is set.
m_windowUnderMouse = currentWindowUnderMouse;
}
- QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition,
- keyStateToMouseButtons((int)msg.wParam),
+ QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
QWindowsKeyMapper::queryKeyboardModifiers());
+ m_previousCaptureWindow = hasCapture ? window : 0;
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
index 1b19b34458..965deb4e0f 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.h
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -81,6 +81,8 @@ private:
QPointer<QWindow> m_trackedWindow;
QHash<DWORD, int> m_touchInputIDToTouchPointID;
QTouchDevice *m_touchDevice;
+ bool m_leftButtonDown;
+ QWindow *m_previousCaptureWindow;
};
Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(int wParam)
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 0717a8ec60..a09ab583c8 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -125,11 +125,19 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM
Qt::PortraitOrientation : Qt::LandscapeOrientation;
// EnumDisplayMonitors (as opposed to EnumDisplayDevices) enumerates only
// virtual desktop screens.
+ data.name = QString::fromWCharArray(info.szDevice);
data.flags = QWindowsScreenData::VirtualDesktop;
- if (info.dwFlags & MONITORINFOF_PRIMARY)
+ if (info.dwFlags & MONITORINFOF_PRIMARY) {
data.flags |= QWindowsScreenData::PrimaryScreen;
- data.name = QString::fromWCharArray(info.szDevice);
- result->append(data);
+ // QPlatformIntegration::screenAdded() documentation specifies that first
+ // added screen will be the primary screen, so order accordingly.
+ // Note that the side effect of this policy is that there is no way to change primary
+ // screen reported by Qt, unless we want to delete all existing screens and add them
+ // again whenever primary screen changes.
+ result->prepend(data);
+ } else {
+ result->append(data);
+ }
return TRUE;
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 9aada91e73..25aae11d87 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -715,7 +715,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
setFlag(OpenGLSurface);
QWindowsContext::instance()->addWindow(m_data.hwnd, this);
if (aWindow->isTopLevel()) {
- switch (aWindow->windowType()) {
+ switch (aWindow->type()) {
case Qt::Window:
case Qt::Dialog:
case Qt::Sheet:
@@ -893,8 +893,8 @@ void QWindowsWindow::show_sys() const
int sm = SW_SHOWNORMAL;
bool fakedMaximize = false;
const QWindow *w = window();
- const Qt::WindowFlags flags = w->windowFlags();
- const Qt::WindowType type = w->windowType();
+ const Qt::WindowFlags flags = w->flags();
+ const Qt::WindowType type = w->type();
if (w->isTopLevel()) {
const Qt::WindowState state = w->windowState();
if (state & Qt::WindowMinimized) {
@@ -931,7 +931,7 @@ void QWindowsWindow::show_sys() const
// partially from QWidgetPrivate::hide_sys()
void QWindowsWindow::hide_sys() const
{
- const Qt::WindowFlags flags = window()->windowFlags();
+ const Qt::WindowFlags flags = window()->flags();
if (flags != Qt::Desktop) {
if (flags & Qt::Popup)
ShowWindow(m_data.hwnd, SW_HIDE);
@@ -979,7 +979,7 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
// to dialog frames, etc (see SetParent() ) if the top level state changes.
if (wasTopLevel != isTopLevel) {
const unsigned flags = isTopLevel ? unsigned(0) : unsigned(WindowCreationData::ForceChild);
- setWindowFlags_sys(window()->windowFlags(), flags);
+ setWindowFlags_sys(window()->flags(), flags);
}
}
}
diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README
index 59d9ffe39b..2f666bebfd 100644
--- a/src/plugins/platforms/xcb/README
+++ b/src/plugins/platforms/xcb/README
@@ -1,5 +1,7 @@
Requires libxcb >= 1.5.
+PACKAGE DEPENDENCIES
+
Required packages:
libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev
@@ -13,3 +15,9 @@ libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-d
On Fedora, the following packages are required:
libxcb libxcb-devel libXrender libXrender-devel xcb-util-wm xcb-util-wm-devel xcb-util xcb-util-devel xcb-util-image xcb-util-image-devel xcb-util-keysyms xcb-util-keysyms-devel
+
+REDUCING RUNTIME DEPENDENCIES
+
+The '-qt-xcb' configure option can be used to get rid of most xcb- dependencies. Only libxcb will
+still be linked dynamically, since it will be most likely be pulled in via other dependencies anyway.
+This should allow for binaries that are portable across most modern Linux distributions.
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index 8c300d6c19..10aaa5a3b5 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -86,6 +86,7 @@ static Window createDummyWindow(QXcbScreen *screen, XVisualInfo *visualInfo)
0, 0, 100, 100,
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWBackPixel|CWBorderPixel|CWColormap, &a);
+ XFreeColormap(DISPLAY_FROM_XCB(screen), cmap);
return window;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 85f6fc9213..405a16d488 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -58,6 +58,7 @@
#include <QTimer>
#include <QByteArray>
+#include <dlfcn.h>
#include <stdio.h>
#include <errno.h>
#include <xcb/shm.h>
@@ -281,17 +282,16 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char
qFatal("QXcbConnection: Could not connect to display %s", m_displayName.constData());
m_reader = new QXcbEventReader(this);
-#ifdef XCB_POLL_FOR_QUEUED_EVENT
connect(m_reader, SIGNAL(eventPending()), this, SLOT(processXcbEvents()), Qt::QueuedConnection);
- m_reader->start();
-#else
- QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));
-
- QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
- connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
- connect(dispatcher, SIGNAL(awake()), this, SLOT(processXcbEvents()));
-#endif
+ connect(m_reader, SIGNAL(finished()), this, SLOT(processXcbEvents()));
+ if (!m_reader->startThread()) {
+ QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));
+
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
+ connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
+ connect(dispatcher, SIGNAL(awake()), this, SLOT(processXcbEvents()));
+ }
xcb_extension_t *extensions[] = {
&xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id,
@@ -363,10 +363,11 @@ QXcbConnection::~QXcbConnection()
finalizeXInput2();
#endif
-#ifdef XCB_POLL_FOR_QUEUED_EVENT
- sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION);
- m_reader->wait();
-#endif
+ if (m_reader->isRunning()) {
+ sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION);
+ m_reader->wait();
+ }
+
delete m_reader;
#ifdef XCB_USE_EGL
@@ -807,14 +808,37 @@ void QXcbConnection::addPeekFunc(PeekFunc f)
m_peekFuncs.append(f);
}
-#ifdef XCB_POLL_FOR_QUEUED_EVENT
+QXcbEventReader::QXcbEventReader(QXcbConnection *connection)
+ : m_connection(connection)
+ , m_xcb_poll_for_queued_event(0)
+{
+#ifdef RTLD_DEFAULT
+ m_xcb_poll_for_queued_event = (XcbPollForQueuedEventFunctionPointer)dlsym(RTLD_DEFAULT, "xcb_poll_for_queued_event");
+#endif
+
+#ifdef Q_XCB_DEBUG
+ if (m_xcb_poll_for_queued_event)
+ qDebug("Using threaded event reader with xcb_poll_for_queued_event");
+#endif
+}
+
+bool QXcbEventReader::startThread()
+{
+ if (m_xcb_poll_for_queued_event) {
+ QThread::start();
+ return true;
+ }
+
+ return false;
+}
+
void QXcbEventReader::run()
{
xcb_generic_event_t *event;
while (m_connection && (event = xcb_wait_for_event(m_connection->xcb_connection()))) {
m_mutex.lock();
addEvent(event);
- while (m_connection && (event = xcb_poll_for_queued_event(m_connection->xcb_connection())))
+ while (m_connection && (event = m_xcb_poll_for_queued_event(m_connection->xcb_connection())))
addEvent(event);
m_mutex.unlock();
emit eventPending();
@@ -823,7 +847,6 @@ void QXcbEventReader::run()
for (int i = 0; i < m_events.size(); ++i)
free(m_events.at(i));
}
-#endif
void QXcbEventReader::addEvent(xcb_generic_event_t *event)
{
@@ -836,10 +859,10 @@ void QXcbEventReader::addEvent(xcb_generic_event_t *event)
QXcbEventArray *QXcbEventReader::lock()
{
m_mutex.lock();
-#ifndef XCB_POLL_FOR_QUEUED_EVENT
- while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection->xcb_connection()))
- m_events << event;
-#endif
+ if (!m_xcb_poll_for_queued_event) {
+ while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection->xcb_connection()))
+ m_events << event;
+ }
return &m_events;
}
@@ -919,6 +942,12 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
void QXcbConnection::processXcbEvents()
{
+ int connection_error = xcb_connection_has_error(xcb_connection());
+ if (connection_error) {
+ qWarning("The X11 connection broke (error %d). Did the X11 server die?", connection_error);
+ exit(1);
+ }
+
QXcbEventArray *eventqueue = m_reader->lock();
for(int i = 0; i < eventqueue->size(); ++i) {
@@ -932,6 +961,30 @@ void QXcbConnection::processXcbEvents()
if (!response_type) {
handleXcbError((xcb_generic_error_t *)event);
} else {
+ if (response_type == XCB_MOTION_NOTIFY) {
+ // compress multiple motion notify events in a row
+ // to avoid swamping the event queue
+ xcb_generic_event_t *next = eventqueue->value(i+1, 0);
+ if (next && (next->response_type & ~0x80) == XCB_MOTION_NOTIFY)
+ continue;
+ }
+
+ if (response_type == XCB_CONFIGURE_NOTIFY) {
+ // compress multiple configure notify events for the same window
+ bool found = false;
+ for (int j = i; j < eventqueue->size(); ++j) {
+ xcb_generic_event_t *other = eventqueue->at(j);
+ if (other && (other->response_type & ~0x80) == XCB_CONFIGURE_NOTIFY
+ && ((xcb_configure_notify_event_t *)other)->event == ((xcb_configure_notify_event_t *)event)->event)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ continue;
+ }
+
QVector<PeekFunc>::iterator it = m_peekFuncs.begin();
while (it != m_peekFuncs.end()) {
// These callbacks return true if the event is what they were
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 8b2315c67e..c67acb3218 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -278,18 +278,15 @@ class QXcbEventReader : public QThread
{
Q_OBJECT
public:
- QXcbEventReader(QXcbConnection *connection)
- : m_connection(connection)
- {
- }
+ QXcbEventReader(QXcbConnection *connection);
-#ifdef XCB_POLL_FOR_QUEUED_EVENT
void run();
-#endif
QXcbEventArray *lock();
void unlock();
+ bool startThread();
+
signals:
void eventPending();
@@ -299,6 +296,9 @@ private:
QMutex m_mutex;
QXcbEventArray m_events;
QXcbConnection *m_connection;
+
+ typedef xcb_generic_event_t * (*XcbPollForQueuedEventFunctionPointer)(xcb_connection_t *c);
+ XcbPollForQueuedEventFunctionPointer m_xcb_poll_for_queued_event;
};
class QAbstractEventDispatcher;
@@ -376,6 +376,8 @@ public:
bool hasXRandr() const { return has_randr_extension; }
bool hasInputShape() const { return has_input_shape; }
+ bool supportsThreadedRendering() const { return m_reader->isRunning(); }
+
xcb_timestamp_t getTimestamp();
private slots:
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 27a926eca2..cd7237e4b4 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -396,7 +396,7 @@ void QXcbDrag::move(const QMouseEvent *me)
QXcbWindow *w = 0;
if (target) {
w = connection()->platformWindowFromId(target);
- if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ if (w && (w->window()->type() == Qt::Desktop) /*&& !w->acceptDrops()*/)
w = 0;
} else {
w = 0;
@@ -507,7 +507,7 @@ void QXcbDrag::drop(const QMouseEvent *event)
QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
- if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ if (w && (w->window()->type() == Qt::Desktop) /*&& !w->acceptDrops()*/)
w = 0;
Transaction t = {
@@ -722,7 +722,7 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
p -= geometry.topLeft();
- if (!w || (w->windowType() == Qt::Desktop))
+ if (!w || (w->type() == Qt::Desktop))
return;
if (e->data.data32[0] != xdnd_dragsource) {
@@ -912,7 +912,7 @@ void QXcbDrag::send_leave()
QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
- if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ if (w && (w->window()->type() == Qt::Desktop) /*&& !w->acceptDrops()*/)
w = 0;
if (w)
@@ -1157,7 +1157,7 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
DNDDEBUG << "xdndEnable" << w << on;
if (on) {
QXcbWindow *xdnd_widget = 0;
- if ((w->window()->windowType() == Qt::Desktop)) {
+ if ((w->window()->type() == Qt::Desktop)) {
if (desktop_proxy) // *WE* already have one.
return false;
@@ -1191,7 +1191,7 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
return false;
}
} else {
- if ((w->window()->windowType() == Qt::Desktop)) {
+ if ((w->window()->type() == Qt::Desktop)) {
xcb_delete_property(xcb_connection(), w->xcb_window(), atom(QXcbAtom::XdndProxy));
delete desktop_proxy;
desktop_proxy = 0;
@@ -1225,7 +1225,7 @@ QVariant QXcbDropData::xdndObtainData(const QByteArray &format, QVariant::Type r
QXcbConnection *c = drag->connection();
QXcbWindow *xcb_window = c->platformWindowFromId(drag->xdnd_dragsource);
- if (xcb_window && drag->currentDrag() && xcb_window->window()->windowType() != Qt::Desktop) {
+ if (xcb_window && drag->currentDrag() && xcb_window->window()->type() != Qt::Desktop) {
QMimeData *data = drag->currentDrag()->mimeData();
if (data->hasFormat(QLatin1String(format)))
result = data->data(QLatin1String(format));
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 2ffe53c04b..22e5386937 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -214,7 +214,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
#else
case OpenGL: return false;
#endif
- case ThreadedOpenGL: return false;
+ case ThreadedOpenGL: return m_connections.at(0)->supportsThreadedRendering();
case WindowMasks: return true;
case MultipleWindows: return true;
default: return QPlatformIntegration::hasCapability(cap);
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index a8542af156..d35ce181e3 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -53,6 +53,7 @@
#include <qpa/qplatforminputcontext.h>
#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformcursor.h>
#ifndef XK_ISO_Left_Tab
#define XK_ISO_Left_Tab 0xFE20
@@ -1106,9 +1107,15 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
filtered = inputContext->filterEvent(&event);
}
- if (!filtered)
+ if (!filtered) {
+ if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
+ const QPoint globalPos = window->screen()->handle()->cursor()->pos();
+ const QPoint pos = window->mapFromGlobal(globalPos);
+ QWindowSystemInterface::handleContextMenuEvent(window, false, pos, globalPos, modifiers);
+ }
QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
code, sym, state, string.left(count), isAutoRepeat);
+ }
if (isAutoRepeat && type == QEvent::KeyRelease) {
// since we removed it from the event queue using checkEvent we need to send the key press here
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index fa5f5f43d0..a44e7fb959 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -104,6 +104,25 @@ void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceSt
return result;
}
+void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resource, QScreen *screen)
+{
+ const QXcbResourceMap::const_iterator it = qXcbResourceMap()->constFind(resource.toLower());
+ if (it == qXcbResourceMap()->constEnd() || !screen->handle())
+ return 0;
+ const QXcbScreen *xcbScreen = static_cast<QXcbScreen *>(screen->handle());
+ switch (it.value()) {
+ case Display:
+#ifdef XCB_USE_XLIB
+ return xcbScreen->connection()->xlib_display();
+#else
+ break;
+#endif
+ default:
+ break;
+ }
+ return 0;
+}
+
void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
QByteArray lowerCaseResource = resourceString.toLower();
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index c15d00255a..a7e0a207cb 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -65,6 +65,7 @@ public:
QXcbNativeInterface();
void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
+ void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index eab18e2435..e0f5dbc435 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -121,13 +121,13 @@ QT_BEGIN_NAMESPACE
// Returns true if we should set WM_TRANSIENT_FOR on \a w
static inline bool isTransient(const QWindow *w)
{
- return w->windowType() == Qt::Dialog
- || w->windowType() == Qt::Sheet
- || w->windowType() == Qt::Tool
- || w->windowType() == Qt::SplashScreen
- || w->windowType() == Qt::ToolTip
- || w->windowType() == Qt::Drawer
- || w->windowType() == Qt::Popup;
+ return w->type() == Qt::Dialog
+ || w->type() == Qt::Sheet
+ || w->type() == Qt::Tool
+ || w->type() == Qt::SplashScreen
+ || w->type() == Qt::ToolTip
+ || w->type() == Qt::Drawer
+ || w->type() == Qt::Popup;
}
static inline QImage::Format imageFormatForDepth(int depth)
@@ -175,7 +175,7 @@ void QXcbWindow::create()
m_configureNotifyPending = true;
m_windowState = Qt::WindowNoState;
- Qt::WindowType type = window()->windowType();
+ Qt::WindowType type = window()->type();
if (type == Qt::Desktop) {
m_window = m_screen->root();
@@ -309,7 +309,7 @@ void QXcbWindow::create()
if (m_screen->syncRequestSupported())
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
- if (window()->windowFlags() & Qt::WindowContextHelpButtonHint)
+ if (window()->flags() & Qt::WindowContextHelpButtonHint)
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP);
Q_XCB_CALL(xcb_change_property(xcb_connection(),
@@ -347,7 +347,7 @@ void QXcbWindow::create()
memset(&hints, 0, sizeof(hints));
xcb_wm_hints_set_normal(&hints);
- xcb_wm_hints_set_input(&hints, !(window()->windowFlags() & Qt::WindowDoesNotAcceptFocus));
+ xcb_wm_hints_set_input(&hints, !(window()->flags() & Qt::WindowDoesNotAcceptFocus));
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
@@ -375,11 +375,11 @@ void QXcbWindow::create()
connection()->xi2Select(m_window);
#endif
- setWindowFlags(window()->windowFlags());
- setWindowTitle(window()->windowTitle());
setWindowState(window()->windowState());
+ setWindowFlags(window()->flags());
+ setWindowTitle(window()->title());
- if (window()->windowFlags() & Qt::WindowTransparentForInput)
+ if (window()->flags() & Qt::WindowTransparentForInput)
setTransparentForMouseEvents(true);
#ifndef QT_NO_DRAGANDDROP
@@ -534,7 +534,7 @@ void QXcbWindow::show()
else
xcb_wm_hints_set_normal(&hints);
- xcb_wm_hints_set_input(&hints, !(window()->windowFlags() & Qt::WindowDoesNotAcceptFocus));
+ xcb_wm_hints_set_input(&hints, !(window()->flags() & Qt::WindowDoesNotAcceptFocus));
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
@@ -943,8 +943,8 @@ void QXcbWindow::updateMotifWmHintsBeforeMap()
{
QtMotifWmHints mwmhints = getMotifWmHints(connection(), m_window);
- if (window()->windowModality() != Qt::NonModal) {
- switch (window()->windowModality()) {
+ if (window()->modality() != Qt::NonModal) {
+ switch (window()->modality()) {
case Qt::WindowModal:
mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
break;
@@ -979,17 +979,17 @@ void QXcbWindow::updateMotifWmHintsBeforeMap()
}
}
- if (window()->windowFlags() & Qt::WindowMinimizeButtonHint) {
+ if (window()->flags() & Qt::WindowMinimizeButtonHint) {
mwmhints.flags |= MWM_HINTS_DECORATIONS;
mwmhints.decorations |= MWM_DECOR_MINIMIZE;
mwmhints.functions |= MWM_FUNC_MINIMIZE;
}
- if (window()->windowFlags() & Qt::WindowMaximizeButtonHint) {
+ if (window()->flags() & Qt::WindowMaximizeButtonHint) {
mwmhints.flags |= MWM_HINTS_DECORATIONS;
mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
mwmhints.functions |= MWM_FUNC_MAXIMIZE;
}
- if (window()->windowFlags() & Qt::WindowCloseButtonHint)
+ if (window()->flags() & Qt::WindowCloseButtonHint)
mwmhints.functions |= MWM_FUNC_CLOSE;
setMotifWmHints(connection(), m_window, mwmhints);
@@ -999,7 +999,7 @@ void QXcbWindow::updateNetWmStateBeforeMap()
{
NetWmStates states(0);
- const Qt::WindowFlags flags = window()->windowFlags();
+ const Qt::WindowFlags flags = window()->flags();
if (flags & Qt::WindowStaysOnTopHint) {
states |= NetWmStateAbove;
states |= NetWmStateStaysOnTop;
@@ -1015,7 +1015,7 @@ void QXcbWindow::updateNetWmStateBeforeMap()
states |= NetWmStateMaximizedVert;
}
- if (window()->windowModality() != Qt::NonModal)
+ if (window()->modality() != Qt::NonModal)
states |= NetWmStateModal;
setNetWmStates(states);
@@ -1303,6 +1303,42 @@ QXcbEGLSurface *QXcbWindow::eglSurface() const
}
#endif
+class ExposeCompressor
+{
+public:
+ ExposeCompressor(xcb_window_t window, QRegion *region)
+ : m_window(window)
+ , m_region(region)
+ , m_pending(true)
+ {
+ }
+
+ bool checkEvent(xcb_generic_event_t *event)
+ {
+ if (!event)
+ return false;
+ if ((event->response_type & ~0x80) != XCB_EXPOSE)
+ return false;
+ xcb_expose_event_t *expose = (xcb_expose_event_t *)event;
+ if (expose->window != m_window)
+ return false;
+ if (expose->count == 0)
+ m_pending = false;
+ *m_region |= QRect(expose->x, expose->y, expose->width, expose->height);
+ return true;
+ }
+
+ bool pending() const
+ {
+ return m_pending;
+ }
+
+private:
+ xcb_window_t m_window;
+ QRegion *m_region;
+ bool m_pending;
+};
+
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
{
QRect rect(event->x, event->y, event->width, event->height);
@@ -1312,8 +1348,15 @@ void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
else
m_exposeRegion |= rect;
+ ExposeCompressor compressor(m_window, &m_exposeRegion);
+ xcb_generic_event_t *filter = 0;
+ do {
+ filter = connection()->checkEvent(compressor);
+ free(filter);
+ } while (filter);
+
// if count is non-zero there are more expose events pending
- if (event->count == 0) {
+ if (event->count == 0 || !compressor.pending()) {
QWindowSystemInterface::handleExposeEvent(window(), m_exposeRegion);
m_exposeRegion = QRegion();
}
@@ -1529,7 +1572,9 @@ void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
return;
}
- QWindowSystemInterface::handleEnterEvent(window());
+ const QPoint local(event->event_x, event->event_y);
+ const QPoint global(event->root_x, event->root_y);
+ QWindowSystemInterface::handleEnterEvent(window(), local, global);
}
void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
@@ -1570,8 +1615,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
const long *data = (const long *)xcb_get_property_value(reply);
if (reply->length != 0 && XCB_WM_STATE_ICONIC == data[0])
newState = Qt::WindowMinimized;
- free(reply);
}
+ free(reply);
} // WM_STATE: Quick check for 'Minimize'.
if (newState != Qt::WindowMinimized) { // Something else changed, get _NET_WM_STATE.
const NetWmStates states = netWmStates();
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
new file mode 100644
index 0000000000..b7b5650eea
--- /dev/null
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -0,0 +1,117 @@
+TARGET = xcb
+
+PLUGIN_TYPE = platforms
+load(qt_plugin)
+
+QT += core-private gui-private platformsupport-private
+
+
+SOURCES = \
+ qxcbclipboard.cpp \
+ qxcbconnection.cpp \
+ qxcbintegration.cpp \
+ qxcbkeyboard.cpp \
+ qxcbmime.cpp \
+ qxcbdrag.cpp \
+ qxcbscreen.cpp \
+ qxcbwindow.cpp \
+ qxcbbackingstore.cpp \
+ qxcbwmsupport.cpp \
+ main.cpp \
+ qxcbnativeinterface.cpp \
+ qxcbcursor.cpp \
+ qxcbimage.cpp \
+ qxlibconvenience.cpp
+
+HEADERS = \
+ qxcbclipboard.h \
+ qxcbconnection.h \
+ qxcbintegration.h \
+ qxcbkeyboard.h \
+ qxcbdrag.h \
+ qxcbmime.h \
+ qxcbobject.h \
+ qxcbscreen.h \
+ qxcbwindow.h \
+ qxcbbackingstore.h \
+ qxcbwmsupport.h \
+ qxcbnativeinterface.h \
+ qxcbcursor.h \
+ qxcbimage.h \
+ qxlibconvenience.h
+
+LIBS += -ldl
+
+# needed by GLX, Xcursor, XLookupString, ...
+contains(QT_CONFIG, xcb-xlib) {
+ DEFINES += XCB_USE_XLIB
+ LIBS += -lX11 -lX11-xcb
+
+ *-maemo* {
+ contains(QT_CONFIG, xinput2) {
+ # XInput2 support for Harmattan.
+ DEFINES += XCB_USE_XINPUT2_MAEMO
+ SOURCES += qxcbconnection_maemo.cpp
+ LIBS += -lXi
+ }
+ DEFINES += XCB_USE_MAEMO_WINDOW_PROPERTIES
+ } else {
+ contains(QT_CONFIG, xinput2) {
+ DEFINES += XCB_USE_XINPUT2
+ SOURCES += qxcbconnection_xi2.cpp
+ LIBS += -lXi
+ }
+ }
+}
+
+# to support custom cursors with depth > 1
+contains(QT_CONFIG, xcb-render) {
+ DEFINES += XCB_USE_RENDER
+ LIBS += -lxcb-render -lxcb-render-util -lXrender
+}
+
+contains(QT_CONFIG, opengl) {
+ contains(QT_CONFIG, opengles2) {
+ DEFINES += XCB_USE_EGL
+ LIBS += -lEGL
+ HEADERS += qxcbeglsurface.h
+
+ # EGL on MeeGo 1.2 Harmattan needs this macro to map EGLNativeDisplayType
+ # and other types to the correct X11 types
+ DEFINES += SUPPORT_X11
+ } else:contains(QT_CONFIG, xcb-xlib) {
+ DEFINES += XCB_USE_GLX
+ HEADERS += qglxintegration.h
+ SOURCES += qglxintegration.cpp
+ LIBS += $$QMAKE_LIBS_DYNLOAD
+ contains(QT_CONFIG, xcb-glx) {
+ DEFINES += XCB_HAS_XCB_GLX
+ LIBS += -lxcb-glx
+ }
+ }
+}
+
+DEFINES += $$QMAKE_DEFINES_XCB
+LIBS += $$QMAKE_LIBS_XCB
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
+
+CONFIG += qpa/genericunixfontdatabase
+
+contains(QT_CONFIG, dbus) {
+DEFINES += XCB_USE_IBUS
+QT += dbus
+LIBS += -ldbus-1
+}
+
+OTHER_FILES += xcb.json README
+
+contains(QT_CONFIG, xcb-qt) {
+ DEFINES += XCB_USE_RENDER
+ XCB_DIR = ../../../3rdparty/xcb
+ INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude
+ LIBS += -lxcb -L ./xcb-static -l xcb-static
+} else {
+ LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr
+ !contains(DEFINES, QT_NO_SHAPE):LIBS += -lxcb-shape
+}
+
diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
new file mode 100644
index 0000000000..0257826e09
--- /dev/null
+++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
@@ -0,0 +1,70 @@
+#
+# Statically compile in code for
+# libxcb-fixes, libxcb-randr, libxcb-shm, libxcb-sync, libxcb-image, libxcb-keysyms, libxcb-icccm, libxcb-renderutil
+#
+TEMPLATE = lib
+TARGET = xcb-static
+CONFIG += staticlib
+
+XCB_DIR = ../../../../3rdparty/xcb
+
+INCLUDEPATH += $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude
+
+# ignore compiler warnings in 3rdparty code
+QMAKE_CFLAGS_STATIC_LIB+=-w
+
+#
+# libxcb
+#
+LIBXCB_DIR = $$XCB_DIR/libxcb
+
+SOURCES += \
+ $$LIBXCB_DIR/xfixes.c \
+ $$LIBXCB_DIR/randr.c \
+ $$LIBXCB_DIR/shm.c \
+ $$LIBXCB_DIR/sync.c \
+ $$LIBXCB_DIR/render.c \
+ $$LIBXCB_DIR/shape.c
+
+#
+# xcb-util
+#
+XCB_UTIL_DIR = $$XCB_DIR/xcb-util
+
+
+SOURCES += \
+ $$XCB_UTIL_DIR/xcb_aux.c \
+ $$XCB_UTIL_DIR/atoms.c \
+ $$XCB_UTIL_DIR/event.c
+
+#
+# xcb-util-image
+#
+XCB_IMAGE_DIR = $$XCB_DIR/xcb-util-image
+
+SOURCES += $$XCB_IMAGE_DIR/xcb_image.c
+
+#
+# xcb-util-keysyms
+#
+XCB_KEYSYMS_DIR = $$XCB_DIR/xcb-util-keysyms
+
+SOURCES += $$XCB_KEYSYMS_DIR/keysyms.c
+
+#
+# xcb-util-renderutil
+#
+
+XCB_RENDERUTIL_DIR = $$XCB_DIR/xcb-util-renderutil
+
+SOURCES += $$XCB_RENDERUTIL_DIR/util.c
+
+#
+# xcb-util-wm
+#
+XCB_WM_DIR = $$XCB_DIR/xcb-util-wm
+
+SOURCES += \
+ $$XCB_WM_DIR/icccm.c
+
+OTHER_FILES = $$XCB_DIR/README
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
index 34f7c74675..dab0d8cb14 100644
--- a/src/plugins/platforms/xcb/xcb.pro
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -1,112 +1,5 @@
-TARGET = xcb
+TEMPLATE = subdirs
+CONFIG += ordered
-PLUGIN_TYPE = platforms
-load(qt_plugin)
-
-QT += core-private gui-private platformsupport-private
-
-
-SOURCES = \
- qxcbclipboard.cpp \
- qxcbconnection.cpp \
- qxcbintegration.cpp \
- qxcbkeyboard.cpp \
- qxcbmime.cpp \
- qxcbdrag.cpp \
- qxcbscreen.cpp \
- qxcbwindow.cpp \
- qxcbbackingstore.cpp \
- qxcbwmsupport.cpp \
- main.cpp \
- qxcbnativeinterface.cpp \
- qxcbcursor.cpp \
- qxcbimage.cpp \
- qxlibconvenience.cpp
-
-HEADERS = \
- qxcbclipboard.h \
- qxcbconnection.h \
- qxcbintegration.h \
- qxcbkeyboard.h \
- qxcbdrag.h \
- qxcbmime.h \
- qxcbobject.h \
- qxcbscreen.h \
- qxcbwindow.h \
- qxcbbackingstore.h \
- qxcbwmsupport.h \
- qxcbnativeinterface.h \
- qxcbcursor.h \
- qxcbimage.h \
- qxlibconvenience.h
-
-contains(QT_CONFIG, xcb-poll-for-queued-event) {
- DEFINES += XCB_POLL_FOR_QUEUED_EVENT
-}
-
-# needed by GLX, Xcursor, XLookupString, ...
-contains(QT_CONFIG, xcb-xlib) {
- DEFINES += XCB_USE_XLIB
- LIBS += -lX11 -lX11-xcb
-
- *-maemo* {
- contains(QT_CONFIG, xinput2) {
- # XInput2 support for Harmattan.
- DEFINES += XCB_USE_XINPUT2_MAEMO
- SOURCES += qxcbconnection_maemo.cpp
- LIBS += -lXi
- }
- DEFINES += XCB_USE_MAEMO_WINDOW_PROPERTIES
- } else {
- contains(QT_CONFIG, xinput2) {
- DEFINES += XCB_USE_XINPUT2
- SOURCES += qxcbconnection_xi2.cpp
- LIBS += -lXi
- }
- }
-}
-
-# to support custom cursors with depth > 1
-contains(QT_CONFIG, xcb-render) {
- DEFINES += XCB_USE_RENDER
- LIBS += -lxcb-render -lxcb-render-util -lXrender
-}
-
-!contains(DEFINES, QT_NO_SHAPE):LIBS += -lxcb-shape
-
-contains(QT_CONFIG, opengl) {
- contains(QT_CONFIG, opengles2) {
- DEFINES += XCB_USE_EGL
- LIBS += -lEGL
- HEADERS += qxcbeglsurface.h
-
- # EGL on MeeGo 1.2 Harmattan needs this macro to map EGLNativeDisplayType
- # and other types to the correct X11 types
- DEFINES += SUPPORT_X11
- } else:contains(QT_CONFIG, xcb-xlib) {
- DEFINES += XCB_USE_GLX
- HEADERS += qglxintegration.h
- SOURCES += qglxintegration.cpp
- LIBS += $$QMAKE_LIBS_DYNLOAD
- contains(QT_CONFIG, xcb-glx) {
- DEFINES += XCB_HAS_XCB_GLX
- LIBS += -lxcb-glx
- }
- }
-}
-
-LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shape -lxcb-shm -lxcb-randr
-
-DEFINES += $$QMAKE_DEFINES_XCB
-LIBS += $$QMAKE_LIBS_XCB
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
-
-CONFIG += qpa/genericunixfontdatabase
-
-contains(QT_CONFIG, dbus) {
-DEFINES += XCB_USE_IBUS
-QT += dbus
-LIBS += -ldbus-1
-}
-
-OTHER_FILES += xcb.json
+contains(QT_CONFIG, xcb-qt):SUBDIRS+=xcb-static
+SUBDIRS += xcb-plugin.pro
diff --git a/src/plugins/printsupport/cocoa/cocoa.pro b/src/plugins/printsupport/cocoa/cocoa.pro
index 4e99b4a8f5..c0206fd2bc 100644
--- a/src/plugins/printsupport/cocoa/cocoa.pro
+++ b/src/plugins/printsupport/cocoa/cocoa.pro
@@ -1,5 +1,5 @@
TARGET = cocoaprintersupport
-
+MODULE = cocoaprintersupport
PLUGIN_TYPE = printsupport
load(qt_plugin)
diff --git a/src/plugins/printsupport/cups/cups.pro b/src/plugins/printsupport/cups/cups.pro
index bd0b6af114..0ea5058c00 100644
--- a/src/plugins/printsupport/cups/cups.pro
+++ b/src/plugins/printsupport/cups/cups.pro
@@ -1,5 +1,5 @@
TARGET = cupsprintersupport
-
+MODULE = cupsprintersupport
PLUGIN_TYPE = printsupport
load(qt_plugin)
diff --git a/src/plugins/printsupport/windows/windows.pro b/src/plugins/printsupport/windows/windows.pro
index 5e8738554c..5b5dd86beb 100644
--- a/src/plugins/printsupport/windows/windows.pro
+++ b/src/plugins/printsupport/windows/windows.pro
@@ -1,5 +1,5 @@
TARGET = windowsprintersupport
-
+MODULE = windowsprintersupport
PLUGIN_TYPE = printsupport
load(qt_plugin)