diff options
Diffstat (limited to 'src/plugins')
107 files changed, 1308 insertions, 293 deletions
diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp index 55b1d375dd..8392ef3a6d 100644 --- a/src/plugins/accessible/widgets/main.cpp +++ b/src/plugins/accessible/widgets/main.cpp @@ -199,7 +199,7 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec } else if (classname == QLatin1String("QSplitterHandle")) { iface = new QAccessibleWidget(widget, QAccessible::Grip); #endif -#ifndef QT_NO_TEXTEDIT +#if !defined(QT_NO_TEXTEDIT) && !defined(QT_NO_CURSOR) } else if (classname == QLatin1String("QTextEdit")) { iface = new QAccessibleTextEdit(widget); } else if (classname == QLatin1String("QPlainTextEdit")) { @@ -233,7 +233,7 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec } else if (classname == QLatin1String("QRubberBand")) { iface = new QAccessibleWidget(widget, QAccessible::Border); #endif -#ifndef QT_NO_TEXTBROWSER +#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) } else if (classname == QLatin1String("QTextBrowser")) { iface = new QAccessibleTextBrowser(widget); #endif diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp index 5f7d9a9c30..c7dcee78f0 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp +++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp @@ -165,7 +165,7 @@ QAccessibleMenuItem::~QAccessibleMenuItem() QAccessibleInterface *QAccessibleMenuItem::childAt(int x, int y ) const { - for (int i = childCount(); i >= 0; --i) { + for (int i = childCount() - 1; i >= 0; --i) { QAccessibleInterface *childInterface = child(i); if (childInterface->rect().contains(x,y)) { return childInterface; diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index 56e6166e85..e93a82c0ce 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -99,7 +99,7 @@ QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel) return widgets; } -#ifndef QT_NO_TEXTEDIT +#if !defined(QT_NO_TEXTEDIT) && !defined(QT_NO_CURSOR) QAccessiblePlainTextEdit::QAccessiblePlainTextEdit(QWidget* o) :QAccessibleTextWidget(o) @@ -292,7 +292,7 @@ void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex) qWarning("AccessibleTextEdit::scrollToSubstring failed!"); } -#endif // QT_NO_TEXTEDIT +#endif // QT_NO_TEXTEDIT && QT_NO_CURSOR #ifndef QT_NO_STACKEDWIDGET // ======================= QAccessibleStackedWidget ====================== @@ -488,7 +488,7 @@ QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget) #endif // QT_NO_DIALOGBUTTONBOX -#ifndef QT_NO_TEXTBROWSER +#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) QAccessibleTextBrowser::QAccessibleTextBrowser(QWidget *widget) : QAccessibleTextEdit(widget) { @@ -499,7 +499,7 @@ QAccessible::Role QAccessibleTextBrowser::role() const { return QAccessible::StaticText; } -#endif // QT_NO_TEXTBROWSER +#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR #ifndef QT_NO_CALENDARWIDGET // ===================== QAccessibleCalendarWidget ======================== diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h index e14b89a63b..fd76dbd076 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h @@ -122,7 +122,6 @@ protected: virtual QTextDocument *textDocument() const = 0; virtual QWidget *viewport() const = 0; }; -#endif //QT_NO_CURSOR #ifndef QT_NO_TEXTEDIT class QAccessiblePlainTextEdit : public QAccessibleTextWidget @@ -177,6 +176,7 @@ protected: QWidget *viewport() const; }; #endif // QT_NO_TEXTEDIT +#endif //QT_NO_CURSOR class QAccessibleStackedWidget : public QAccessibleWidget { @@ -245,7 +245,7 @@ public: explicit QAccessibleDialogButtonBox(QWidget *widget); }; -#ifndef QT_NO_TEXTBROWSER +#if !defined(QT_NO_TEXTBROWSER) && !defined(QT_NO_CURSOR) class QAccessibleTextBrowser : public QAccessibleTextEdit { public: @@ -253,7 +253,7 @@ public: QAccessible::Role role() const; }; -#endif // QT_NO_TEXTBROWSER +#endif // QT_NO_TEXTBROWSER && QT_NO_CURSOR #ifndef QT_NO_CALENDARWIDGET class QAccessibleCalendarWidget : public QAccessibleWidget diff --git a/src/plugins/accessible/widgets/rangecontrols.cpp b/src/plugins/accessible/widgets/rangecontrols.cpp index 954369b6b3..d03130f148 100644 --- a/src/plugins/accessible/widgets/rangecontrols.cpp +++ b/src/plugins/accessible/widgets/rangecontrols.cpp @@ -122,6 +122,11 @@ QVariant QAccessibleAbstractSpinBox::minimumValue() const return abstractSpinBox()->property("minimum"); } +QVariant QAccessibleAbstractSpinBox::minimumStepSize() const +{ + return abstractSpinBox()->property("stepSize"); +} + /*! \class QAccessibleSpinBox \brief The QAccessibleSpinBox class implements the QAccessibleInterface for spinbox widgets. @@ -278,6 +283,11 @@ QVariant QAccessibleAbstractSlider::minimumValue() const return abstractSlider()->minimum(); } +QVariant QAccessibleAbstractSlider::minimumStepSize() const +{ + return abstractSlider()->singleStep(); +} + QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const { return static_cast<QAbstractSlider *>(object()); diff --git a/src/plugins/accessible/widgets/rangecontrols.h b/src/plugins/accessible/widgets/rangecontrols.h index b26d97421a..a370ada199 100644 --- a/src/plugins/accessible/widgets/rangecontrols.h +++ b/src/plugins/accessible/widgets/rangecontrols.h @@ -71,6 +71,7 @@ public: void setCurrentValue(const QVariant &value); QVariant maximumValue() const; QVariant minimumValue() const; + QVariant minimumStepSize() const; // FIXME Action interface @@ -110,6 +111,7 @@ public: void setCurrentValue(const QVariant &value); QVariant maximumValue() const; QVariant minimumValue() const; + QVariant minimumStepSize() const; protected: QAbstractSlider *abstractSlider() const; diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index 1bd509dc41..8bf71da6e1 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -832,6 +832,14 @@ QVariant QAccessibleProgressBar::minimumValue() const return progressBar()->minimum(); } +QVariant QAccessibleProgressBar::minimumStepSize() const +{ + // This is arbitrary since any value between min and max is valid. + // Some screen readers (orca use it to calculate how many digits to display though, + // so it makes sense to return a "sensible" value. Providing 100 increments seems ok. + return (progressBar()->maximum() - progressBar()->minimum()) / 100.0; +} + QProgressBar *QAccessibleProgressBar::progressBar() const { return qobject_cast<QProgressBar *>(object()); diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index 2e1bca88b4..dbea8d4f09 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -188,6 +188,7 @@ public: QVariant currentValue() const; QVariant maximumValue() const; QVariant minimumValue() const; + QVariant minimumStepSize() const; inline void setCurrentValue(const QVariant &) {} protected: diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro index afabbac9bc..aff60d9781 100644 --- a/src/plugins/accessible/widgets/widgets.pro +++ b/src/plugins/accessible/widgets/widgets.pro @@ -1,6 +1,7 @@ TARGET = qtaccessiblewidgets PLUGIN_TYPE = accessible +PLUGIN_CLASS_NAME = AccessibleFactory load(qt_plugin) QT += core-private gui-private widgets-private diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro index 899eede7bf..0375500306 100644 --- a/src/plugins/bearer/bearer.pro +++ b/src/plugins/bearer/bearer.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -linux*:contains(QT_CONFIG, dbus) { +linux*:qtHaveModule(dbus) { SUBDIRS += generic SUBDIRS += connman networkmanager } diff --git a/src/plugins/bearer/blackberry/blackberry.pro b/src/plugins/bearer/blackberry/blackberry.pro index 220a506d90..c75de3aaad 100644 --- a/src/plugins/bearer/blackberry/blackberry.pro +++ b/src/plugins/bearer/blackberry/blackberry.pro @@ -1,6 +1,7 @@ TARGET = qbbbearer PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QBBEnginePlugin load(qt_plugin) QT = core-private network-private diff --git a/src/plugins/bearer/connman/connman.pro b/src/plugins/bearer/connman/connman.pro index 99d9b367f2..cccdff0fdb 100644 --- a/src/plugins/bearer/connman/connman.pro +++ b/src/plugins/bearer/connman/connman.pro @@ -1,6 +1,7 @@ TARGET = qconnmanbearer PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QConnmanEnginePlugin load(qt_plugin) QT = core network-private dbus diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 46757ab021..dbfac6b438 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -57,9 +57,24 @@ #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE -static QDBusConnection dbusConnection = QDBusConnection::systemBus(); +QDBusArgument &operator<<(QDBusArgument &argument, const ConnmanMap &map) +{ + argument.beginStructure(); + argument << map.objectPath << map.propertyMap; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, ConnmanMap &map) +{ + argument.beginStructure(); + argument >> map.objectPath >> map.propertyMap; + argument.endStructure(); + return argument; +} +static QDBusConnection dbusConnection = QDBusConnection::systemBus(); QConnmanManagerInterface::QConnmanManagerInterface( QObject *parent) : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE), QLatin1String(CONNMAN_MANAGER_PATH), @@ -301,14 +316,37 @@ QStringList QConnmanManagerInterface::getProfiles() QStringList QConnmanManagerInterface::getTechnologies() { - QVariant var = getProperty("Technologies"); - return qdbus_cast<QStringList >(var); + QStringList list; + QDBusReply<ConnmanMapList> replyList = this->call(QLatin1String("GetTechnologies")); + if (replyList.isValid()) { + Q_FOREACH (ConnmanMap map, replyList.value()) { + list << map.objectPath.path(); + } + } else { + // try for older version + QVariant var = getProperty("Technologies"); + if (!var.isNull()) { + list = qdbus_cast<QStringList>(var); + } + } + return list; } QStringList QConnmanManagerInterface::getServices() { - QVariant var = getProperty("Services"); - return qdbus_cast<QStringList >(var); + QStringList list; + QDBusReply<ConnmanMapList> replyList = this->call(QLatin1String("GetServices")); + if (replyList.isValid()) { + Q_FOREACH (ConnmanMap map, replyList.value()) { + list << map.objectPath.path(); + } + } else { + QVariant var = getProperty("Services"); + if (!var.isNull()) { + list = qdbus_cast<QStringList>(var); + } + } + return list; } QString QConnmanManagerInterface::getPathForTechnology(const QString &name) diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h index be2063f8e8..3ed66f4769 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h +++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h @@ -59,6 +59,7 @@ #include <QtDBus/QDBusInterface> #include <QtDBus/QDBusMessage> #include <QtDBus/QDBusReply> +#include <QtDBus/QDBusArgument> #include <QtDBus/QDBusPendingCallWatcher> #include <QtDBus/QDBusObjectPath> @@ -90,11 +91,23 @@ QT_BEGIN_NAMESPACE +struct ConnmanMap { + QDBusObjectPath objectPath; + QVariantMap propertyMap; +}; + +typedef QList< ConnmanMap > ConnmanMapList; + QT_END_NAMESPACE +Q_DECLARE_METATYPE(QT_PREPEND_NAMESPACE(ConnmanMap)) +Q_DECLARE_METATYPE(QT_PREPEND_NAMESPACE(ConnmanMapList)) QT_BEGIN_NAMESPACE +QDBusArgument &operator<<(QDBusArgument &argument, const ConnmanMap &obj); +const QDBusArgument &operator>>(const QDBusArgument &argument, ConnmanMap &obj); + class QConnmanManagerInterface : public QDBusAbstractInterface { Q_OBJECT diff --git a/src/plugins/bearer/corewlan/corewlan.pro b/src/plugins/bearer/corewlan/corewlan.pro index 481b75c8ab..db8651de6e 100644 --- a/src/plugins/bearer/corewlan/corewlan.pro +++ b/src/plugins/bearer/corewlan/corewlan.pro @@ -1,6 +1,7 @@ TARGET = qcorewlanbearer PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QCoreWlanEnginePlugin load(qt_plugin) QT = core-private network-private diff --git a/src/plugins/bearer/generic/generic.pro b/src/plugins/bearer/generic/generic.pro index a1da0dddda..d0e17380e3 100644 --- a/src/plugins/bearer/generic/generic.pro +++ b/src/plugins/bearer/generic/generic.pro @@ -1,6 +1,7 @@ TARGET = qgenericbearer PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QGenericEnginePlugin load(qt_plugin) QT = core-private network-private diff --git a/src/plugins/bearer/nativewifi/nativewifi.pro b/src/plugins/bearer/nativewifi/nativewifi.pro index 4382cd08cd..e372c8ca05 100644 --- a/src/plugins/bearer/nativewifi/nativewifi.pro +++ b/src/plugins/bearer/nativewifi/nativewifi.pro @@ -1,6 +1,7 @@ TARGET = qnativewifibearer PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QNativeWifiEnginePlugin load(qt_plugin) QT = core-private network-private diff --git a/src/plugins/bearer/networkmanager/networkmanager.pro b/src/plugins/bearer/networkmanager/networkmanager.pro index 4f299e22f2..1ed9bfaa1b 100644 --- a/src/plugins/bearer/networkmanager/networkmanager.pro +++ b/src/plugins/bearer/networkmanager/networkmanager.pro @@ -1,6 +1,7 @@ TARGET = qnmbearer PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QNetworkManagerEnginePlugin load(qt_plugin) QT = core network-private dbus diff --git a/src/plugins/bearer/nla/nla.pro b/src/plugins/bearer/nla/nla.pro index 56c06a57b1..bac7608477 100644 --- a/src/plugins/bearer/nla/nla.pro +++ b/src/plugins/bearer/nla/nla.pro @@ -1,6 +1,7 @@ TARGET = qnlabearer PLUGIN_TYPE = bearer +PLUGIN_CLASS_NAME = QNlaEnginePlugin load(qt_plugin) QT = core core-private network network-private diff --git a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro index 97b827b779..281515145f 100644 --- a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro +++ b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro @@ -1,6 +1,7 @@ TARGET = qevdevkeyboardplugin PLUGIN_TYPE = generic +PLUGIN_CLASS_NAME = QEvdevKeyboardPlugin load(qt_plugin) QT += core-private platformsupport-private gui-private diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro index c1356593df..9a3cc839cc 100644 --- a/src/plugins/generic/evdevmouse/evdevmouse.pro +++ b/src/plugins/generic/evdevmouse/evdevmouse.pro @@ -1,6 +1,7 @@ TARGET = qevdevmouseplugin PLUGIN_TYPE = generic +PLUGIN_CLASS_NAME = QEvdevMousePlugin load(qt_plugin) QT += core-private platformsupport-private gui-private diff --git a/src/plugins/generic/evdevtablet/evdevtablet.pro b/src/plugins/generic/evdevtablet/evdevtablet.pro index 066819be33..ee3fbb3ec1 100644 --- a/src/plugins/generic/evdevtablet/evdevtablet.pro +++ b/src/plugins/generic/evdevtablet/evdevtablet.pro @@ -1,6 +1,7 @@ TARGET = qevdevtabletplugin PLUGIN_TYPE = generic +PLUGIN_CLASS_NAME = QEvdevTabletPlugin load(qt_plugin) SOURCES = main.cpp diff --git a/src/plugins/generic/evdevtouch/evdevtouch.pro b/src/plugins/generic/evdevtouch/evdevtouch.pro index 2c1d6913ad..3d1c481c36 100644 --- a/src/plugins/generic/evdevtouch/evdevtouch.pro +++ b/src/plugins/generic/evdevtouch/evdevtouch.pro @@ -1,6 +1,7 @@ TARGET = qevdevtouchplugin PLUGIN_TYPE = generic +PLUGIN_CLASS_NAME = QEvdevTouchScreenPlugin load(qt_plugin) SOURCES = main.cpp diff --git a/src/plugins/generic/meego/meego.pro b/src/plugins/generic/meego/meego.pro index b8845418e8..c428517cd5 100644 --- a/src/plugins/generic/meego/meego.pro +++ b/src/plugins/generic/meego/meego.pro @@ -1,6 +1,7 @@ TARGET = qmeegointegration PLUGIN_TYPE = generic +PLUGIN_CLASS_NAME = QMeeGoIntegrationPlugin load(qt_plugin) SOURCES = qmeegointegration.cpp \ diff --git a/src/plugins/generic/tslib/tslib.pro b/src/plugins/generic/tslib/tslib.pro index ab0645d89a..035857bb73 100644 --- a/src/plugins/generic/tslib/tslib.pro +++ b/src/plugins/generic/tslib/tslib.pro @@ -1,6 +1,7 @@ TARGET = qtslibplugin PLUGIN_TYPE = generic +PLUGIN_CLASS_NAME = QTsLibPlugin load(qt_plugin) HEADERS = qtslib.h diff --git a/src/plugins/imageformats/gif/gif.pro b/src/plugins/imageformats/gif/gif.pro index d5acfedff7..898f06e7c7 100644 --- a/src/plugins/imageformats/gif/gif.pro +++ b/src/plugins/imageformats/gif/gif.pro @@ -1,6 +1,7 @@ TARGET = qgif PLUGIN_TYPE = imageformats +PLUGIN_CLASS_NAME = QGifPlugin load(qt_plugin) include(../../../gui/image/qgifhandler.pri) diff --git a/src/plugins/imageformats/gif/main.h b/src/plugins/imageformats/gif/main.h index 46d669a97f..c7770edc53 100644 --- a/src/plugins/imageformats/gif/main.h +++ b/src/plugins/imageformats/gif/main.h @@ -42,6 +42,8 @@ #include <qimageiohandler.h> #include <qstringlist.h> +#ifndef QT_NO_IMAGEFORMATPLUGIN + #ifdef QT_NO_IMAGEFORMAT_GIF #undef QT_NO_IMAGEFORMAT_GIF #endif @@ -62,3 +64,5 @@ public: }; QT_END_NAMESPACE + +#endif // QT_NO_IMAGEFORMATPLUGIN diff --git a/src/plugins/imageformats/ico/ico.pro b/src/plugins/imageformats/ico/ico.pro index 48bfd6b344..4250fcb4bc 100644 --- a/src/plugins/imageformats/ico/ico.pro +++ b/src/plugins/imageformats/ico/ico.pro @@ -1,6 +1,7 @@ TARGET = qico PLUGIN_TYPE = imageformats +PLUGIN_CLASS_NAME = QICOPlugin load(qt_plugin) QTDIR_build:REQUIRES = "!contains(QT_CONFIG, no-ico)" diff --git a/src/plugins/imageformats/jpeg/jpeg.pro b/src/plugins/imageformats/jpeg/jpeg.pro index 35153eb59c..45bf7bbd43 100644 --- a/src/plugins/imageformats/jpeg/jpeg.pro +++ b/src/plugins/imageformats/jpeg/jpeg.pro @@ -1,6 +1,7 @@ TARGET = qjpeg PLUGIN_TYPE = imageformats +PLUGIN_CLASS_NAME = QJpegPlugin load(qt_plugin) QT += core-private diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro index 033d5a4d5c..75a5b5838f 100644 --- a/src/plugins/platforminputcontexts/ibus/ibus.pro +++ b/src/plugins/platforminputcontexts/ibus/ibus.pro @@ -1,6 +1,7 @@ TARGET = ibusplatforminputcontextplugin PLUGIN_TYPE = platforminputcontexts +PLUGIN_CLASS_NAME = QIbusPlatformInputContextPlugin load(qt_plugin) QT += dbus gui-private diff --git a/src/plugins/platforminputcontexts/maliit/maliit.pro b/src/plugins/platforminputcontexts/maliit/maliit.pro index dec6833196..1e50f7289b 100644 --- a/src/plugins/platforminputcontexts/maliit/maliit.pro +++ b/src/plugins/platforminputcontexts/maliit/maliit.pro @@ -1,6 +1,7 @@ TARGET = maliitplatforminputcontextplugin PLUGIN_TYPE = platforminputcontexts +PLUGIN_CLASS_NAME = QMaliitPlatformInputContextPlugin load(qt_plugin) QT += dbus gui-private diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro index 7c1f55927d..c8449e7e44 100644 --- a/src/plugins/platforminputcontexts/platforminputcontexts.pro +++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs -contains(QT_CONFIG, dbus) { +qtHaveModule(dbus) { !macx:!win32:SUBDIRS += ibus maliit } diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 78fcf20afc..83e2a88e6a 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -1,6 +1,7 @@ TARGET = qcocoa PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QCocoaIntegrationPlugin load(qt_plugin) OBJECTIVE_SOURCES += main.mm \ @@ -38,6 +39,7 @@ OBJECTIVE_SOURCES += main.mm \ qcocoaservices.mm \ qcocoasystemtrayicon.mm \ qcocoaintrospection.mm \ + qcocoakeymapper.mm \ HEADERS += qcocoaintegration.h \ qcocoatheme.h \ @@ -72,6 +74,7 @@ HEADERS += qcocoaintegration.h \ qcocoaservices.h \ qcocoasystemtrayicon.h \ qcocoaintrospection.h \ + qcocoakeymapper.h \ RESOURCES += qcocoaresources.qrc @@ -79,7 +82,7 @@ LIBS += -framework Cocoa -framework IOKit QT += core-private gui-private platformsupport-private -!contains(QT_CONFIG, no-widgets) { +qtHaveModule(widgets) { OBJECTIVE_SOURCES += \ qpaintengine_mac.mm \ qprintengine_mac.mm \ @@ -95,13 +98,6 @@ QT += core-private gui-private platformsupport-private OTHER_FILES += cocoa.json -# Build the release libqcocoa.dylib only, skip the debug version. -# The Qt plugin loader will dlopen both if found, causing duplicate -# Objective-c class definitions for the classes defined in the plugin. -contains(QT_CONFIG,release):CONFIG -= debug -contains(QT_CONFIG,debug_and_release):CONFIG -= debug_and_release -contains(QT_CONFIG,build_all):CONFIG -= build_all - # Acccessibility debug support # DEFINES += QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR # include ($$PWD/../../../../util/accessibilityinspector/accessibilityinspector.pri) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index df6b64443d..d5841c1983 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -122,7 +122,7 @@ static QAccessibleInterface *acast(void *ptr) [attributes addObject : NSAccessibilityValueAttribute]; } - return attributes; + return [attributes autorelease]; } - (id)accessibilityAttributeValue:(NSString *)attribute { @@ -139,7 +139,7 @@ static QAccessibleInterface *acast(void *ptr) [kids addObject:[QCocoaAccessibleElement elementWithInterface:(void*)childInterface parent:self]]; } - return NSAccessibilityUnignoredChildren(kids); + return kids; } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { // Just check if the app thinks we're focused. id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute]; @@ -239,6 +239,10 @@ static QAccessibleInterface *acast(void *ptr) if (!accessibleInterface) return NSAccessibilityUnignoredAncestor(self); + + if (!acast(accessibleInterface)->isValid()) + return NSAccessibilityUnignoredAncestor(self); + QAccessibleInterface *childInterface = acast(accessibleInterface)->childAt(point.x, qt_mac_flipYCoordinate(point.y)); // No child found, meaning we hit this element. diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 7aa365df67..80c9e227d2 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -510,14 +510,16 @@ static bool IsMouseOrKeyEvent( NSEvent* event ) static inline void qt_mac_waitForMoreEvents(NSString *runLoopMode = NSDefaultRunLoopMode) { - // If no event exist in the cocoa event que, wait - // (and free up cpu time) until at least one event occur. - // This implementation is a bit on the edge, but seems to - // work fine: - [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantFuture] - inMode:runLoopMode - dequeue:NO]; + // If no event exist in the cocoa event que, wait (and free up cpu time) until + // at least one event occur. Setting 'dequeuing' to 'no' in the following call + // causes it to hang under certain circumstances (QTBUG-28283), so we tell it + // to dequeue instead, just to repost the event again: + NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantFuture] + inMode:runLoopMode + dequeue:YES]; + if (event) + [NSApp postEvent:event atStart:YES]; } bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index f9122f56d1..5747cc01e9 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -223,7 +223,7 @@ static QString strippedText(QString s) - (void)showModelessPanel { if (mOpenPanel){ - QFileInfo info(*mCurrentSelection); + QFileInfo info(!mCurrentSelection->isEmpty() ? *mCurrentSelection : QT_PREPEND_NAMESPACE(QCFString::toQString)(mCurrentDir)); NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath()); bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:nil shouldShowFilename:filepath]; @@ -241,7 +241,7 @@ static QString strippedText(QString s) - (BOOL)runApplicationModalPanel { - QFileInfo info(*mCurrentSelection); + QFileInfo info(!mCurrentSelection->isEmpty() ? *mCurrentSelection : QT_PREPEND_NAMESPACE(QCFString::toQString)(mCurrentDir)); NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath()); bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:nil shouldShowFilename:filepath]; @@ -266,7 +266,7 @@ static QString strippedText(QString s) - (void)showWindowModalSheet:(QWindow *)parent { - QFileInfo info(*mCurrentSelection); + QFileInfo info(!mCurrentSelection->isEmpty() ? *mCurrentSelection : QT_PREPEND_NAMESPACE(QCFString::toQString)(mCurrentDir)); NSString *filepath = QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath()); bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:nil shouldShowFilename:filepath]; diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index 5ccd019a9b..ff3ba63931 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -92,20 +92,16 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) QFont newFont; if (cocoaFont) { int pSize = qRound([cocoaFont pointSize]); - QString family(QCFString::toQString([cocoaFont familyName])); - QString typeface(QCFString::toQString([cocoaFont fontName])); - - int hyphenPos = typeface.indexOf(QLatin1Char('-')); - if (hyphenPos != -1) { - typeface.remove(0, hyphenPos + 1); - } else { - typeface = QLatin1String("Normal"); - } + CTFontDescriptorRef font = CTFontCopyFontDescriptor((CTFontRef)cocoaFont); + // QCoreTextFontDatabase::populateFontDatabase() is using localized names + QString family = QCFString::toQString((CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontFamilyNameAttribute, NULL)); + QString style = QCFString::toQString((CFStringRef) CTFontDescriptorCopyLocalizedAttribute(font, kCTFontStyleNameAttribute, NULL)); - newFont = QFontDatabase().font(family, typeface, pSize); + newFont = QFontDatabase().font(family, style, pSize); newFont.setUnderline(resolveFont.underline()); newFont.setStrikeOut(resolveFont.strikeOut()); + CFRelease(font); } return newFont; } diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 9783899742..31a56b9d66 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -138,6 +138,8 @@ NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image) NSImage *qt_mac_create_nsimage(const QPixmap &pm) { + if (pm.isNull()) + return 0; QImage image = pm.toImage(); CGImageRef cgImage = qt_mac_image_to_cgimage(image); NSImage *nsImage = qt_mac_cgimage_to_nsimage(cgImage); @@ -784,14 +786,49 @@ CGImageRef qt_mac_toCGImage(const QImage &qImage, bool isMask, uchar **dataCopy) NULL, false); } else { - CGColorSpaceRef cgColourSpaceRef = CGColorSpaceCreateDeviceRGB(); + // Try get a device color space. Using the device color space means + // that the CGImage can be drawn to screen without per-pixel color + // space conversion, at the cost of less color accuracy. + CGColorSpaceRef cgColourSpaceRef = 0; + CMProfileRef sysProfile; + if (CMGetSystemProfile(&sysProfile) == noErr) + { + cgColourSpaceRef = CGColorSpaceCreateWithPlatformColorSpace(sysProfile); + CMCloseProfile(sysProfile); + } + + // Fall back to Generic RGB if a profile was not found. + if (!cgColourSpaceRef) + cgColourSpaceRef = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + + // Create a CGBitmapInfo contiaining the image format. + // Support the 8-bit per component (A)RGB formats. + CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little; + switch (qImage.format()) { + case QImage::Format_ARGB32_Premultiplied : + bitmapInfo |= kCGImageAlphaPremultipliedFirst; + break; + case QImage::Format_ARGB32 : + bitmapInfo |= kCGImageAlphaFirst; + break; + case QImage::Format_RGB32 : + bitmapInfo |= kCGImageAlphaNoneSkipFirst; + break; + case QImage::Format_RGB888 : + bitmapInfo |= kCGImageAlphaNone; + break; + default: + qWarning() << "qt_mac_toCGImage: Unsupported image format" << qImage.format(); + break; + } + cgImage = CGImageCreate(width, height, colorBufferSize, bitDepth, bytesPrLine, cgColourSpaceRef, - kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst, + bitmapInfo, cgDataProviderRef, NULL, false, diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 1bb46ea3ea..e455a3552e 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -49,6 +49,7 @@ #include "qcocoaclipboard.h" #include "qcocoadrag.h" #include "qcocoaservices.h" +#include "qcocoakeymapper.h" #include <QtCore/QScopedPointer> #include <qpa/qplatformintegration.h> @@ -121,6 +122,8 @@ public: QPlatformServices *services() const; QVariant styleHint(StyleHint hint) const; + QList<int> possibleKeys(const QKeyEvent *event) const; + void updateScreens(); private: @@ -138,6 +141,7 @@ private: QScopedPointer<QCocoaDrag> mCocoaDrag; QScopedPointer<QPlatformNativeInterface> mNativeInterface; QScopedPointer<QCocoaServices> mServices; + QScopedPointer<QCocoaKeyMapper> mKeyboardMapper; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 393c471c25..e096096e99 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -199,6 +199,7 @@ QCocoaIntegration::QCocoaIntegration() , mCocoaDrag(new QCocoaDrag) , mNativeInterface(new QCocoaNativeInterface) , mServices(new QCocoaServices) + , mKeyboardMapper(new QCocoaKeyMapper) { initResources(); QCocoaAutoReleasePool pool; @@ -414,4 +415,9 @@ QVariant QCocoaIntegration::styleHint(StyleHint hint) const return QPlatformIntegration::styleHint(hint); } +QList<int> QCocoaIntegration::possibleKeys(const QKeyEvent *event) const +{ + return mKeyboardMapper->possibleKeys(event); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.h b/src/plugins/platforms/cocoa/qcocoakeymapper.h new file mode 100644 index 0000000000..693539dd4e --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoakeymapper.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QCOCOAKEYMAPPER_H +#define QCOCOAKEYMAPPER_H + +#include <qcocoahelpers.h> + +#include <Cocoa/Cocoa.h> +#include <Carbon/Carbon.h> + +#include <QtCore/QList> +#include <QtGui/QKeyEvent> + +QT_BEGIN_NAMESPACE + +/* + \internal + A Mac KeyboardLayoutItem has 8 possible states: + 1. Unmodified + 2. Shift + 3. Control + 4. Control + Shift + 5. Alt + 6. Alt + Shift + 7. Alt + Control + 8. Alt + Control + Shift + 9. Meta + 10. Meta + Shift + 11. Meta + Control + 12. Meta + Control + Shift + 13. Meta + Alt + 14. Meta + Alt + Shift + 15. Meta + Alt + Control + 16. Meta + Alt + Control + Shift +*/ +struct KeyboardLayoutItem { + bool dirty; + quint32 qtKey[16]; // Can by any Qt::Key_<foo>, or unicode character +}; + + +class QCocoaKeyMapper +{ +public: + QCocoaKeyMapper(); + ~QCocoaKeyMapper(); + QList<int> possibleKeys(const QKeyEvent *event) const; + bool updateKeyboard(); + void deleteLayouts(); + void updateKeyMap(unsigned short macVirtualKey, QChar unicodeKey); + void clearMappings(); + +private: + QCFType<TISInputSourceRef> currentInputSource; + + QLocale keyboardInputLocale; + Qt::LayoutDirection keyboardInputDirection; + enum { NullMode, UnicodeMode, OtherMode } keyboard_mode; + union { + const UCKeyboardLayout *unicode; + void *other; + } keyboard_layout_format; + KeyboardLayoutRef currentKeyboardLayout; + KeyboardLayoutKind keyboard_kind; + UInt32 keyboard_dead; + KeyboardLayoutItem *keyLayout[256]; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm new file mode 100644 index 0000000000..6df0466355 --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm @@ -0,0 +1,468 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "qcocoakeymapper.h" + +#include <QtCore/QDebug> +#include <QtGui/QGuiApplication> + +QT_BEGIN_NAMESPACE + +// QCocoaKeyMapper debug facilities +//#define DEBUG_KEY_BINDINGS +//#define DEBUG_KEY_BINDINGS_MODIFIERS +//#define DEBUG_KEY_MAPS + +// Possible modifier states. +// NOTE: The order of these states match the order in updatePossibleKeyCodes()! +static const Qt::KeyboardModifiers ModsTbl[] = { + Qt::NoModifier, // 0 + Qt::ShiftModifier, // 1 + Qt::ControlModifier, // 2 + Qt::ControlModifier | Qt::ShiftModifier, // 3 + Qt::AltModifier, // 4 + Qt::AltModifier | Qt::ShiftModifier, // 5 + Qt::AltModifier | Qt::ControlModifier, // 6 + Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7 + Qt::MetaModifier, // 8 + Qt::MetaModifier | Qt::ShiftModifier, // 9 + Qt::MetaModifier | Qt::ControlModifier, // 10 + Qt::MetaModifier | Qt::ControlModifier | Qt::ShiftModifier,// 11 + Qt::MetaModifier | Qt::AltModifier, // 12 + Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier, // 13 + Qt::MetaModifier | Qt::AltModifier | Qt::ControlModifier, // 14 + Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 15 +}; + +bool qt_mac_eat_unicode_key = false; + +Q_GUI_EXPORT void qt_mac_secure_keyboard(bool b) +{ + static bool secure = false; + if (b != secure){ + b ? EnableSecureEventInput() : DisableSecureEventInput(); + secure = b; + } +} + +/* key maps */ +struct qt_mac_enum_mapper +{ + int mac_code; + int qt_code; +#if defined(DEBUG_KEY_BINDINGS) +# define QT_MAC_MAP_ENUM(x) x, #x + const char *desc; +#else +# define QT_MAC_MAP_ENUM(x) x +#endif +}; + +//modifiers +static qt_mac_enum_mapper qt_mac_modifier_symbols[] = { + { shiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) }, + { rightShiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) }, + { controlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) }, + { rightControlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) }, + { cmdKey, QT_MAC_MAP_ENUM(Qt::ControlModifier) }, + { optionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) }, + { rightOptionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) }, + { kEventKeyModifierNumLockMask, QT_MAC_MAP_ENUM(Qt::KeypadModifier) }, + { 0, QT_MAC_MAP_ENUM(0) } +}; +Qt::KeyboardModifiers qt_mac_get_modifiers(int keys) +{ +#ifdef DEBUG_KEY_BINDINGS_MODIFIERS + qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", keys, keys); +#endif + Qt::KeyboardModifiers ret = Qt::NoModifier; + for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) { + if (keys & qt_mac_modifier_symbols[i].mac_code) { +#ifdef DEBUG_KEY_BINDINGS_MODIFIERS + qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc); +#endif + ret |= Qt::KeyboardModifier(qt_mac_modifier_symbols[i].qt_code); + } + } + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + Qt::KeyboardModifiers oldModifiers = ret; + ret &= ~(Qt::MetaModifier | Qt::ControlModifier); + if (oldModifiers & Qt::ControlModifier) + ret |= Qt::MetaModifier; + if (oldModifiers & Qt::MetaModifier) + ret |= Qt::ControlModifier; + } + return ret; +} +static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys) +{ +#ifdef DEBUG_KEY_BINDINGS_MODIFIERS + qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", (int)keys, (int)keys); +#endif + int ret = 0; + for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) { + if (keys & qt_mac_modifier_symbols[i].qt_code) { +#ifdef DEBUG_KEY_BINDINGS_MODIFIERS + qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc); +#endif + ret |= qt_mac_modifier_symbols[i].mac_code; + } + } + + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + int oldModifiers = ret; + ret &= ~(controlKeyBit | cmdKeyBit); + if (oldModifiers & controlKeyBit) + ret |= cmdKeyBit; + if (oldModifiers & cmdKeyBit) + ret |= controlKeyBit; + } + return ret; +} + +//keyboard keys (non-modifiers) +static qt_mac_enum_mapper qt_mac_keyboard_symbols[] = { + { kHomeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Home) }, + { kEnterCharCode, QT_MAC_MAP_ENUM(Qt::Key_Enter) }, + { kEndCharCode, QT_MAC_MAP_ENUM(Qt::Key_End) }, + { kBackspaceCharCode, QT_MAC_MAP_ENUM(Qt::Key_Backspace) }, + { kTabCharCode, QT_MAC_MAP_ENUM(Qt::Key_Tab) }, + { kPageUpCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageUp) }, + { kPageDownCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageDown) }, + { kReturnCharCode, QT_MAC_MAP_ENUM(Qt::Key_Return) }, + { kEscapeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Escape) }, + { kLeftArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Left) }, + { kRightArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Right) }, + { kUpArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Up) }, + { kDownArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Down) }, + { kHelpCharCode, QT_MAC_MAP_ENUM(Qt::Key_Help) }, + { kDeleteCharCode, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, +//ascii maps, for debug + { ':', QT_MAC_MAP_ENUM(Qt::Key_Colon) }, + { ';', QT_MAC_MAP_ENUM(Qt::Key_Semicolon) }, + { '<', QT_MAC_MAP_ENUM(Qt::Key_Less) }, + { '=', QT_MAC_MAP_ENUM(Qt::Key_Equal) }, + { '>', QT_MAC_MAP_ENUM(Qt::Key_Greater) }, + { '?', QT_MAC_MAP_ENUM(Qt::Key_Question) }, + { '@', QT_MAC_MAP_ENUM(Qt::Key_At) }, + { ' ', QT_MAC_MAP_ENUM(Qt::Key_Space) }, + { '!', QT_MAC_MAP_ENUM(Qt::Key_Exclam) }, + { '"', QT_MAC_MAP_ENUM(Qt::Key_QuoteDbl) }, + { '#', QT_MAC_MAP_ENUM(Qt::Key_NumberSign) }, + { '$', QT_MAC_MAP_ENUM(Qt::Key_Dollar) }, + { '%', QT_MAC_MAP_ENUM(Qt::Key_Percent) }, + { '&', QT_MAC_MAP_ENUM(Qt::Key_Ampersand) }, + { '\'', QT_MAC_MAP_ENUM(Qt::Key_Apostrophe) }, + { '(', QT_MAC_MAP_ENUM(Qt::Key_ParenLeft) }, + { ')', QT_MAC_MAP_ENUM(Qt::Key_ParenRight) }, + { '*', QT_MAC_MAP_ENUM(Qt::Key_Asterisk) }, + { '+', QT_MAC_MAP_ENUM(Qt::Key_Plus) }, + { ',', QT_MAC_MAP_ENUM(Qt::Key_Comma) }, + { '-', QT_MAC_MAP_ENUM(Qt::Key_Minus) }, + { '.', QT_MAC_MAP_ENUM(Qt::Key_Period) }, + { '/', QT_MAC_MAP_ENUM(Qt::Key_Slash) }, + { '[', QT_MAC_MAP_ENUM(Qt::Key_BracketLeft) }, + { ']', QT_MAC_MAP_ENUM(Qt::Key_BracketRight) }, + { '\\', QT_MAC_MAP_ENUM(Qt::Key_Backslash) }, + { '_', QT_MAC_MAP_ENUM(Qt::Key_Underscore) }, + { '`', QT_MAC_MAP_ENUM(Qt::Key_QuoteLeft) }, + { '{', QT_MAC_MAP_ENUM(Qt::Key_BraceLeft) }, + { '}', QT_MAC_MAP_ENUM(Qt::Key_BraceRight) }, + { '|', QT_MAC_MAP_ENUM(Qt::Key_Bar) }, + { '~', QT_MAC_MAP_ENUM(Qt::Key_AsciiTilde) }, + { '^', QT_MAC_MAP_ENUM(Qt::Key_AsciiCircum) }, + { 0, QT_MAC_MAP_ENUM(0) } +}; + +static qt_mac_enum_mapper qt_mac_keyvkey_symbols[] = { //real scan codes + { 122, QT_MAC_MAP_ENUM(Qt::Key_F1) }, + { 120, QT_MAC_MAP_ENUM(Qt::Key_F2) }, + { 99, QT_MAC_MAP_ENUM(Qt::Key_F3) }, + { 118, QT_MAC_MAP_ENUM(Qt::Key_F4) }, + { 96, QT_MAC_MAP_ENUM(Qt::Key_F5) }, + { 97, QT_MAC_MAP_ENUM(Qt::Key_F6) }, + { 98, QT_MAC_MAP_ENUM(Qt::Key_F7) }, + { 100, QT_MAC_MAP_ENUM(Qt::Key_F8) }, + { 101, QT_MAC_MAP_ENUM(Qt::Key_F9) }, + { 109, QT_MAC_MAP_ENUM(Qt::Key_F10) }, + { 103, QT_MAC_MAP_ENUM(Qt::Key_F11) }, + { 111, QT_MAC_MAP_ENUM(Qt::Key_F12) }, + { 105, QT_MAC_MAP_ENUM(Qt::Key_F13) }, + { 107, QT_MAC_MAP_ENUM(Qt::Key_F14) }, + { 113, QT_MAC_MAP_ENUM(Qt::Key_F15) }, + { 106, QT_MAC_MAP_ENUM(Qt::Key_F16) }, + { 0, QT_MAC_MAP_ENUM(0) } +}; + +static qt_mac_enum_mapper qt_mac_private_unicode[] = { + { 0xF700, QT_MAC_MAP_ENUM(Qt::Key_Up) }, //NSUpArrowFunctionKey + { 0xF701, QT_MAC_MAP_ENUM(Qt::Key_Down) }, //NSDownArrowFunctionKey + { 0xF702, QT_MAC_MAP_ENUM(Qt::Key_Left) }, //NSLeftArrowFunctionKey + { 0xF703, QT_MAC_MAP_ENUM(Qt::Key_Right) }, //NSRightArrowFunctionKey + { 0xF727, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertFunctionKey + { 0xF728, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteFunctionKey + { 0xF729, QT_MAC_MAP_ENUM(Qt::Key_Home) }, //NSHomeFunctionKey + { 0xF72B, QT_MAC_MAP_ENUM(Qt::Key_End) }, //NSEndFunctionKey + { 0xF72C, QT_MAC_MAP_ENUM(Qt::Key_PageUp) }, //NSPageUpFunctionKey + { 0xF72D, QT_MAC_MAP_ENUM(Qt::Key_PageDown) }, //NSPageDownFunctionKey + { 0xF72F, QT_MAC_MAP_ENUM(Qt::Key_ScrollLock) }, //NSScrollLockFunctionKey + { 0xF730, QT_MAC_MAP_ENUM(Qt::Key_Pause) }, //NSPauseFunctionKey + { 0xF731, QT_MAC_MAP_ENUM(Qt::Key_SysReq) }, //NSSysReqFunctionKey + { 0xF735, QT_MAC_MAP_ENUM(Qt::Key_Menu) }, //NSMenuFunctionKey + { 0xF738, QT_MAC_MAP_ENUM(Qt::Key_Print) }, //NSPrintFunctionKey + { 0xF73A, QT_MAC_MAP_ENUM(Qt::Key_Clear) }, //NSClearDisplayFunctionKey + { 0xF73D, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertCharFunctionKey + { 0xF73E, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteCharFunctionKey + { 0xF741, QT_MAC_MAP_ENUM(Qt::Key_Select) }, //NSSelectFunctionKey + { 0xF742, QT_MAC_MAP_ENUM(Qt::Key_Execute) }, //NSExecuteFunctionKey + { 0xF746, QT_MAC_MAP_ENUM(Qt::Key_Help) }, //NSHelpFunctionKey + { 0xF747, QT_MAC_MAP_ENUM(Qt::Key_Mode_switch) }, //NSModeSwitchFunctionKey + { 0, QT_MAC_MAP_ENUM(0) } +}; + +static int qt_mac_get_key(int modif, const QChar &key, int virtualKey) +{ +#ifdef DEBUG_KEY_BINDINGS + qDebug("**Mapping key: %d (0x%04x) - %d (0x%04x)", key.unicode(), key.unicode(), virtualKey, virtualKey); +#endif + + if (key == kClearCharCode && virtualKey == 0x47) + return Qt::Key_Clear; + + if (key.isDigit()) { +#ifdef DEBUG_KEY_BINDINGS + qDebug("%d: got key: %d", __LINE__, key.digitValue()); +#endif + return key.digitValue() + Qt::Key_0; + } + + if (key.isLetter()) { +#ifdef DEBUG_KEY_BINDINGS + qDebug("%d: got key: %d", __LINE__, (key.toUpper().unicode() - 'A')); +#endif + return (key.toUpper().unicode() - 'A') + Qt::Key_A; + } + if (key.isSymbol()) { +#ifdef DEBUG_KEY_BINDINGS + qDebug("%d: got key: %d", __LINE__, (key.unicode())); +#endif + return key.unicode(); + } + + for (int i = 0; qt_mac_keyboard_symbols[i].qt_code; i++) { + if (qt_mac_keyboard_symbols[i].mac_code == key) { + /* To work like Qt for X11 we issue Backtab when Shift + Tab are pressed */ + if (qt_mac_keyboard_symbols[i].qt_code == Qt::Key_Tab && (modif & Qt::ShiftModifier)) { +#ifdef DEBUG_KEY_BINDINGS + qDebug("%d: got key: Qt::Key_Backtab", __LINE__); +#endif + return Qt::Key_Backtab; + } + +#ifdef DEBUG_KEY_BINDINGS + qDebug("%d: got key: %s", __LINE__, qt_mac_keyboard_symbols[i].desc); +#endif + return qt_mac_keyboard_symbols[i].qt_code; + } + } + + //last ditch try to match the scan code + for (int i = 0; qt_mac_keyvkey_symbols[i].qt_code; i++) { + if (qt_mac_keyvkey_symbols[i].mac_code == virtualKey) { +#ifdef DEBUG_KEY_BINDINGS + qDebug("%d: got key: %s", __LINE__, qt_mac_keyvkey_symbols[i].desc); +#endif + return qt_mac_keyvkey_symbols[i].qt_code; + } + } + + // check if they belong to key codes in private unicode range + if (key >= 0xf700 && key <= 0xf747) { + if (key >= 0xf704 && key <= 0xf726) { + return Qt::Key_F1 + (key.unicode() - 0xf704) ; + } + for (int i = 0; qt_mac_private_unicode[i].qt_code; i++) { + if (qt_mac_private_unicode[i].mac_code == key) { + return qt_mac_private_unicode[i].qt_code; + } + } + + } + + //oh well +#ifdef DEBUG_KEY_BINDINGS + qDebug("Unknown case.. %s:%d %d[%d] %d", __FILE__, __LINE__, key.unicode(), key.toLatin1(), virtualKey); +#endif + return Qt::Key_unknown; +} + +QCocoaKeyMapper::QCocoaKeyMapper() +{ + memset(keyLayout, 0, sizeof(keyLayout)); + keyboard_layout_format.unicode = 0; + currentInputSource = 0; +} + +QCocoaKeyMapper::~QCocoaKeyMapper() +{ + deleteLayouts(); +} + +bool QCocoaKeyMapper::updateKeyboard() +{ + const UCKeyboardLayout *uchrData = 0; + QCFType<TISInputSourceRef> source = TISCopyCurrentKeyboardInputSource(); + if (keyboard_mode != NullMode && source == currentInputSource) { + return false; + } + Q_ASSERT(source != 0); + CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(source, + kTISPropertyUnicodeKeyLayoutData)); + uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0; + + keyboard_kind = LMGetKbdType(); + if (uchrData) { + keyboard_layout_format.unicode = uchrData; + keyboard_mode = UnicodeMode; + } + currentInputSource = source; + keyboard_dead = 0; + CFStringRef iso639Code; + + CFArrayRef array = static_cast<CFArrayRef>(TISGetInputSourceProperty(currentInputSource, kTISPropertyInputSourceLanguages)); + iso639Code = static_cast<CFStringRef>(CFArrayGetValueAtIndex(array, 0)); // Actually a RFC3066bis, but it's close enough + + if (iso639Code) { + keyboardInputLocale = QLocale(QCFString::toQString(iso639Code)); + keyboardInputDirection = keyboardInputLocale.textDirection(); + } else { + keyboardInputLocale = QLocale::c(); + keyboardInputDirection = Qt::LeftToRight; + } + return true; +} + +void QCocoaKeyMapper::deleteLayouts() +{ + keyboard_mode = NullMode; + for (int i = 0; i < 255; ++i) { + if (keyLayout[i]) { + delete keyLayout[i]; + keyLayout[i] = 0; + } + } +} + +void QCocoaKeyMapper::clearMappings() +{ + deleteLayouts(); + updateKeyboard(); +} + +void QCocoaKeyMapper::updateKeyMap(unsigned short macVirtualKey, QChar unicodeKey) +{ + if (updateKeyboard()) { + // ### Qt 4 did this: + // QKeyMapper::changeKeyboard(); + } + if (keyLayout[macVirtualKey]) + return; + + UniCharCount buffer_size = 10; + UniChar buffer[buffer_size]; + keyLayout[macVirtualKey] = new KeyboardLayoutItem; + for (int i = 0; i < 16; ++i) { + UniCharCount out_buffer_size = 0; + keyLayout[macVirtualKey]->qtKey[i] = 0; + + const UInt32 keyModifier = ((qt_mac_get_mac_modifiers(ModsTbl[i]) >> 8) & 0xFF); + OSStatus err = UCKeyTranslate(keyboard_layout_format.unicode, macVirtualKey, kUCKeyActionDown, keyModifier, + keyboard_kind, 0, &keyboard_dead, buffer_size, &out_buffer_size, buffer); + if (err == noErr && out_buffer_size) { + const QChar unicode(buffer[0]); + int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey); + if (qtkey == Qt::Key_unknown) + qtkey = unicode.unicode(); + keyLayout[macVirtualKey]->qtKey[i] = qtkey; + } else { + int qtkey = qt_mac_get_key(keyModifier, unicodeKey, macVirtualKey); + if (qtkey == Qt::Key_unknown) + qtkey = unicodeKey.unicode(); + keyLayout[macVirtualKey]->qtKey[i] = qtkey; + } + } +#ifdef DEBUG_KEY_MAPS + qDebug("updateKeyMap for virtual key = 0x%02x!", (uint)macVirtualKey); + for (int i = 0; i < 16; ++i) { + qDebug(" [%d] (%d,0x%02x,'%c')", i, + keyLayout[macVirtualKey]->qtKey[i], + keyLayout[macVirtualKey]->qtKey[i], + keyLayout[macVirtualKey]->qtKey[i]); + } +#endif +} + +QList<int> QCocoaKeyMapper::possibleKeys(const QKeyEvent *event) const +{ + QList<int> ret; + const_cast<QCocoaKeyMapper *>(this)->updateKeyMap(event->nativeVirtualKey(), QChar(event->key())); + + KeyboardLayoutItem *kbItem = keyLayout[event->nativeVirtualKey()]; + + if (!kbItem) // Key is not in any keyboard layout (e.g. eisu-key on Japanese keyboard) + return ret; + + int baseKey = kbItem->qtKey[0]; + Qt::KeyboardModifiers keyMods = event->modifiers(); + + ret << int(baseKey + keyMods); // The base key is _always_ valid, of course + + for (int i = 1; i < 8; ++i) { + Qt::KeyboardModifiers neededMods = ModsTbl[i]; + int key = kbItem->qtKey[i]; + if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) { + ret << int(key + (keyMods & ~neededMods)); + } + } + return ret; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index f0b1bd330a..271c9d2894 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -107,8 +107,10 @@ QPlatformPrinterSupport *QCocoaNativeInterface::createPlatformPrinterSupport() void *QCocoaNativeInterface::NSPrintInfoForPrintEngine(QPrintEngine *printEngine) { #ifndef QT_NO_WIDGETS - QMacPrintEngine *macPrintEngine = static_cast<QMacPrintEngine *>(printEngine); - return macPrintEngine->d_func()->printInfo; + QMacPrintEnginePrivate *macPrintEnginePriv = static_cast<QMacPrintEngine *>(printEngine)->d_func(); + if (macPrintEnginePriv->state == QPrinter::Idle && !macPrintEnginePriv->isPrintSessionInitialized()) + macPrintEnginePriv->initialize(); + return macPrintEnginePriv->printInfo; #else qFatal("Printing is not supported when Qt is configured with -no-widgets"); return 0; diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index aacf47ec43..692e504432 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -96,6 +96,8 @@ QColor qt_mac_colorForThemeTextColor(ThemeTextColor themeColor) case kThemeTextColorTabFrontInactive: case kThemeTextColorBevelButtonInactive: return QColor(127, 127, 127, 255); + case kThemeTextColorMenuItemSelected: + return Qt::white; default: return QColor(0, 0, 0, 255); // ### TODO: Sample color like Qt 4. } @@ -153,21 +155,19 @@ struct QMacPaletteMap { }; static QMacPaletteMap mac_widget_colors[] = { -// TODO (msorvig): Fix/match palette behavior with Qt 4 and enable. -// -// QMacPaletteMap(QPlatformTheme::ToolButtonPalette, kThemeTextColorBevelButtonActive, kThemeTextColorBevelButtonInactive), -// QMacPaletteMap(QPlatformTheme::ButtonPalette, kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive), -// QMacPaletteMap(QPlatformTheme::HeaderPalette, kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive), -// QMacPaletteMap(QPlatformTheme::ComboBoxPalette, kThemeTextColorPopupButtonActive, kThemeTextColorPopupButtonInactive), -// QMacPaletteMap(QPlatformTheme::ItemViewPalette, kThemeTextColorListView, kThemeTextColorDialogInactive), -// QMacPaletteMap(QPlatformTheme::MessageBoxLabelPelette, kThemeTextColorAlertActive, kThemeTextColorAlertInactive), -// QMacPaletteMap(QPlatformTheme::TabBarPalette, kThemeTextColorTabFrontActive, kThemeTextColorTabFrontInactive), -// QMacPaletteMap(QPlatformTheme::LabelPalette, kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive), -// QMacPaletteMap(QPlatformTheme::GroupBoxPalette, kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive), -// QMacPaletteMap(QPlatformTheme::MenuPalette, kThemeTextColorPopupLabelActive, kThemeTextColorPopupLabelInactive), -// ### TODO: The zeros below gives white-on-black text. -// QMacPaletteMap(QPlatformTheme::TextEditPalette, 0, 0), -// QMacPaletteMap(QPlatformTheme::TextLineEditPalette, 0, 0), + QMacPaletteMap(QPlatformTheme::ToolButtonPalette, kThemeTextColorBevelButtonActive, kThemeTextColorBevelButtonInactive), + QMacPaletteMap(QPlatformTheme::ButtonPalette, kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive), + QMacPaletteMap(QPlatformTheme::HeaderPalette, kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive), + QMacPaletteMap(QPlatformTheme::ComboBoxPalette, kThemeTextColorPopupButtonActive, kThemeTextColorPopupButtonInactive), + QMacPaletteMap(QPlatformTheme::ItemViewPalette, kThemeTextColorListView, kThemeTextColorDialogInactive), + QMacPaletteMap(QPlatformTheme::MessageBoxLabelPelette, kThemeTextColorAlertActive, kThemeTextColorAlertInactive), + QMacPaletteMap(QPlatformTheme::TabBarPalette, kThemeTextColorTabFrontActive, kThemeTextColorTabFrontInactive), + QMacPaletteMap(QPlatformTheme::LabelPalette, kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive), + QMacPaletteMap(QPlatformTheme::GroupBoxPalette, kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive), + QMacPaletteMap(QPlatformTheme::MenuPalette, kThemeTextColorPopupLabelActive, kThemeTextColorPopupLabelInactive), + //### TODO: The zeros below gives white-on-black text. + QMacPaletteMap(QPlatformTheme::TextEditPalette, 0, 0), + QMacPaletteMap(QPlatformTheme::TextLineEditPalette, 0, 0), QMacPaletteMap(QPlatformTheme::NPalettes, 0, 0) }; QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes() @@ -175,7 +175,7 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes() QHash<QPlatformTheme::Palette, QPalette*> palettes; QColor qc; for (int i = 0; mac_widget_colors[i].paletteRole != QPlatformTheme::NPalettes; i++) { - QPalette pal; + QPalette pal = *qt_mac_createSystemPalette(); if (mac_widget_colors[i].active != 0) { qc = qt_mac_colorForThemeTextColor(mac_widget_colors[i].active); pal.setColor(QPalette::Active, QPalette::Text, qc); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index f786e6969f..b545844a24 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -49,6 +49,7 @@ #include <QtCore/qfileinfo.h> #include <QtCore/private/qcore_mac_p.h> #include <qwindow.h> +#include <private/qwindow_p.h> #include <qpa/qwindowsysteminterface.h> #include <qpa/qplatformscreen.h> @@ -372,9 +373,9 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) if (flags == Qt::Window) { styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); } else if ((flags & Qt::Dialog) && (window()->modality() != Qt::NonModal)) { - styleMask = NSTitledWindowMask; + styleMask = NSResizableWindowMask | NSTitledWindowMask; } else if (!(flags & Qt::FramelessWindowHint)) { - if (flags & Qt::WindowMaximizeButtonHint) + if ((flags & Qt::Dialog) || (flags & Qt::WindowMaximizeButtonHint)) styleMask |= NSResizableWindowMask; if (flags & Qt::WindowTitleHint) styleMask |= NSTitledWindowMask; @@ -590,9 +591,7 @@ void QCocoaWindow::windowDidResize() if (!m_nsWindow) return; - NSRect rect = [[m_nsWindow contentView]frame]; - // Call setFrameSize which will trigger a frameDidChangeNotification on QNSView. - [[m_nsWindow contentView] setFrameSize:rect.size]; + [m_contentView updateGeometry]; } void QCocoaWindow::windowWillClose() @@ -651,6 +650,10 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) NSRect frame = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); [m_contentView setFrame:frame]; } + + const qreal opacity = qt_window_private(window())->opacity; + if (!qFuzzyCompare(opacity, qreal(1.0))) + setOpacity(opacity); } NSWindow * QCocoaWindow::createNSWindow() diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index f93fd86205..9cdfe6f5bb 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -66,6 +66,7 @@ QT_END_NAMESPACE QString m_composingText; bool m_sendKeyEvent; QStringList *currentCustomDragTypes; + bool m_sendUpAsRightButton; Qt::KeyboardModifiers currentWheelModifiers; bool m_subscribesForGlobalFrameNotifications; } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index b608989e43..678f88baa0 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -84,6 +84,7 @@ static QTouchDevice *touchDevice = 0; m_sendKeyEvent = false; m_subscribesForGlobalFrameNotifications = false; currentCustomDragTypes = 0; + m_sendUpAsRightButton = false; if (!touchDevice) { touchDevice = new QTouchDevice; @@ -184,6 +185,9 @@ static QTouchDevice *touchDevice = 0; geometry = qt_mac_toQRect([self frame]); } + if (m_platformWindow->m_nsWindow && geometry == m_platformWindow->geometry()) + return; + #ifdef QT_COCOA_ENABLE_WINDOW_DEBUG qDebug() << "QNSView::udpateGeometry" << m_platformWindow << geometry; #endif @@ -312,6 +316,7 @@ static QTouchDevice *touchDevice = 0; ); CGImageRef bsCGImage = m_backingStore->getBackingStoreCGImage(); CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect); + CGContextSetBlendMode(cgContext, kCGBlendModeCopy); CGContextDrawImage(cgContext, dirtyWindowRect, cleanImg); // Clean-up: @@ -427,6 +432,7 @@ static QTouchDevice *touchDevice = 0; - (void)mouseDown:(NSEvent *)theEvent { + m_sendUpAsRightButton = false; if (m_platformWindow->m_activePopupWindow) { QWindowSystemInterface::handleCloseEvent(m_platformWindow->m_activePopupWindow); QWindowSystemInterface::flushWindowSystemEvents(); @@ -438,7 +444,12 @@ static QTouchDevice *touchDevice = 0; [inputManager handleMouseEvent:theEvent]; } } else { - m_buttons |= Qt::LeftButton; + if ([self convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) { + m_buttons |= Qt::RightButton; + m_sendUpAsRightButton = true; + } else { + m_buttons |= Qt::LeftButton; + } [self handleMouseEvent:theEvent]; } } @@ -452,7 +463,12 @@ static QTouchDevice *touchDevice = 0; - (void)mouseUp:(NSEvent *)theEvent { - m_buttons &= QFlag(~int(Qt::LeftButton)); + if (m_sendUpAsRightButton) { + m_buttons &= QFlag(~int(Qt::RightButton)); + m_sendUpAsRightButton = false; + } else { + m_buttons &= QFlag(~int(Qt::LeftButton)); + } [self handleMouseEvent:theEvent]; } @@ -740,9 +756,19 @@ static QTouchDevice *touchDevice = 0; - (void)handleKeyEvent:(NSEvent *)nsevent eventType:(int)eventType { ulong timestamp = [nsevent timestamp] * 1000; - Qt::KeyboardModifiers modifiers = [self convertKeyModifiers:[nsevent modifierFlags]]; + ulong nativeModifiers = [nsevent modifierFlags]; + Qt::KeyboardModifiers modifiers = [self convertKeyModifiers: nativeModifiers]; NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers]; + // [from Qt 4 impl] There is no way to get the scan code from carbon. But we cannot + // use the value 0, since it indicates that the event originates from somewhere + // else than the keyboard. + quint32 nativeScanCode = 1; + + UInt32 nativeVirtualKey = 0; + EventRef eventRef = EventRef([nsevent eventRef]); + GetEventParameter(eventRef, kEventParamKeyCode, typeUInt32, 0, sizeof(nativeVirtualKey), 0, &nativeVirtualKey); + QChar ch; int keyCode; if ([charactersIgnoringModifiers length] > 0) { @@ -783,7 +809,8 @@ static QTouchDevice *touchDevice = 0; } if (m_sendKeyEvent && m_composingText.isEmpty()) - QWindowSystemInterface::handleKeyEvent(m_window, timestamp, QEvent::Type(eventType), keyCode, modifiers, text); + QWindowSystemInterface::handleExtendedKeyEvent(m_window, timestamp, QEvent::Type(eventType), keyCode, modifiers, + nativeScanCode, nativeVirtualKey, nativeModifiers, text); m_sendKeyEvent = false; } diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm index 6824f19489..da714d3326 100644 --- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm +++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm @@ -80,7 +80,7 @@ [kids addObject:[QCocoaAccessibleElement elementWithInterface: m_accessibleRoot->child(i) parent:self ]]; } - return NSAccessibilityUnignoredChildren(kids); + return kids; } else { return [super accessibilityAttributeValue:attribute]; } diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro index 29c5ebd99b..ec4a612b52 100644 --- a/src/plugins/platforms/directfb/directfb.pro +++ b/src/plugins/platforms/directfb/directfb.pro @@ -1,6 +1,7 @@ TARGET = qdirectfb PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QDirectFbIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.cpp b/src/plugins/platforms/directfb/qdirectfbblitter.cpp index cac250fb9d..ec6ecd540c 100644 --- a/src/plugins/platforms/directfb/qdirectfbblitter.cpp +++ b/src/plugins/platforms/directfb/qdirectfbblitter.cpp @@ -133,7 +133,7 @@ void QDirectFbBlitter::alphaFillRect(const QRectF &rect, const QColor &color, QP int x, y, w, h; DFBResult result; - // check paramters + // check parameters rect.toRect().getRect(&x, &y ,&w, &h); if ((w <= 0) || (h <= 0)) return; diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.cpp b/src/plugins/platforms/directfb/qdirectfbcursor.cpp index 1ff71f3e63..b04848ec40 100644 --- a/src/plugins/platforms/directfb/qdirectfbcursor.cpp +++ b/src/plugins/platforms/directfb/qdirectfbcursor.cpp @@ -47,9 +47,12 @@ QT_BEGIN_NAMESPACE QDirectFBCursor::QDirectFBCursor(QPlatformScreen *screen) : m_screen(screen) { +#ifndef QT_NO_CURSOR m_image.reset(new QPlatformCursorImage(0, 0, 0, 0, 0, 0)); +#endif } +#ifndef QT_NO_CURSOR void QDirectFBCursor::changeCursor(QCursor *cursor, QWindow *) { int xSpot; @@ -82,5 +85,6 @@ void QDirectFBCursor::changeCursor(QCursor *cursor, QWindow *) layer->SetCursorShape(layer, surface, xSpot, ySpot); layer->SetCooperativeLevel(layer, DLSCL_SHARED); } +#endif QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.h b/src/plugins/platforms/directfb/qdirectfbcursor.h index bd11b97467..21f205a5a1 100644 --- a/src/plugins/platforms/directfb/qdirectfbcursor.h +++ b/src/plugins/platforms/directfb/qdirectfbcursor.h @@ -56,10 +56,14 @@ class QDirectFBCursor : public QPlatformCursor { public: QDirectFBCursor(QPlatformScreen *screen); +#ifndef QT_NO_CURSOR void changeCursor(QCursor *cursor, QWindow *window); +#endif private: +#ifndef QT_NO_CURSOR QScopedPointer<QPlatformCursorImage> m_image; +#endif QPlatformScreen *m_screen; }; diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index 1223b6b133..45059a9cb9 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -1,6 +1,7 @@ TARGET = qeglfs PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QEglFSIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp index 85bc8679f2..b29849226f 100644 --- a/src/plugins/platforms/eglfs/qeglfscursor.cpp +++ b/src/plugins/platforms/eglfs/qeglfscursor.cpp @@ -55,8 +55,10 @@ QEglFSCursor::QEglFSCursor(QEglFSScreen *screen) initCursorAtlas(); // initialize the cursor +#ifndef QT_NO_CURSOR QCursor cursor(Qt::ArrowCursor); setCurrentCursor(&cursor); +#endif } QEglFSCursor::~QEglFSCursor() @@ -183,6 +185,7 @@ void QEglFSCursor::initCursorAtlas() m_cursorAtlas.image = image; } +#ifndef QT_NO_CURSOR void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window) { Q_UNUSED(window); @@ -221,6 +224,7 @@ bool QEglFSCursor::setCurrentCursor(QCursor *cursor) return true; } +#endif void QEglFSCursor::update(const QRegion &rgn) { diff --git a/src/plugins/platforms/eglfs/qeglfscursor.h b/src/plugins/platforms/eglfs/qeglfscursor.h index 9a91b73894..1c82abdb44 100644 --- a/src/plugins/platforms/eglfs/qeglfscursor.h +++ b/src/plugins/platforms/eglfs/qeglfscursor.h @@ -57,7 +57,9 @@ public: QEglFSCursor(QEglFSScreen *screen); ~QEglFSCursor(); +#ifndef QT_NO_CURSOR void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE; +#endif void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE; QPoint pos() const Q_DECL_OVERRIDE; @@ -68,7 +70,9 @@ public: virtual void paintOnScreen(); protected: +#ifndef QT_NO_CURSOR bool setCurrentCursor(QCursor *cursor); +#endif void draw(const QRectF &rect); void update(const QRegion ®ion); diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp index f60b9ee83d..7106b99490 100644 --- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp +++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE void QEglFSHooks::platformInit() { + Q_UNUSED(hooks); } void QEglFSHooks::platformDestroy() diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 32d20e6aaa..df665cea84 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -75,7 +75,7 @@ void QEglFSWindow::create() if (m_window) return; - if (window()->windowType() == Qt::Desktop) { + if (window()->type() == Qt::Desktop) { QRect rect(QPoint(), hooks->screenSize()); QPlatformWindow::setGeometry(rect); QWindowSystemInterface::handleGeometryChange(window(), rect); diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro index 57191d8d97..c0300e0960 100644 --- a/src/plugins/platforms/kms/kms.pro +++ b/src/plugins/platforms/kms/kms.pro @@ -1,6 +1,7 @@ TARGET = qkms PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QKmsIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private opengl-private diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro index 2482a64469..9e9f9b29b7 100644 --- a/src/plugins/platforms/linuxfb/linuxfb.pro +++ b/src/plugins/platforms/linuxfb/linuxfb.pro @@ -1,6 +1,7 @@ TARGET = qlinuxfb PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QLinuxFbIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index 9c3d37269c..3131b16232 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -1,6 +1,7 @@ TARGET = qminimal PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/minimalegl/minimalegl.pro b/src/plugins/platforms/minimalegl/minimalegl.pro index 23a6ad9708..00c83eb1ca 100644 --- a/src/plugins/platforms/minimalegl/minimalegl.pro +++ b/src/plugins/platforms/minimalegl/minimalegl.pro @@ -1,6 +1,7 @@ TARGET = qminimalegl PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QMinimalEglIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/openwfd/openwf.pro b/src/plugins/platforms/openwfd/openwf.pro index 1b177cba04..2dbcb282db 100644 --- a/src/plugins/platforms/openwfd/openwf.pro +++ b/src/plugins/platforms/openwfd/openwf.pro @@ -1,6 +1,7 @@ TARGET = qopenwf PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QOpenWFDIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index fa5f69769c..203cdebda9 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -1,4 +1,4 @@ -TARGET = qnx +TARGET = qqnx QT += platformsupport platformsupport-private @@ -140,4 +140,5 @@ include (../../../platformsupport/eglconvenience/eglconvenience.pri) include (../../../platformsupport/fontdatabases/fontdatabases.pri) PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QQnxIntegrationPlugin load(qt_plugin) diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp index 262bdb16f4..79d7c7d9ca 100644 --- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp +++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper.cpp @@ -43,6 +43,7 @@ #include "qqnxbpseventfilter.h" #include "qqnxscreen.h" +#include "qqnxintegration.h" #include <QDebug> #include <QEventLoop> @@ -58,9 +59,9 @@ QT_BEGIN_NAMESPACE -QQnxFileDialogHelper::QQnxFileDialogHelper(QQnxBpsEventFilter *eventFilter) +QQnxFileDialogHelper::QQnxFileDialogHelper(const QQnxIntegration *integration) : QPlatformFileDialogHelper(), - m_eventFilter(eventFilter), + m_integration(integration), m_dialog(0), m_acceptMode(QFileDialogOptions::AcceptOpen), m_selectedFilter(), @@ -144,8 +145,9 @@ bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modali Q_UNUSED(flags); qFileDialogHelperDebug() << Q_FUNC_INFO; + QQnxBpsEventFilter *eventFilter = m_integration->bpsEventFilter(); // We *really* need the bps event filter ;) - if (!m_eventFilter) + if (!eventFilter) return false; // Native dialogs can only handle application modal use cases so far @@ -208,12 +210,15 @@ bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modali m_acceptMode = opts->acceptMode(); // Set the libscreen window group and common properties - QQnxScreen *nativeScreen = static_cast<QQnxScreen *>(parent->screen()->handle()); + + QQnxScreen *nativeScreen = parent ? static_cast<QQnxScreen *>(parent->screen()->handle()) : + m_integration->primaryDisplay(); + Q_ASSERT(nativeScreen); dialog_set_group_id(m_dialog, nativeScreen->windowGroupName()); dialog_set_title_text(m_dialog, opts->windowTitle().toLocal8Bit().constData()); // Register ourselves for dialog domain events from bps - m_eventFilter->registerForDialogEvents(this); + eventFilter->registerForDialogEvents(this); // Show the dialog dialog_show(m_dialog); diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h index 352709c763..e17ea80501 100644 --- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h +++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h @@ -48,13 +48,13 @@ QT_BEGIN_NAMESPACE -class QQnxBpsEventFilter; +class QQnxIntegration; class QQnxFileDialogHelper : public QPlatformFileDialogHelper { Q_OBJECT public: - explicit QQnxFileDialogHelper(QQnxBpsEventFilter *eventFilter); + explicit QQnxFileDialogHelper(const QQnxIntegration *); ~QQnxFileDialogHelper(); bool handleEvent(bps_event_t *event); @@ -81,7 +81,7 @@ Q_SIGNALS: private: void setNameFilter(const QString &filter); - QQnxBpsEventFilter *m_eventFilter; + const QQnxIntegration *m_integration; dialog_instance_t m_dialog; QFileDialogOptions::AcceptMode m_acceptMode; QString m_selectedFilter; diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index e594ea952d..bff4dbdc2a 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -406,7 +406,7 @@ QPlatformTheme *QQnxIntegration::createPlatformTheme(const QString &name) const { qIntegrationDebug() << Q_FUNC_INFO << "name =" << name; if (name == QQnxTheme::name()) - return new QQnxTheme(m_fontDatabase, m_bpsEventFilter); + return new QQnxTheme(this); return QPlatformIntegration::createPlatformTheme(name); } #endif diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index 97a5e631e8..e3eb9e06ba 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -128,10 +128,10 @@ public: void createDisplay(screen_display_t display, bool isPrimary); void removeDisplay(QQnxScreen *screen); + QQnxScreen *primaryDisplay() const; private: void createDisplays(); void destroyDisplays(); - QQnxScreen *primaryDisplay() const; static void addWindow(screen_window_t qnxWindow, QWindow *window); static void removeWindow(screen_window_t qnxWindow); diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 3b57f5d4e5..5450f086e9 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -429,7 +429,7 @@ void QQnxScreen::addWindow(QQnxWindow *window) // Such a situation would strangely break focus handling due to the // invisible desktop widget window being layered on top of normal // windows - if (window->window()->windowType() == Qt::Desktop) + if (window->window()->type() == Qt::Desktop) m_childWindows.push_front(window); else m_childWindows.push_back(window); diff --git a/src/plugins/platforms/qnx/qqnxtheme.cpp b/src/plugins/platforms/qnx/qqnxtheme.cpp index be62c3e410..ae9acd845e 100644 --- a/src/plugins/platforms/qnx/qqnxtheme.cpp +++ b/src/plugins/platforms/qnx/qqnxtheme.cpp @@ -43,13 +43,11 @@ #include "qqnxfiledialoghelper.h" #include "qqnxsystemsettings.h" +#include "qqnxintegration.h" QT_BEGIN_NAMESPACE -QQnxTheme::QQnxTheme(QPlatformFontDatabase *fontDatabase, - QQnxBpsEventFilter *eventFilter) - : m_fontDatabase(fontDatabase), - m_eventFilter(eventFilter) +QQnxTheme::QQnxTheme(const QQnxIntegration *integration) : m_integration(integration) { } @@ -77,7 +75,7 @@ QPlatformDialogHelper *QQnxTheme::createPlatformDialogHelper(DialogType type) co { switch (type) { case QPlatformTheme::FileDialog: - return new QQnxFileDialogHelper(m_eventFilter); + return new QQnxFileDialogHelper(m_integration); #ifndef QT_NO_COLORDIALOG case QPlatformTheme::ColorDialog: #endif @@ -91,8 +89,10 @@ QPlatformDialogHelper *QQnxTheme::createPlatformDialogHelper(DialogType type) co const QFont *QQnxTheme::font(Font type) const { - if (m_fonts.isEmpty() && m_fontDatabase) - m_fonts = qt_qnx_createRoleFonts(m_fontDatabase); + QPlatformFontDatabase *fontDatabase = m_integration->fontDatabase(); + + if (fontDatabase && m_fonts.isEmpty()) + m_fonts = qt_qnx_createRoleFonts(fontDatabase); return m_fonts.value(type, 0); } diff --git a/src/plugins/platforms/qnx/qqnxtheme.h b/src/plugins/platforms/qnx/qqnxtheme.h index ea44d1cee2..17b2eab142 100644 --- a/src/plugins/platforms/qnx/qqnxtheme.h +++ b/src/plugins/platforms/qnx/qqnxtheme.h @@ -51,14 +51,12 @@ QT_BEGIN_NAMESPACE -class QQnxBpsEventFilter; - -class QPlatformFontDatabase; +class QQnxIntegration; class QQnxTheme : public QPlatformTheme { public: - QQnxTheme(QPlatformFontDatabase *fontDatabase, QQnxBpsEventFilter *eventFilter); + explicit QQnxTheme(const QQnxIntegration *); ~QQnxTheme(); static QString name() { return QStringLiteral("blackberry"); } @@ -69,9 +67,8 @@ public: const QFont *font(Font type = SystemFont) const; private: - QPlatformFontDatabase *m_fontDatabase; - QQnxBpsEventFilter *m_eventFilter; mutable QHash<QPlatformTheme::Font, QFont*> m_fonts; + const QQnxIntegration *m_integration; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp index 059dcb574b..3d2f49aa6c 100644 --- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp +++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp @@ -86,6 +86,11 @@ bool QQnxVirtualKeyboardBps::handleEvent(bps_event_t *event) bool QQnxVirtualKeyboardBps::showKeyboard() { qVirtualKeyboardDebug() << Q_FUNC_INFO << "current visibility=" << isVisible(); + + // They keyboard's mode is global between applications, we have to set it each time + if ( !isVisible() ) + applyKeyboardMode(keyboardMode()); + virtualkeyboard_show(); return true; } diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index e4505c6c60..af7a89a399 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -269,7 +269,7 @@ void QQnxWindow::setVisible(bool visible) root->updateVisibility(root->m_visible); - window()->requestActivateWindow(); + window()->requestActivate(); if (window()->isTopLevel() && visible) QWindowSystemInterface::handleExposeEvent(window(), window()->geometry()); @@ -511,8 +511,8 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen) Q_FOREACH (QQnxWindow *childWindow, m_childWindows) { // Only subwindows and tooltips need necessarily be moved to another display with the window. - if ((window()->windowType() & Qt::WindowType_Mask) == Qt::SubWindow || - (window()->windowType() & Qt::WindowType_Mask) == Qt::ToolTip) + if ((window()->type() & Qt::WindowType_Mask) == Qt::SubWindow || + (window()->type() & Qt::WindowType_Mask) == Qt::ToolTip) childWindow->setScreen(platformScreen); } diff --git a/src/plugins/platforms/windows/accessible/comutils.cpp b/src/plugins/platforms/windows/accessible/comutils.cpp index 5e5a1ebd0f..a67e2c4534 100644 --- a/src/plugins/platforms/windows/accessible/comutils.cpp +++ b/src/plugins/platforms/windows/accessible/comutils.cpp @@ -88,7 +88,7 @@ inline uint QColorToOLEColor(const QColor &col) return qRgba(col.blue(), col.green(), col.red(), 0x00); } -bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out) +bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out) { QVariant qvar = var; // "type" is the expected type, so coerce if necessary @@ -107,12 +107,12 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type } if (out && arg.vt == (VT_VARIANT|VT_BYREF) && arg.pvarVal) { - return QVariantToVARIANT(var, *arg.pvarVal, typeName, false); + return QVariant2VARIANT(var, *arg.pvarVal, typeName, false); } if (out && proptype == QVariant::UserType && typeName == "QVariant") { VARIANT *pVariant = new VARIANT; - QVariantToVARIANT(var, *pVariant, QByteArray(), false); + QVariant2VARIANT(var, *pVariant, QByteArray(), false); arg.vt = VT_VARIANT|VT_BYREF; arg.pvarVal = pVariant; return true; @@ -409,7 +409,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type for (LONG j = 0; j < columnCount; ++j) { QVariant elem = columns.at(j); VariantInit(&variant); - QVariantToVARIANT(elem, variant, elem.typeName()); + QVariant2VARIANT(elem, variant, elem.typeName()); rgIndices[1] = j; SafeArrayPutElement(array, rgIndices, pElement); clearVARIANT(&variant); @@ -425,7 +425,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type if (listType != QVariant::LastType) elem.convert(listType); VariantInit(&variant); - QVariantToVARIANT(elem, variant, elem.typeName()); + QVariant2VARIANT(elem, variant, elem.typeName()); SafeArrayPutElement(array, &index, pElement); clearVARIANT(&variant); } @@ -555,7 +555,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type arg.pRecInfo = recordInfo, arg.pvRecord = record; if (out) { - qWarning("QVariantToVARIANT: out-parameter not supported for records"); + qWarning("QVariant2VARIANT: out-parameter not supported for records"); return false; } } @@ -574,7 +574,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type if (arg.pdispVal) arg.pdispVal->AddRef(); if (out) { - qWarning("QVariantToVARIANT: out-parameter not supported for IDispatch"); + qWarning("QVariant2VARIANT: out-parameter not supported for IDispatch"); return false; } } else if (!qstrcmp(qvar.typeName(), "IDispatch**")) { @@ -588,7 +588,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type if (arg.punkVal) arg.punkVal->AddRef(); if (out) { - qWarning("QVariantToVARIANT: out-parameter not supported for IUnknown"); + qWarning("QVariant2VARIANT: out-parameter not supported for IUnknown"); return false; } #ifdef QAX_SERVER @@ -602,7 +602,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type qAxFactory()->createObjectWrapper(static_cast<QObject*>(user), &arg.pdispVal); } if (out) { - qWarning("QVariantToVARIANT: out-parameter not supported for subtype"); + qWarning("QVariant2VARIANT: out-parameter not supported for subtype"); return false; } #else @@ -612,7 +612,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type arg.vt = VT_DISPATCH; object->queryInterface(IID_IDispatch, (void**)&arg.pdispVal); if (out) { - qWarning("QVariantToVARIANT: out-parameter not supported for subtype"); + qWarning("QVariant2VARIANT: out-parameter not supported for subtype"); return false; } #endif diff --git a/src/plugins/platforms/windows/accessible/comutils.h b/src/plugins/platforms/windows/accessible/comutils.h index c9ed2b1224..8593f68d76 100644 --- a/src/plugins/platforms/windows/accessible/comutils.h +++ b/src/plugins/platforms/windows/accessible/comutils.h @@ -52,7 +52,8 @@ QT_BEGIN_NAMESPACE class QVariant; -bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out); +// Originally QVariantToVARIANT copied from ActiveQt - renamed to avoid conflicts in static builds. +bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out); inline QString BSTRToQString(const BSTR &bstr) { diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 03bb94db8f..838cd055ab 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -1425,7 +1425,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_currentValue(VARIANT *curre return E_FAIL; if (QAccessibleValueInterface *valueIface = valueInterface()) { const QVariant var = valueIface->currentValue(); - if (QVariantToVARIANT(var, *currentValue, QByteArray(), false)) + if (QVariant2VARIANT(var, *currentValue, QByteArray(), false)) return S_OK; } @@ -1456,7 +1456,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_maximumValue(VARIANT *maxim return E_FAIL; if (QAccessibleValueInterface *valueIface = valueInterface()) { const QVariant var = valueIface->maximumValue(); - if (QVariantToVARIANT(var, *maximumValue, QByteArray(), false)) + if (QVariant2VARIANT(var, *maximumValue, QByteArray(), false)) return S_OK; } maximumValue->vt = VT_EMPTY; @@ -1470,7 +1470,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_minimumValue(VARIANT *minim return E_FAIL; if (QAccessibleValueInterface *valueIface = valueInterface()) { const QVariant var = valueIface->minimumValue(); - if (QVariantToVARIANT(var, *minimumValue, QByteArray(), false)) + if (QVariant2VARIANT(var, *minimumValue, QByteArray(), false)) return S_OK; } minimumValue->vt = VT_EMPTY; diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index 94a5dd6a68..44a79d86ee 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -48,6 +48,7 @@ #include <QtCore/qlocale.h> #include <QtCore/qmap.h> #include <QtCore/qpair.h> +#include <QtCore/qpointer.h> #include <QtCore/qsettings.h> #include <QtGui/qaccessible.h> #include <QtGui/qaccessible2.h> @@ -87,10 +88,9 @@ // This stuff is used for widgets/items with no window handle: -typedef QMap<int, QPair<QObject*,int> > NotifyMap; +typedef QMap<int, QPair<QPointer<QObject>,int> > NotifyMap; Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents) - QT_BEGIN_NAMESPACE @@ -182,14 +182,25 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", window); static int eventNum = 0; - if (event->type() != QAccessible::MenuCommand) { // MenuCommand is faked - // See comment "SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE" + if (event->type() != QAccessible::MenuCommand && // MenuCommand is faked + event->type() != QAccessible::ObjectDestroyed) { + /* In some rare occasions, the server (Qt) might get a ::get_accChild call with a + childId that references an entry in the cache where there was a dangling + QObject-pointer. Previously we crashed on this. + + There is no point in actually notifying the AT client that the object got destroyed, + because the AT client won't query for get_accChild if the event is ObjectDestroyed + anyway, and we have no other way of mapping the eventId argument to the actual + child/descendant object. (Firefox seems to simply completely ignore + EVENT_OBJECT_DESTROY). + + We therefore guard each QObject in the cache with a QPointer, and only notify the AT + client if the type is not ObjectDestroyed. + */ eventNum %= 50; //[0..49] int eventId = - (eventNum - 1); - - qAccessibleRecentSentEvents()->insert(eventId, qMakePair(event->object(), event->child())); - ::NotifyWinEvent(event->type(), hWnd, OBJID_CLIENT, eventId ); - + qAccessibleRecentSentEvents()->insert(eventId, qMakePair(QPointer<QObject>(event->object()), event->child())); + ::NotifyWinEvent(event->type(), hWnd, OBJID_CLIENT, eventId); ++eventNum; } #endif // Q_OS_WINCE @@ -233,7 +244,8 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) */ QPair<QObject*, int> QWindowsAccessibility::getCachedObject(int entryId) { - return qAccessibleRecentSentEvents()->value(entryId); + QPair<QPointer<QObject>, int> pair = qAccessibleRecentSentEvents()->value(entryId); + return qMakePair(pair.first.data(), pair.second); } /* diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 328053604e..f1bdc77303 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -757,7 +757,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChild(VARIANT varChildI acc = res; } } else { - qWarning("get_accChild got a negative varChildID, but did not find it in cache"); + qWarning("get_accChild got a negative varChildID (%d), but did not find it in cache", childIndex); } } else { if (childIndex) { diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 5a1b4f1522..d4a8bd12d3 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1033,17 +1033,17 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, writingSystems.setSupported(ws); } - QPlatformFontDatabase::registerFont(familyName, foundryName, weight, + QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, weight, style, stretch, antialias, scalable, size, fixed, writingSystems, 0); // add fonts windows can generate for us: if (weight <= QFont::DemiBold) - QPlatformFontDatabase::registerFont(familyName, foundryName, QFont::Bold, + QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, style, stretch, antialias, scalable, size, fixed, writingSystems, 0); if (style != QFont::StyleItalic) - QPlatformFontDatabase::registerFont(familyName, foundryName, weight, + QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, weight, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, 0); if (weight <= QFont::DemiBold && style != QFont::StyleItalic) - QPlatformFontDatabase::registerFont(familyName, foundryName, QFont::Bold, + QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, 0); if (!englishName.isEmpty()) @@ -1298,43 +1298,6 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal return fontEngine; } -QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const -{ - QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script); - if (!result.isEmpty()) - return result; - - switch (styleHint) { - case QFont::Times: - result << QString::fromLatin1("Times New Roman"); - break; - case QFont::Courier: - result << QString::fromLatin1("Courier New"); - break; - case QFont::Monospace: - result << QString::fromLatin1("Courier New"); - break; - case QFont::Cursive: - result << QString::fromLatin1("Comic Sans MS"); - break; - case QFont::Fantasy: - result << QString::fromLatin1("Impact"); - break; - case QFont::Decorative: - result << QString::fromLatin1("Old English"); - break; - case QFont::Helvetica: - case QFont::System: - default: - result << QString::fromLatin1("Arial"); - } - - if (QWindowsContext::verboseFonts) - qDebug() << __FUNCTION__ << family << style << styleHint - << script << result << m_families.size(); - return result; -} - static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData) { QList<quint32> offsets; @@ -1686,6 +1649,82 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request) return lf; } +static QStringList extraTryFontsForFamily(const QString& family) +{ + QStringList result; + QFontDatabase db; + if (!db.writingSystems(family).contains(QFontDatabase::Symbol)) { + if (!tryFonts) { + LANGID lid = GetUserDefaultLangID(); + switch (lid&0xff) { + case LANG_CHINESE: // Chinese (Taiwan) + if ( lid == 0x0804 ) // Taiwan + tryFonts = ch_TW_tryFonts; + else + tryFonts = ch_CN_tryFonts; + break; + case LANG_JAPANESE: + tryFonts = jp_tryFonts; + break; + case LANG_KOREAN: + tryFonts = kr_tryFonts; + break; + default: + tryFonts = other_tryFonts; + break; + } + } + QStringList fm = QFontDatabase().families(); + const char **tf = tryFonts; + while (tf && *tf) { + if (fm.contains(QLatin1String(*tf))) + result << QLatin1String(*tf); + ++tf; + } + } + return result; +} + +QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const +{ + QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script); + if (!result.isEmpty()) + return result; + + switch (styleHint) { + case QFont::Times: + result << QString::fromLatin1("Times New Roman"); + break; + case QFont::Courier: + result << QString::fromLatin1("Courier New"); + break; + case QFont::Monospace: + result << QString::fromLatin1("Courier New"); + break; + case QFont::Cursive: + result << QString::fromLatin1("Comic Sans MS"); + break; + case QFont::Fantasy: + result << QString::fromLatin1("Impact"); + break; + case QFont::Decorative: + result << QString::fromLatin1("Old English"); + break; + case QFont::Helvetica: + case QFont::System: + default: + result << QString::fromLatin1("Arial"); + } + + result.append(extraTryFontsForFamily(family)); + + if (QWindowsContext::verboseFonts) + qDebug() << __FUNCTION__ << family << style << styleHint + << script << result << m_families.size(); + return result; +} + + QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &request, HDC fontHdc, int dpi, bool rawMode, const QStringList &family_list, @@ -1849,42 +1888,16 @@ QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &requ #endif if (script == QChar::Script_Common - && !(request.styleStrategy & QFont::NoFontMerging)) { - QFontDatabase db; - if (!db.writingSystems(request.family).contains(QFontDatabase::Symbol)) { - if(!tryFonts) { - LANGID lid = GetUserDefaultLangID(); - switch( lid&0xff ) { - case LANG_CHINESE: // Chinese (Taiwan) - if ( lid == 0x0804 ) // Taiwan - tryFonts = ch_TW_tryFonts; - else - tryFonts = ch_CN_tryFonts; - break; - case LANG_JAPANESE: - tryFonts = jp_tryFonts; - break; - case LANG_KOREAN: - tryFonts = kr_tryFonts; - break; - default: - tryFonts = other_tryFonts; - break; - } - } - QStringList fm = QFontDatabase().families(); - QStringList list = family_list; - const char **tf = tryFonts; - while(tf && *tf) { - if(fm.contains(QLatin1String(*tf))) - list << QLatin1String(*tf); - ++tf; - } - QFontEngine *mfe = new QWindowsMultiFontEngine(fe, list); - mfe->setObjectName(QStringLiteral("QWindowsMultiFontEngine_") + request.family); - mfe->fontDef = fe->fontDef; - fe = mfe; - } + && !(request.styleStrategy & QFont::NoFontMerging)) { + QStringList extraFonts = extraTryFontsForFamily(request.family); + if (extraFonts.size()) { + QStringList list = family_list; + list.append(extraFonts); + QFontEngine *mfe = new QWindowsMultiFontEngine(fe, list); + mfe->setObjectName(QStringLiteral("QWindowsMultiFontEngine_") + request.family); + mfe->fontDef = fe->fontDef; + fe = mfe; + } } return fe; } diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index d30c1f984d..0509a55eaa 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -279,20 +279,20 @@ static bool addFontToDatabase(QString familyName, const QString &scriptName, if (!QDir::isAbsolutePath(value)) value.prepend(QString::fromLocal8Bit(qgetenv("windir") + "\\Fonts\\")); - QPlatformFontDatabase::registerFont(faceName, foundryName, weight, style, stretch, + QPlatformFontDatabase::registerFont(faceName, QString(), foundryName, weight, style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(value, index)); // add fonts windows can generate for us: if (weight <= QFont::DemiBold) - QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, style, stretch, + QPlatformFontDatabase::registerFont(faceName, QString(), foundryName, QFont::Bold, style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(value, index)); if (style != QFont::StyleItalic) - QPlatformFontDatabase::registerFont(faceName, foundryName, weight, QFont::StyleItalic, stretch, + QPlatformFontDatabase::registerFont(faceName, QString(), foundryName, weight, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(value, index)); if (weight <= QFont::DemiBold && style != QFont::StyleItalic) - QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, QFont::StyleItalic, stretch, + QPlatformFontDatabase::registerFont(faceName, QString(), foundryName, QFont::Bold, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(value, index)); if (!englishName.isEmpty()) diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index f7ba0d237d..210405d4ba 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -41,6 +41,11 @@ #ifndef QT_NO_DIRECTWRITE +#if _WIN32_WINNT < 0x0600 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 +#endif + #include "qwindowsfontenginedirectwrite.h" #include "qwindowsfontdatabase.h" #include "qwindowscontext.h" diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1f6253438f..3831c6b10e 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -55,6 +55,7 @@ #include <QtGui/QWindow> #include <QtGui/QRegion> #include <private/qwindow_p.h> +#include <private/qguiapplication_p.h> #include <qpa/qwindowsysteminterface.h> #include <QtCore/QDebug> @@ -321,7 +322,6 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag topLevel = ((creationFlags & ForceChild) || embedded) ? false : w->isTopLevel(); if (topLevel && flags == 1) { - qWarning("Remove me: fixing toplevel window flags"); flags |= Qt::WindowTitleHint|Qt::WindowSystemMenuHint|Qt::WindowMinimizeButtonHint |Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint; } @@ -731,6 +731,9 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, 0); setWindowState(aWindow->windowState()); + const qreal opacity = qt_window_private(aWindow)->opacity; + if (!qFuzzyCompare(opacity, qreal(1.0))) + setOpacity(opacity); } QWindowsWindow::~QWindowsWindow() @@ -1185,8 +1188,21 @@ void QWindowsWindow::setWindowTitle(const QString &title) { if (QWindowsContext::verboseWindows) qDebug() << __FUNCTION__ << this << window() <<title; - if (m_data.hwnd) - SetWindowText(m_data.hwnd, (const wchar_t*)title.utf16()); + if (m_data.hwnd) { + + QString fullTitle = title; + if (QGuiApplicationPrivate::displayName) { + // Append display name, if set. + if (!fullTitle.isEmpty()) + fullTitle += QStringLiteral(" - "); + fullTitle += *QGuiApplicationPrivate::displayName; + } else if (fullTitle.isEmpty()) { + // Don't let the window title be completely empty, use the app name as fallback. + fullTitle = QCoreApplication::applicationName(); + } + + SetWindowText(m_data.hwnd, (const wchar_t*)fullTitle.utf16()); + } } void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags) diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 794bd3aa35..7f73465135 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -1,14 +1,13 @@ -TARGET = windows +TARGET = qwindows PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QWindowsIntegrationPlugin load(qt_plugin) QT *= core-private QT *= gui-private QT *= platformsupport-private -INCLUDEPATH += ../../../3rdparty/harfbuzz/src - # Note: OpenGL32 must precede Gdi32 as it overwrites some functions. LIBS *= -lole32 !wince*:LIBS *= -lgdi32 -luser32 -lwinspool -limm32 -lwinmm -loleaut32 diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 4c4df137a3..1192894693 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -257,6 +257,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char , has_shape_extension(false) , has_randr_extension(false) , has_input_shape(false) + , m_buttons(0) { #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); @@ -312,6 +313,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char initializeAllAtoms(); m_time = XCB_CURRENT_TIME; + m_netWmUserTime = XCB_CURRENT_TIME; initializeXRandr(); updateScreens(); @@ -662,6 +664,73 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error) #endif } +static Qt::MouseButtons translateMouseButtons(int s) +{ + Qt::MouseButtons ret = 0; + if (s & XCB_BUTTON_MASK_1) + ret |= Qt::LeftButton; + if (s & XCB_BUTTON_MASK_2) + ret |= Qt::MidButton; + if (s & XCB_BUTTON_MASK_3) + ret |= Qt::RightButton; + return ret; +} + +static Qt::MouseButton translateMouseButton(xcb_button_t s) +{ + switch (s) { + case 1: return Qt::LeftButton; + case 2: return Qt::MidButton; + case 3: return Qt::RightButton; + // Button values 4-7 were already handled as Wheel events, and won't occur here. + case 8: return Qt::BackButton; // Also known as Qt::ExtraButton1 + case 9: return Qt::ForwardButton; // Also known as Qt::ExtraButton2 + case 10: return Qt::ExtraButton3; + case 11: return Qt::ExtraButton4; + case 12: return Qt::ExtraButton5; + case 13: return Qt::ExtraButton6; + case 14: return Qt::ExtraButton7; + case 15: return Qt::ExtraButton8; + case 16: return Qt::ExtraButton9; + case 17: return Qt::ExtraButton10; + case 18: return Qt::ExtraButton11; + case 19: return Qt::ExtraButton12; + case 20: return Qt::ExtraButton13; + case 21: return Qt::ExtraButton14; + case 22: return Qt::ExtraButton15; + case 23: return Qt::ExtraButton16; + case 24: return Qt::ExtraButton17; + case 25: return Qt::ExtraButton18; + case 26: return Qt::ExtraButton19; + case 27: return Qt::ExtraButton20; + case 28: return Qt::ExtraButton21; + case 29: return Qt::ExtraButton22; + case 30: return Qt::ExtraButton23; + case 31: return Qt::ExtraButton24; + default: return Qt::NoButton; + } +} + +void QXcbConnection::handleButtonPress(xcb_generic_event_t *ev) +{ + xcb_button_press_event_t *event = (xcb_button_press_event_t *)ev; + + // the event explicitly contains the state of the three first buttons, + // the rest we need to manage ourselves + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); + m_buttons |= translateMouseButton(event->detail); +} + +void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev) +{ + xcb_button_release_event_t *event = (xcb_button_release_event_t *)ev; + + // the event explicitly contains the state of the three first buttons, + // the rest we need to manage ourselves + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); + m_buttons &= ~translateMouseButton(event->detail); +} + void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) { #ifdef Q_XCB_DEBUG @@ -686,8 +755,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) case XCB_EXPOSE: HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent); case XCB_BUTTON_PRESS: + handleButtonPress(event); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); case XCB_BUTTON_RELEASE: + handleButtonRelease(event); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); case XCB_MOTION_NOTIFY: HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index c67acb3218..464d918adf 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -370,6 +370,9 @@ public: inline xcb_timestamp_t time() const { return m_time; } inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; } + inline xcb_timestamp_t netWmUserTime() const { return m_netWmUserTime; } + inline void setNetWmUserTime(xcb_timestamp_t t) { if (t > m_netWmUserTime) m_netWmUserTime = t; } + bool hasGLX() const { return has_glx_extension; } bool hasXFixes() const { return xfixes_first_event > 0; } bool hasXShape() const { return has_shape_extension; } @@ -380,6 +383,8 @@ public: xcb_timestamp_t getTimestamp(); + Qt::MouseButtons buttons() const { return m_buttons; } + private slots: void processXcbEvents(); @@ -400,6 +405,8 @@ private: QXcbScreen* findOrCreateScreen(QList<QXcbScreen *>& newScreens, int screenNumber, xcb_screen_t* xcbScreen, xcb_randr_get_output_info_reply_t *output = NULL); void updateScreens(); + void handleButtonPress(xcb_generic_event_t *event); + void handleButtonRelease(xcb_generic_event_t *event); bool m_xi2Enabled; int m_xi2Minor; @@ -448,6 +455,7 @@ private: xcb_atom_t m_allAtoms[QXcbAtom::NAtoms]; xcb_timestamp_t m_time; + xcb_timestamp_t m_netWmUserTime; QByteArray m_displayName; @@ -501,6 +509,8 @@ private: bool has_shape_extension; bool has_randr_extension; bool has_input_shape; + + Qt::MouseButtons m_buttons; }; #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display())) diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index c1cfbd02d6..e1dfe3d6c0 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -291,6 +291,7 @@ QXcbCursor::~QXcbCursor() xcb_close_font(xcb_connection(), cursorFont); } +#ifndef QT_NO_CURSOR void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) { QXcbWindow *w = 0; @@ -507,6 +508,7 @@ xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor) } return c; } +#endif void QXcbCursor::queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask) { diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index 4c74034988..a4f3bf11ee 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -52,20 +52,26 @@ class QXcbCursor : public QXcbObject, public QPlatformCursor public: QXcbCursor(QXcbConnection *conn, QXcbScreen *screen); ~QXcbCursor(); +#ifndef QT_NO_CURSOR void changeCursor(QCursor *cursor, QWindow *widget); +#endif QPoint pos() const; void setPos(const QPoint &pos); static void queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask = 0); private: +#ifndef QT_NO_CURSOR xcb_cursor_t createFontCursor(int cshape); xcb_cursor_t createBitmapCursor(QCursor *cursor); xcb_cursor_t createNonStandardCursor(int cshape); +#endif QXcbScreen *m_screen; +#ifndef QT_NO_CURSOR QMap<int, xcb_cursor_t> m_shapeCursorMap; QMap<qint64, xcb_cursor_t> m_bitmapCursorMap; +#endif }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index a44e7fb959..9c360df900 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -71,6 +71,8 @@ public: insert("screen",QXcbNativeInterface::Screen); insert("eglcontext",QXcbNativeInterface::EglContext); insert("glxcontext",QXcbNativeInterface::GLXContext); + insert("apptime",QXcbNativeInterface::AppTime); + insert("appusertime",QXcbNativeInterface::AppUserTime); } }; @@ -109,18 +111,24 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q const QXcbResourceMap::const_iterator it = qXcbResourceMap()->constFind(resource.toLower()); if (it == qXcbResourceMap()->constEnd() || !screen->handle()) return 0; + void *result = 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; + result = xcbScreen->connection()->xlib_display(); #endif + break; + case AppTime: + result = appTime(xcbScreen); + break; + case AppUserTime: + result = appUserTime(xcbScreen); + break; default: break; } - return 0; + return result; } void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) @@ -151,6 +159,36 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr return result; } +QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::nativeResourceFunctionForScreen(const QByteArray &resource) +{ + const QByteArray lowerCaseResource = resource.toLower(); + if (lowerCaseResource == "setapptime") + return NativeResourceForScreenFunction(setAppTime); + else if (lowerCaseResource == "setappusertime") + return NativeResourceForScreenFunction(setAppUserTime); + return 0; +} + +void *QXcbNativeInterface::appTime(const QXcbScreen *screen) +{ + return reinterpret_cast<void *>(quintptr(screen->connection()->time())); +} + +void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen) +{ + return reinterpret_cast<void *>(quintptr(screen->connection()->netWmUserTime())); +} + +void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time) +{ + static_cast<QXcbScreen *>(screen->handle())->connection()->setTime(time); +} + +void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time) +{ + static_cast<QXcbScreen *>(screen->handle())->connection()->setNetWmUserTime(time); +} + QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface::nativeResourceFunctionForContext(const QByteArray &resource) { QByteArray lowerCaseResource = resource.toLower(); diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index a7e0a207cb..e2e03fce8f 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -43,11 +43,13 @@ #define QXCBNATIVEINTERFACE_H #include <qpa/qplatformnativeinterface.h> +#include <xcb/xcb.h> QT_BEGIN_NAMESPACE class QWidget; class QXcbScreen; +class QXcbConnection; class QXcbNativeInterface : public QPlatformNativeInterface { @@ -59,7 +61,9 @@ public: Screen, GraphicsDevice, EglContext, - GLXContext + GLXContext, + AppTime, + AppUserTime }; QXcbNativeInterface(); @@ -69,6 +73,7 @@ public: void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window); NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource); + NativeResourceForScreenFunction nativeResourceFunctionForScreen(const QByteArray &resource) Q_DECL_OVERRIDE; inline const QByteArray &genericEventFilterType() const { return m_genericEventFilterType; } @@ -77,6 +82,10 @@ public: void *connectionForWindow(QWindow *window); void *screenForWindow(QWindow *window); void *graphicsDeviceForWindow(QWindow *window); + void *appTime(const QXcbScreen *screen); + void *appUserTime(const QXcbScreen *screen); + static void setAppTime(QScreen *screen, xcb_timestamp_t time); + static void setAppUserTime(QScreen *screen, xcb_timestamp_t time); static void *eglContextForContext(QOpenGLContext *context); static void *glxContextForContext(QOpenGLContext *context); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 6452186bbf..fc80662c46 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -50,6 +50,7 @@ #include <QDebug> #include <qpa/qwindowsysteminterface.h> +#include <private/qmath_p.h> QT_BEGIN_NAMESPACE @@ -65,6 +66,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, , m_orientation(Qt::PrimaryOrientation) , m_number(number) , m_refreshRate(60) + , m_forcedDpi(-1) { if (connection->hasXRandr()) xcb_randr_select_input(xcb_connection(), screen()->root, true); @@ -81,6 +83,9 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, if (m_availableGeometry.isEmpty()) m_availableGeometry = QRect(QPoint(), m_virtualSize); + readXResources(); + + #ifdef Q_XCB_DEBUG qDebug(); qDebug("Screen output %s of xcb screen %d:", m_outputName.toUtf8().constData(), m_number); @@ -242,8 +247,11 @@ QImage::Format QXcbScreen::format() const QDpi QXcbScreen::logicalDpi() const { - return QDpi(25.4 * m_virtualSize.width() / m_virtualSizeMillimeters.width(), - 25.4 * m_virtualSize.height() / m_virtualSizeMillimeters.height()); + if (m_forcedDpi > 0) + return QDpi(m_forcedDpi, m_forcedDpi); + + return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(), + Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); } QPlatformCursor *QXcbScreen::cursor() const @@ -315,6 +323,9 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry()); QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry()); QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation); + QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), + Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(), + Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); } void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) @@ -470,4 +481,41 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) return result; } +void QXcbScreen::readXResources() +{ + int offset = 0; + QByteArray resources; + while(1) { + xcb_get_property_reply_t *reply = + xcb_get_property_reply(xcb_connection(), + xcb_get_property_unchecked(xcb_connection(), false, screen()->root, + XCB_ATOM_RESOURCE_MANAGER, + XCB_ATOM_STRING, offset/4, 8192), NULL); + bool more = false; + if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) { + resources += QByteArray((const char *)xcb_get_property_value(reply), xcb_get_property_value_length(reply)); + offset += xcb_get_property_value_length(reply); + more = reply->bytes_after != 0; + } + + if (reply) + free(reply); + + if (!more) + break; + } + + QList<QByteArray> split = resources.split('\n'); + for (int i = 0; i < split.size(); ++i) { + const QByteArray &r = split.at(i); + if (r.startsWith("Xft.dpi:\t")) { + bool ok; + int dpi = r.mid(sizeof("Xft.dpi:")).toInt(&ok); + if (ok) + m_forcedDpi = dpi; + break; + } + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index d9eee464dc..96d30cde8b 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -96,6 +96,7 @@ public: void updateGeometry(xcb_timestamp_t timestamp); void updateRefreshRate(); + void readXResources(); private: xcb_screen_t *m_screen; xcb_randr_crtc_t m_crtc; @@ -114,6 +115,7 @@ private: QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals; QXcbCursor *m_cursor; int m_refreshRate; + int m_forcedDpi; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 5e4e749c83..528c4c6580 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -385,6 +385,10 @@ void QXcbWindow::create() #ifndef QT_NO_DRAGANDDROP connection()->drag()->dndEnable(this, true); #endif + + const qreal opacity = qt_window_private(window())->opacity; + if (!qFuzzyCompare(opacity, qreal(1.0))) + setOpacity(opacity); } QXcbWindow::~QXcbWindow() @@ -1024,6 +1028,7 @@ void QXcbWindow::updateNetWmStateBeforeMap() void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp) { xcb_window_t wid = m_window; + connection()->setNetWmUserTime(timestamp); const bool isSupportedByWM = connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW)); if (m_netWmUserTimeWindow || isSupportedByWM) { @@ -1112,7 +1117,18 @@ void QXcbWindow::setParent(const QPlatformWindow *parent) void QXcbWindow::setWindowTitle(const QString &title) { - QByteArray ba = title.toUtf8(); + QString fullTitle = title; + if (QGuiApplicationPrivate::displayName) { + // Append display name, if set. + if (!fullTitle.isEmpty()) + fullTitle += QString::fromUtf8(" \xe2\x80\x94 "); // unicode character U+2014, EM DASH + fullTitle += *QGuiApplicationPrivate::displayName; + } else if (fullTitle.isEmpty()) { + // Don't let the window title be completely empty, use the app name as fallback. + fullTitle = QCoreApplication::applicationName(); + } + const QByteArray ba = fullTitle.toUtf8(); + Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, @@ -1460,53 +1476,6 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) } } -static Qt::MouseButtons translateMouseButtons(int s) -{ - Qt::MouseButtons ret = 0; - if (s & XCB_BUTTON_MASK_1) - ret |= Qt::LeftButton; - if (s & XCB_BUTTON_MASK_2) - ret |= Qt::MidButton; - if (s & XCB_BUTTON_MASK_3) - ret |= Qt::RightButton; - return ret; -} - -static Qt::MouseButton translateMouseButton(xcb_button_t s) -{ - switch (s) { - case 1: return Qt::LeftButton; - case 2: return Qt::MidButton; - case 3: return Qt::RightButton; - // Button values 4-7 were already handled as Wheel events, and won't occur here. - case 8: return Qt::BackButton; // Also known as Qt::ExtraButton1 - case 9: return Qt::ForwardButton; // Also known as Qt::ExtraButton2 - case 10: return Qt::ExtraButton3; - case 11: return Qt::ExtraButton4; - case 12: return Qt::ExtraButton5; - case 13: return Qt::ExtraButton6; - case 14: return Qt::ExtraButton7; - case 15: return Qt::ExtraButton8; - case 16: return Qt::ExtraButton9; - case 17: return Qt::ExtraButton10; - case 18: return Qt::ExtraButton11; - case 19: return Qt::ExtraButton12; - case 20: return Qt::ExtraButton13; - case 21: return Qt::ExtraButton14; - case 22: return Qt::ExtraButton15; - case 23: return Qt::ExtraButton16; - case 24: return Qt::ExtraButton17; - case 25: return Qt::ExtraButton18; - case 26: return Qt::ExtraButton19; - case 27: return Qt::ExtraButton20; - case 28: return Qt::ExtraButton21; - case 29: return Qt::ExtraButton22; - case 30: return Qt::ExtraButton23; - case 31: return Qt::ExtraButton24; - default: return Qt::NoButton; - } -} - void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) { updateNetWmUserTime(event->time); @@ -1528,7 +1497,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) return; } - handleMouseEvent(event->detail, event->state, event->time, local, global, modifiers); + handleMouseEvent(event->time, local, global, modifiers); } void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event) @@ -1537,7 +1506,12 @@ void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *even QPoint global(event->root_x, event->root_y); Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); - handleMouseEvent(event->detail, event->state, event->time, local, global, modifiers); + if (event->detail >= 4 && event->detail <= 7) { + // mouse wheel, handled in handleButtonPressEvent() + return; + } + + handleMouseEvent(event->time, local, global, modifiers); } void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) @@ -1546,19 +1520,13 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) QPoint global(event->root_x, event->root_y); Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); - handleMouseEvent(event->detail, event->state, event->time, local, global, modifiers); + handleMouseEvent(event->time, local, global, modifiers); } -void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) +void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) { connection()->setTime(time); - - Qt::MouseButtons buttons = translateMouseButtons(state); - Qt::MouseButton button = translateMouseButton(detail); - - buttons ^= button; // X event uses state *before*, Qt uses state *after* - - QWindowSystemInterface::handleMouseEvent(window(), time, local, global, buttons, modifiers); + QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers); } class EnterEventChecker @@ -1786,6 +1754,23 @@ static inline xcb_rectangle_t qRectToXCBRectangle(const QRect &r) return result; } +void QXcbWindow::setOpacity(qreal level) +{ + if (!m_window) + return; + + quint32 value = qRound64(qBound(qreal(0), level, qreal(1)) * 0xffffffff); + + Q_XCB_CALL(xcb_change_property(xcb_connection(), + XCB_PROP_MODE_REPLACE, + m_window, + atom(QXcbAtom::_NET_WM_WINDOW_OPACITY), + XCB_ATOM_CARDINAL, + 32, + 1, + (uchar *)&value)); +} + void QXcbWindow::setMask(const QRegion ®ion) { if (!connection()->hasXShape()) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index bd4d18a175..b2c637281d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -109,6 +109,8 @@ public: bool startSystemResize(const QPoint &pos, Qt::Corner corner); + void setOpacity(qreal level); + #if !defined(QT_NO_SHAPE) void setMask(const QRegion ®ion); #endif // !QT_NO_SHAPE @@ -132,11 +134,10 @@ public: void handleFocusOutEvent(const xcb_focus_out_event_t *event); void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event); - void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers); + void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers); void updateSyncRequestCounter(); void updateNetWmUserTime(xcb_timestamp_t timestamp); - void netWmUserTime() const; #if defined(XCB_USE_EGL) QXcbEGLSurface *eglSurface() const; diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro index b7b5650eea..5823e97f36 100644 --- a/src/plugins/platforms/xcb/xcb-plugin.pro +++ b/src/plugins/platforms/xcb/xcb-plugin.pro @@ -1,6 +1,7 @@ -TARGET = xcb +TARGET = qxcb PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QXcbIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private @@ -109,7 +110,7 @@ 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 + LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-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 index d7530fe42e..01667d41db 100644 --- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro +++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro @@ -8,7 +8,7 @@ CONFIG += staticlib XCB_DIR = ../../../../3rdparty/xcb -INCLUDEPATH += $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude +INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude # ignore compiler warnings in 3rdparty code QMAKE_CFLAGS_STATIC_LIB+=-w diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index b056fa4002..3b0ff3f6c8 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs SUBDIRS *= sqldrivers bearer -!contains(QT_CONFIG, no-gui): SUBDIRS *= imageformats platforms platforminputcontexts generic -!contains(QT_CONFIG, no-widgets): SUBDIRS += accessible +qtHaveModule(gui): SUBDIRS *= imageformats platforms platforminputcontexts generic +qtHaveModule(widgets): SUBDIRS += accessible -!wince*:!contains(QT_CONFIG, no-widgets):SUBDIRS += printsupport +!wince*:qtHaveModule(widgets): SUBDIRS += printsupport diff --git a/src/plugins/printsupport/cocoa/cocoa.pro b/src/plugins/printsupport/cocoa/cocoa.pro index c0206fd2bc..a3b9e2dfcf 100644 --- a/src/plugins/printsupport/cocoa/cocoa.pro +++ b/src/plugins/printsupport/cocoa/cocoa.pro @@ -1,6 +1,7 @@ TARGET = cocoaprintersupport MODULE = cocoaprintersupport PLUGIN_TYPE = printsupport +PLUGIN_CLASS_NAME = QCocoaPrinterSupportPlugin load(qt_plugin) QT += gui-private printsupport-private diff --git a/src/plugins/printsupport/cups/cups.pro b/src/plugins/printsupport/cups/cups.pro index 0ea5058c00..f617738a94 100644 --- a/src/plugins/printsupport/cups/cups.pro +++ b/src/plugins/printsupport/cups/cups.pro @@ -1,6 +1,7 @@ TARGET = cupsprintersupport MODULE = cupsprintersupport PLUGIN_TYPE = printsupport +PLUGIN_CLASS_NAME = QCupsPrinterSupportPlugin load(qt_plugin) QT += core-private gui-private printsupport printsupport-private diff --git a/src/plugins/printsupport/windows/windows.pro b/src/plugins/printsupport/windows/windows.pro index 5b5dd86beb..ae9efa342b 100644 --- a/src/plugins/printsupport/windows/windows.pro +++ b/src/plugins/printsupport/windows/windows.pro @@ -1,6 +1,7 @@ TARGET = windowsprintersupport MODULE = windowsprintersupport PLUGIN_TYPE = printsupport +PLUGIN_CLASS_NAME = QWindowsPrinterSupportPlugin load(qt_plugin) QT *= core-private diff --git a/src/plugins/sqldrivers/db2/db2.pro b/src/plugins/sqldrivers/db2/db2.pro index d04e6f191b..2365c5bc0e 100644 --- a/src/plugins/sqldrivers/db2/db2.pro +++ b/src/plugins/sqldrivers/db2/db2.pro @@ -4,4 +4,5 @@ SOURCES = main.cpp OTHER_FILES += db2.json include(../../../sql/drivers/db2/qsql_db2.pri) +PLUGIN_CLASS_NAME = QDB2DriverPlugin include(../qsqldriverbase.pri) diff --git a/src/plugins/sqldrivers/ibase/ibase.pro b/src/plugins/sqldrivers/ibase/ibase.pro index ca2a91aa2e..1f29597a2b 100644 --- a/src/plugins/sqldrivers/ibase/ibase.pro +++ b/src/plugins/sqldrivers/ibase/ibase.pro @@ -4,4 +4,5 @@ SOURCES = main.cpp OTHER_FILES += ibase.json include(../../../sql/drivers/ibase/qsql_ibase.pri) +PLUGIN_CLASS_NAME = QIBaseDriverPlugin include(../qsqldriverbase.pri) diff --git a/src/plugins/sqldrivers/mysql/mysql.pro b/src/plugins/sqldrivers/mysql/mysql.pro index 05d1073701..c917bfca48 100644 --- a/src/plugins/sqldrivers/mysql/mysql.pro +++ b/src/plugins/sqldrivers/mysql/mysql.pro @@ -4,4 +4,5 @@ SOURCES = main.cpp OTHER_FILES += mysql.json include(../../../sql/drivers/mysql/qsql_mysql.pri) +PLUGIN_CLASS_NAME = QMYSQLDriverPlugin include(../qsqldriverbase.pri) diff --git a/src/plugins/sqldrivers/oci/oci.pro b/src/plugins/sqldrivers/oci/oci.pro index 89642f3653..96a0dd9ab6 100644 --- a/src/plugins/sqldrivers/oci/oci.pro +++ b/src/plugins/sqldrivers/oci/oci.pro @@ -4,4 +4,5 @@ SOURCES = main.cpp OTHER_FILES += oci.json include(../../../sql/drivers/oci/qsql_oci.pri) +PLUGIN_CLASS_NAME = QOCIDriverPlugin include(../qsqldriverbase.pri) diff --git a/src/plugins/sqldrivers/odbc/odbc.pro b/src/plugins/sqldrivers/odbc/odbc.pro index 5ebd34fd17..c0020c065f 100644 --- a/src/plugins/sqldrivers/odbc/odbc.pro +++ b/src/plugins/sqldrivers/odbc/odbc.pro @@ -4,4 +4,5 @@ SOURCES = main.cpp OTHER_FILES += odbc.json include(../../../sql/drivers/odbc/qsql_odbc.pri) +PLUGIN_CLASS_NAME = QODBCDriverPlugin include(../qsqldriverbase.pri) diff --git a/src/plugins/sqldrivers/psql/psql.pro b/src/plugins/sqldrivers/psql/psql.pro index cb0d27e171..0fabe0e616 100644 --- a/src/plugins/sqldrivers/psql/psql.pro +++ b/src/plugins/sqldrivers/psql/psql.pro @@ -4,4 +4,5 @@ SOURCES = main.cpp OTHER_FILES += psql.json include(../../../sql/drivers/psql/qsql_psql.pri) +PLUGIN_CLASS_NAME = QPSQLDriverPlugin include(../qsqldriverbase.pri) diff --git a/src/plugins/sqldrivers/sqlite/sqlite.pro b/src/plugins/sqldrivers/sqlite/sqlite.pro index d1f4aa7233..60b30d70c0 100644 --- a/src/plugins/sqldrivers/sqlite/sqlite.pro +++ b/src/plugins/sqldrivers/sqlite/sqlite.pro @@ -6,4 +6,5 @@ include(../../../sql/drivers/sqlite/qsql_sqlite.pri) wince*: DEFINES += HAVE_LOCALTIME_S=0 +PLUGIN_CLASS_NAME = QSQLiteDriverPlugin include(../qsqldriverbase.pri) diff --git a/src/plugins/sqldrivers/sqlite2/sqlite2.pro b/src/plugins/sqldrivers/sqlite2/sqlite2.pro index 1cbd31c3dc..d69afc119f 100644 --- a/src/plugins/sqldrivers/sqlite2/sqlite2.pro +++ b/src/plugins/sqldrivers/sqlite2/sqlite2.pro @@ -4,4 +4,5 @@ SOURCES = smain.cpp OTHER_FILES += sqlite2.json include(../../../sql/drivers/sqlite2/qsql_sqlite2.pri) +PLUGIN_CLASS_NAME = QSQLite2DriverPlugin include(../qsqldriverbase.pri) diff --git a/src/plugins/sqldrivers/tds/tds.pro b/src/plugins/sqldrivers/tds/tds.pro index 9f7c2a193f..88f4b7c451 100644 --- a/src/plugins/sqldrivers/tds/tds.pro +++ b/src/plugins/sqldrivers/tds/tds.pro @@ -4,4 +4,5 @@ SOURCES = main.cpp OTHER_FILES += tds.json include(../../../sql/drivers/tds/qsql_tds.pri) +PLUGIN_CLASS_NAME = QTDSDriverPlugin include(../qsqldriverbase.pri) |