diff options
35 files changed, 560 insertions, 200 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index a171f0894b..2d3a78db01 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -41,11 +41,11 @@ #include <stddef.h> -#define QT_VERSION_STR "5.5.0" +#define QT_VERSION_STR "5.6.0" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x050500 +#define QT_VERSION 0x050600 /* can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) */ diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h index 436bf8dd57..b87dbe4784 100644 --- a/src/corelib/io/qdatastream.h +++ b/src/corelib/io/qdatastream.h @@ -83,10 +83,11 @@ public: Qt_5_3 = Qt_5_2, Qt_5_4 = 16, Qt_5_5 = Qt_5_4, -#if QT_VERSION >= 0x050600 + Qt_5_6 = Qt_5_5, +#if QT_VERSION >= 0x050700 #error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion #endif - Qt_DefaultCompiledVersion = Qt_5_5 + Qt_DefaultCompiledVersion = Qt_5_6 }; enum ByteOrder { diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 694463b9d8..2290a74c31 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -204,6 +204,15 @@ static jfieldID getCachedFieldID(JNIEnv *env, } } +void QJNILocalRefDeleter::cleanup(jobject obj) +{ + if (obj == 0) + return; + + QJNIEnvironmentPrivate env; + env->DeleteLocalRef(obj); +} + class QJNIEnvironmentPrivateTLS { public: @@ -2258,4 +2267,3 @@ bool QJNIObjectPrivate::isSameObject(const QJNIObjectPrivate &other) const } QT_END_NAMESPACE - diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h index e79caed5b8..ae9c7c3a7e 100644 --- a/src/corelib/kernel/qjni_p.h +++ b/src/corelib/kernel/qjni_p.h @@ -51,6 +51,14 @@ QT_BEGIN_NAMESPACE +struct Q_CORE_EXPORT QJNILocalRefDeleter +{ + static void cleanup(jobject obj); +}; + +// To simplify this we only define it for jobjects. +typedef QScopedPointer<_jobject, QJNILocalRefDeleter> QJNIScopedLocalRef; + class Q_CORE_EXPORT QJNIEnvironmentPrivate { public: diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index 8ed9199c60..2800656c13 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -273,6 +273,13 @@ bool QPluginLoader::isLoaded() const #if defined(QT_SHARED) static QString locatePlugin(const QString& fileName) { + const bool isAbsolute = QDir::isAbsolutePath(fileName); + if (isAbsolute) { + QFileInfo fi(fileName); + if (fi.isFile()) { + return fi.canonicalFilePath(); + } + } QStringList prefixes = QLibraryPrivate::prefixes_sys(); prefixes.prepend(QString()); QStringList suffixes = QLibraryPrivate::suffixes_sys(QString()); @@ -281,12 +288,18 @@ static QString locatePlugin(const QString& fileName) // Split up "subdir/filename" const int slash = fileName.lastIndexOf('/'); const QString baseName = fileName.mid(slash + 1); - const QString basePath = fileName.left(slash + 1); // keep the '/' + const QString basePath = isAbsolute ? QString() : fileName.left(slash + 1); // keep the '/' const bool debug = qt_debug_component(); - QStringList paths = QCoreApplication::libraryPaths(); - paths.prepend(QStringLiteral("./")); // search in current dir first + QStringList paths; + if (isAbsolute) { + paths.append(fileName.left(slash)); // don't include the '/' + } else { + paths = QCoreApplication::libraryPaths(); + paths.prepend(QStringLiteral(".")); // search in current dir first + } + foreach (const QString &path, paths) { foreach (const QString &prefix, prefixes) { foreach (const QString &suffix, suffixes) { @@ -337,12 +350,7 @@ void QPluginLoader::setFileName(const QString &fileName) did_load = false; } - QFileInfo fi(fileName); - QString fn; - if (fi.isAbsolute()) - fn = fi.canonicalFilePath(); - else - fn = locatePlugin(fileName); + const QString fn = locatePlugin(fileName); d = QLibraryPrivate::findOrCreate(fn, QString(), lh); if (!fn.isEmpty()) diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp index 7f898f68a8..51723f4a57 100644 --- a/src/corelib/tools/qcommandlineoption.cpp +++ b/src/corelib/tools/qcommandlineoption.cpp @@ -42,6 +42,7 @@ class QCommandLineOptionPrivate : public QSharedData { public: inline QCommandLineOptionPrivate() + : hidden(false) { } void setNames(const QStringList &nameList); @@ -58,6 +59,9 @@ public: //! The list of default values used for this option. QStringList defaultValues; + + //! Show or hide in --help + bool hidden; }; /*! @@ -362,4 +366,30 @@ QStringList QCommandLineOption::defaultValues() const return d->defaultValues; } +/*! + Sets whether to hide this option in the user-visible help output. + + All options are visible by default. Setting \a hidden to true for + a particular option makes it internal, i.e. not listed in the help output. + + \since 5.6 + \sa isHidden + */ +void QCommandLineOption::setHidden(bool hide) +{ + d->hidden = hide; +} + +/*! + Returns true if this option is omitted from the help output, + false if the option is listed. + + \since 5.6 + \sa setHidden() + */ +bool QCommandLineOption::isHidden() const +{ + return d->hidden; +} + QT_END_NAMESPACE diff --git a/src/corelib/tools/qcommandlineoption.h b/src/corelib/tools/qcommandlineoption.h index cf4160ecd2..85fc5ca6dd 100644 --- a/src/corelib/tools/qcommandlineoption.h +++ b/src/corelib/tools/qcommandlineoption.h @@ -77,6 +77,9 @@ public: void setDefaultValues(const QStringList &defaultValues); QStringList defaultValues() const; + void setHidden(bool hidden); + bool isHidden() const; + private: QSharedDataPointer<QCommandLineOptionPrivate> d; }; diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index 21bc14a272..c1e40bf5cd 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -1062,6 +1062,8 @@ QString QCommandLineParserPrivate::helpText() const ++longestOptionNameString; for (int i = 0; i < commandLineOptionList.count(); ++i) { const QCommandLineOption &option = commandLineOptionList.at(i); + if (option.isHidden()) + continue; text += wrapText(optionNameList.at(i), longestOptionNameString, option.description()); } if (!positionalArgumentDefinitions.isEmpty()) { diff --git a/src/platformheaders/xcbfunctions/qxcbfunctionshelper.h b/src/platformheaders/xcbfunctions/qxcbfunctionshelper.h new file mode 100644 index 0000000000..a9d734a387 --- /dev/null +++ b/src/platformheaders/xcbfunctions/qxcbfunctionshelper.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXCBFUNCTIONHELPER_H +#define QXCBFUNCTIONHELPER_H + +#include <QtCore/QByteArray> +#include <QtGui/QGuiApplication> + +QT_BEGIN_NAMESPACE + +namespace QXcbFunctionsHelper +{ + +template<typename ReturnT, typename FunctionT> +ReturnT callPlatformFunction(const QByteArray &functionName) +{ + FunctionT func = reinterpret_cast<FunctionT>(QGuiApplication::platformFunction(functionName)); + return func ? func() : ReturnT(); +} + +template<typename ReturnT, typename FunctionT, typename Arg1> +ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1) +{ + FunctionT func = reinterpret_cast<FunctionT>(QGuiApplication::platformFunction(functionName)); + return func ? func(a1) : ReturnT(); +} + +template<typename ReturnT, typename FunctionT, typename Arg1, typename Arg2> +ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1, Arg2 a2) +{ + FunctionT func = reinterpret_cast<FunctionT>(QGuiApplication::platformFunction(functionName)); + return func ? func(a1, a2) : ReturnT(); +} + +template<typename ReturnT, typename FunctionT, typename Arg1, typename Arg2, typename Arg3> +ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1, Arg2 a2, Arg3 a3) +{ + FunctionT func = reinterpret_cast<FunctionT>(QGuiApplication::platformFunction(functionName)); + return func ? func(a1, a2, a3) : ReturnT(); +} + +template<typename ReturnT, typename FunctionT, typename Arg1, typename Arg2, typename Arg3, typename Arg4> +ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4) +{ + FunctionT func = reinterpret_cast<FunctionT>(QGuiApplication::platformFunction(functionName)); + return func ? func(a1, a2, a3, a4) : ReturnT(); +} + +} + +QT_END_NAMESPACE + +#endif /*QXCBFUNCTIONHELPER_H*/ diff --git a/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h b/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h new file mode 100644 index 0000000000..87e19e6a45 --- /dev/null +++ b/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXCBINTEGRATIONFUNCTIONS_H +#define QXCBINTEGRATIONFUNCTIONS_H + +#include "qxcbfunctionshelper.h" + +QT_BEGIN_NAMESPACE + +class QXcbIntegrationFunctions +{ +public: + typedef bool (*XEmbedSystemTrayVisualHasAlphaChannel)(); + static const QByteArray xEmbedSystemTrayVisualHasAlphaChannelIdentifier() { return QByteArrayLiteral("XcbXEmbedSystemTrayVisualHasAlphaChannel"); } + static bool xEmbedSystemTrayVisualHasAlphaChannel() + { + return QXcbFunctionsHelper::callPlatformFunction<bool, XEmbedSystemTrayVisualHasAlphaChannel>(xEmbedSystemTrayVisualHasAlphaChannelIdentifier()); + } +}; + +QT_END_NAMESPACE + +#endif /*QXCBINTEGRATIONFUNCTIONS_H*/ diff --git a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h index f9008039a1..e07679ddcd 100644 --- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h +++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h @@ -34,8 +34,7 @@ #ifndef QXCBWINDOWFUNCTIONS_H #define QXCBWINDOWFUNCTIONS_H -#include <QtCore/QByteArray> -#include <QtGui/QGuiApplication> +#include "qxcbfunctionshelper.h" QT_BEGIN_NAMESPACE @@ -65,12 +64,30 @@ public: typedef void (*SetWmWindowType)(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowType); static const QByteArray setWmWindowTypeIdentifier() { return QByteArrayLiteral("XcbSetWmWindowType"); } - static void setWmWindowType(QWindow *window, WmWindowType type) { - SetWmWindowType func = reinterpret_cast<SetWmWindowType>(QGuiApplication::platformFunction(setWmWindowTypeIdentifier())); - if (func) - func(window, type); + return QXcbFunctionsHelper::callPlatformFunction<void, SetWmWindowType, QWindow *, WmWindowType>(setWmWindowTypeIdentifier(), window, type); + } + + typedef void (*SetParentRelativeBackPixmap)(const QWindow *window); + static const QByteArray setParentRelativeBackPixmapIdentifier() { return QByteArrayLiteral("XcbSetParentRelativeBackPixmap"); } + static void setParentRelativeBackPixmap(const QWindow *window) + { + return QXcbFunctionsHelper::callPlatformFunction<void, SetParentRelativeBackPixmap, const QWindow *>(setParentRelativeBackPixmapIdentifier(), window); + } + + typedef bool (*RequestSystemTrayWindowDock)(const QWindow *window); + static const QByteArray requestSystemTrayWindowDockIdentifier() { return QByteArrayLiteral("XcbRequestSystemTrayWindowDockIdentifier"); } + static bool requestSystemTrayWindowDock(const QWindow *window) + { + return QXcbFunctionsHelper::callPlatformFunction<bool, RequestSystemTrayWindowDock, const QWindow *>(requestSystemTrayWindowDockIdentifier(), window); + } + + typedef QRect (*SystemTrayWindowGlobalGeometry)(const QWindow *window); + static const QByteArray systemTrayWindowGlobalGeometryIdentifier() { return QByteArrayLiteral("XcbSystemTrayWindowGlobalGeometryIdentifier"); } + static QRect systemTrayWindowGlobalGeometry(const QWindow *window) + { + return QXcbFunctionsHelper::callPlatformFunction<QRect, SystemTrayWindowGlobalGeometry, const QWindow *>(systemTrayWindowGlobalGeometryIdentifier(), window); } }; diff --git a/src/platformheaders/xcbfunctions/xcbfunctions.pri b/src/platformheaders/xcbfunctions/xcbfunctions.pri index 8844913cd1..7f611d80bd 100644 --- a/src/platformheaders/xcbfunctions/xcbfunctions.pri +++ b/src/platformheaders/xcbfunctions/xcbfunctions.pri @@ -1 +1,3 @@ -HEADERS += $$PWD/qxcbwindowfunctions.h +HEADERS += \ + $$PWD/qxcbwindowfunctions.h \ + $$PWD/qxcbintegrationfunctions.h diff --git a/src/platformsupport/fbconvenience/qfbbackingstore.cpp b/src/platformsupport/fbconvenience/qfbbackingstore.cpp index bf9beac894..2800a81507 100644 --- a/src/platformsupport/fbconvenience/qfbbackingstore.cpp +++ b/src/platformsupport/fbconvenience/qfbbackingstore.cpp @@ -46,7 +46,7 @@ QFbBackingStore::QFbBackingStore(QWindow *window) if (window->handle()) (static_cast<QFbWindow *>(window->handle()))->setBackingStore(this); else - (static_cast<QFbScreen *>(window->screen()->handle()))->addBackingStore(this); + (static_cast<QFbScreen *>(window->screen()->handle()))->addPendingBackingStore(this); } QFbBackingStore::~QFbBackingStore() diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index 04aa9f2fae..566f84c9ea 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -74,15 +74,15 @@ bool QFbScreen::event(QEvent *event) void QFbScreen::addWindow(QFbWindow *window) { mWindowStack.prepend(window); - if (!mBackingStores.isEmpty()) { + if (!mPendingBackingStores.isEmpty()) { //check if we have a backing store for this window - for (int i = 0; i < mBackingStores.size(); ++i) { - QFbBackingStore *bs = mBackingStores.at(i); + for (int i = 0; i < mPendingBackingStores.size(); ++i) { + QFbBackingStore *bs = mPendingBackingStores.at(i); // this gets called during QWindow::create() at a point where the // invariant (window->handle()->window() == window) is broken if (bs->window() == window->window()) { window->setBackingStore(bs); - mBackingStores.removeAt(i); + mPendingBackingStores.removeAt(i); break; } } @@ -295,5 +295,14 @@ QRegion QFbScreen::doRedraw() return touchedRegion; } +QFbWindow *QFbScreen::windowForId(WId wid) const +{ + for (int i = 0; i < mWindowStack.count(); ++i) + if (mWindowStack[i]->winId() == wid) + return mWindowStack[i]; + + return 0; +} + QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbscreen_p.h b/src/platformsupport/fbconvenience/qfbscreen_p.h index 7f2db51b00..17b2cab43d 100644 --- a/src/platformsupport/fbconvenience/qfbscreen_p.h +++ b/src/platformsupport/fbconvenience/qfbscreen_p.h @@ -80,7 +80,7 @@ public: virtual void lower(QFbWindow *window); virtual void topWindowChanged(QWindow *) {} - void addBackingStore(QFbBackingStore *bs) {mBackingStores << bs;} + void addPendingBackingStore(QFbBackingStore *bs) { mPendingBackingStores << bs; } void scheduleUpdate(); @@ -89,13 +89,14 @@ public slots: void setPhysicalSize(const QSize &size); void setGeometry(const QRect &rect); -protected slots: +protected: virtual QRegion doRedraw(); -protected: void initializeCompositor(); bool event(QEvent *event); + QFbWindow *windowForId(WId wid) const; + QList<QFbWindow *> mWindowStack; QRegion mRepaintRegion; bool mUpdatePending; @@ -113,7 +114,7 @@ private: QPainter *mCompositePainter; QVector<QPair<QRect, int> > mCachedRects; - QList <QFbBackingStore*> mBackingStores; + QList<QFbBackingStore*> mPendingBackingStores; friend class QFbWindow; bool mIsUpToDate; diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 1c3854182f..5407fa66dc 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -33,6 +33,7 @@ #include "qlinuxfbscreen.h" #include <QtPlatformSupport/private/qfbcursor_p.h> +#include <QtPlatformSupport/private/qfbwindow_p.h> #include <QtCore/QRegularExpression> #include <QtGui/QPainter> @@ -421,5 +422,32 @@ QRegion QLinuxFbScreen::doRedraw() return touched; } +// grabWindow() grabs "from the screen" not from the backingstores. +// In linuxfb's case it will also include the mouse cursor. +QPixmap QLinuxFbScreen::grabWindow(WId wid, int x, int y, int width, int height) const +{ + if (!wid) { + if (width < 0) + width = mFbScreenImage.width() - x; + if (height < 0) + height = mFbScreenImage.height() - y; + return QPixmap::fromImage(mFbScreenImage).copy(x, y, width, height); + } + + QFbWindow *window = windowForId(wid); + if (window) { + const QRect geom = window->geometry(); + if (width < 0) + width = geom.width() - x; + if (height < 0) + height = geom.height() - y; + QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); + rect &= window->geometry(); + return QPixmap::fromImage(mFbScreenImage).copy(rect); + } + + return QPixmap(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h index 0cb9961599..1adce2189b 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h @@ -50,7 +50,8 @@ public: bool initialize(); -public slots: + QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + QRegion doRedraw() Q_DECL_OVERRIDE; private: diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 0caec50c94..2bc9c00a94 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -188,16 +188,18 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share) Window window = 0; // Temporary window used to query OpenGL context if (config) { + const QByteArrayList glxExt = QByteArray(glXQueryExtensionsString(m_display, screen->screenNumber())).split(' '); + // Resolve entry point for glXCreateContextAttribsARB glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; - glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); + if (glxExt.contains("GLX_ARB_create_context")) + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); - QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(m_display, screen->screenNumber())).split(' '); - bool supportsProfiles = glxExt.contains("GLX_ARB_create_context_profile"); + const bool supportsProfiles = glxExt.contains("GLX_ARB_create_context_profile"); // Use glXCreateContextAttribsARB if available // Also, GL ES context creation requires GLX_EXT_create_context_es2_profile - if (glxExt.contains("GLX_ARB_create_context") && glXCreateContextAttribsARB != 0 + if (glXCreateContextAttribsARB != 0 && (m_format.renderableType() != QSurfaceFormat::OpenGLES || (supportsProfiles && glxExt.contains("GLX_EXT_create_context_es2_profile")))) { // Try to create an OpenGL context for each known OpenGL version in descending // order from the requested version. diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 9247da814d..57dcdc8f9c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1811,10 +1811,11 @@ bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *ev, int opCo } #endif // defined(XCB_USE_XINPUT2) -QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() +QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const { if (!m_systemTrayTracker) { - if ( (m_systemTrayTracker = QXcbSystemTrayTracker::create(this)) ) { + QXcbConnection *self = const_cast<QXcbConnection *>(this); + if ((self->m_systemTrayTracker = QXcbSystemTrayTracker::create(self))) { connect(m_systemTrayTracker, SIGNAL(systemTrayWindowChanged(QScreen*)), QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*))); } @@ -1822,6 +1823,22 @@ QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() return m_systemTrayTracker; } +bool QXcbConnection::xEmbedSystemTrayAvailable() +{ + if (!QGuiApplicationPrivate::platformIntegration()) + return false; + QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection(); + return connection->systemTrayTracker(); +} + +bool QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel() +{ + if (!QGuiApplicationPrivate::platformIntegration()) + return false; + QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection(); + return connection->systemTrayTracker() && connection->systemTrayTracker()->visualHasAlphaChannel(); +} + bool QXcbConnection::event(QEvent *e) { if (e->type() == QEvent::User + 1) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index a3c8c0b95e..97c2590708 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -463,7 +463,9 @@ public: QXcbNativeInterface *nativeInterface() const { return m_nativeInterface; } - QXcbSystemTrayTracker *systemTrayTracker(); + QXcbSystemTrayTracker *systemTrayTracker() const; + static bool xEmbedSystemTrayAvailable(); + static bool xEmbedSystemTrayVisualHasAlphaChannel(); #ifdef XCB_USE_XINPUT2 void handleEnterEvent(const xcb_enter_notify_event_t *); @@ -474,6 +476,7 @@ public: bool canGrab() const { return m_canGrabServer; } QXcbGlIntegration *glIntegration() const { return m_glIntegration; } + protected: bool event(QEvent *e) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 0688898cae..6cb238228f 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -47,6 +47,7 @@ #include <QtGui/qscreen.h> #include <QtPlatformHeaders/qxcbwindowfunctions.h> +#include <QtPlatformHeaders/qxcbintegrationfunctions.h> #ifndef QT_NO_DBUS #include "QtPlatformSupport/private/qdbusmenuconnection_p.h" @@ -85,8 +86,7 @@ static int resourceType(const QByteArray &key) QXcbNativeInterface::QXcbNativeInterface() : m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t")), - m_sysTraySelectionAtom(XCB_ATOM_NONE), - m_systrayVisualId(XCB_NONE) + m_sysTraySelectionAtom(XCB_ATOM_NONE) { } @@ -109,22 +109,12 @@ bool QXcbNativeInterface::systemTrayAvailable(const QScreen *screen) const bool QXcbNativeInterface::requestSystemTrayWindowDock(const QWindow *window) { - const QPlatformWindow *platformWindow = window->handle(); - if (!platformWindow) - return false; - QXcbSystemTrayTracker *trayTracker = systemTrayTracker(window->screen()); - if (!trayTracker) - return false; - trayTracker->requestSystemTrayWindowDock(static_cast<const QXcbWindow *>(platformWindow)->xcb_window()); - return true; + return QXcbWindow::requestSystemTrayWindowDockStatic(window); } QRect QXcbNativeInterface::systemTrayWindowGlobalGeometry(const QWindow *window) { - if (const QPlatformWindow *platformWindow = window->handle()) - if (const QXcbSystemTrayTracker *trayTracker = systemTrayTracker(window->screen())) - return trayTracker->systemTrayWindowGlobalGeometry(static_cast<const QXcbWindow *>(platformWindow)->xcb_window()); - return QRect(); + return QXcbWindow::systemTrayWindowGlobalGeometryStatic(window); } xcb_window_t QXcbNativeInterface::locateSystemTray(xcb_connection_t *conn, const QXcbScreen *screen) @@ -155,54 +145,14 @@ xcb_window_t QXcbNativeInterface::locateSystemTray(xcb_connection_t *conn, const return selection_window; } -bool QXcbNativeInterface::systrayVisualHasAlphaChannel() { - const QXcbScreen *screen = static_cast<QXcbScreen *>(QGuiApplication::primaryScreen()->handle()); - - if (m_systrayVisualId == XCB_NONE) { - xcb_connection_t *xcb_conn = screen->xcb_connection(); - xcb_atom_t tray_atom = screen->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL); - - xcb_window_t systray_window = locateSystemTray(xcb_conn, screen); - if (systray_window == XCB_WINDOW_NONE) - return false; - - // Get the xcb property for the _NET_SYSTEM_TRAY_VISUAL atom - xcb_get_property_cookie_t systray_atom_cookie; - xcb_get_property_reply_t *systray_atom_reply; - - systray_atom_cookie = xcb_get_property_unchecked(xcb_conn, false, systray_window, - tray_atom, XCB_ATOM_VISUALID, 0, 1); - systray_atom_reply = xcb_get_property_reply(xcb_conn, systray_atom_cookie, 0); - - if (!systray_atom_reply) - return false; - - if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply) > 0) { - xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply); - m_systrayVisualId = vids[0]; - } - - free(systray_atom_reply); - } - - if (m_systrayVisualId != XCB_NONE) { - quint8 depth = screen->depthOfVisual(m_systrayVisualId); - return depth == 32; - } else { - return false; - } +bool QXcbNativeInterface::systrayVisualHasAlphaChannel() +{ + return QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel(); } -void QXcbNativeInterface::setParentRelativeBackPixmap(const QWindow *qwindow) +void QXcbNativeInterface::setParentRelativeBackPixmap(QWindow *window) { - if (const QPlatformWindow *platformWindow = qwindow->handle()) { - const QXcbWindow *qxwindow = static_cast<const QXcbWindow *>(platformWindow); - xcb_connection_t *xcb_conn = qxwindow->xcb_connection(); - - const quint32 mask = XCB_CW_BACK_PIXMAP; - const quint32 values[] = { XCB_BACK_PIXMAP_PARENT_RELATIVE }; - Q_XCB_CALL(xcb_change_window_attributes(xcb_conn, qxwindow->xcb_window(), mask, values)); - } + QXcbWindow::setParentRelativeBackPixmapStatic(window); } void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString) @@ -378,9 +328,21 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio return func; //case sensitive - if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) { - return QFunctionPointer(QXcbWindow::setWmWindowTypeStatic); - } + if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) + return QFunctionPointer(QXcbWindowFunctions::SetWmWindowType(QXcbWindow::setWmWindowTypeStatic)); + + if (function == QXcbWindowFunctions::setParentRelativeBackPixmapIdentifier()) + return QFunctionPointer(QXcbWindowFunctions::SetParentRelativeBackPixmap(QXcbWindow::setParentRelativeBackPixmapStatic)); + + if (function == QXcbWindowFunctions::requestSystemTrayWindowDockIdentifier()) + return QFunctionPointer(QXcbWindowFunctions::RequestSystemTrayWindowDock(QXcbWindow::requestSystemTrayWindowDockStatic)); + + if (function == QXcbWindowFunctions::systemTrayWindowGlobalGeometryIdentifier()) + return QFunctionPointer(QXcbWindowFunctions::SystemTrayWindowGlobalGeometry(QXcbWindow::systemTrayWindowGlobalGeometryStatic)); + + if (function == QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannelIdentifier()) + return QFunctionPointer(QXcbIntegrationFunctions::XEmbedSystemTrayVisualHasAlphaChannel(QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel)); + return Q_NULLPTR; } diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index 64da388258..b6c207785f 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -104,7 +104,7 @@ public: Q_INVOKABLE void beep(); Q_INVOKABLE bool systemTrayAvailable(const QScreen *screen) const; - Q_INVOKABLE void setParentRelativeBackPixmap(const QWindow *window); + Q_INVOKABLE void setParentRelativeBackPixmap(QWindow *window); Q_INVOKABLE bool systrayVisualHasAlphaChannel(); Q_INVOKABLE bool requestSystemTrayWindowDock(const QWindow *window); Q_INVOKABLE QRect systemTrayWindowGlobalGeometry(const QWindow *window); @@ -120,7 +120,6 @@ private: const QByteArray m_genericEventFilterType; xcb_atom_t m_sysTraySelectionAtom; - xcb_visualid_t m_systrayVisualId; static QXcbScreen *qPlatformScreenForWindow(QWindow *window); diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp index a4fdd70b79..90f298c48d 100644 --- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp +++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp @@ -63,14 +63,14 @@ QXcbSystemTrayTracker *QXcbSystemTrayTracker::create(QXcbConnection *connection) const xcb_atom_t selection = connection->internAtom(netSysTray.constData()); if (!selection) return 0; - return new QXcbSystemTrayTracker(connection, trayAtom, selection, connection); + + return new QXcbSystemTrayTracker(connection, trayAtom, selection); } QXcbSystemTrayTracker::QXcbSystemTrayTracker(QXcbConnection *connection, xcb_atom_t trayAtom, - xcb_atom_t selection, - QObject *parent) - : QObject(parent) + xcb_atom_t selection) + : QObject(connection) , m_selection(selection) , m_trayAtom(trayAtom) , m_connection(connection) @@ -125,6 +125,7 @@ xcb_window_t QXcbSystemTrayTracker::trayWindow() // does not work for the QWindow parented on the tray. QRect QXcbSystemTrayTracker::systemTrayWindowGlobalGeometry(xcb_window_t window) const { + xcb_connection_t *conn = m_connection->xcb_connection(); xcb_get_geometry_reply_t *geomReply = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, window), 0); @@ -161,9 +162,43 @@ void QXcbSystemTrayTracker::handleDestroyNotifyEvent(const xcb_destroy_notify_ev { if (event->window == m_trayWindow) { m_connection->removeWindowEventListener(m_trayWindow); - m_trayWindow = 0; + m_trayWindow = XCB_WINDOW_NONE; emitSystemTrayWindowChanged(); } } +bool QXcbSystemTrayTracker::visualHasAlphaChannel() +{ + if (m_trayWindow == XCB_WINDOW_NONE) + return false; + + xcb_atom_t tray_atom = m_connection->atom(QXcbAtom::_NET_SYSTEM_TRAY_VISUAL); + + // Get the xcb property for the _NET_SYSTEM_TRAY_VISUAL atom + xcb_get_property_cookie_t systray_atom_cookie; + xcb_get_property_reply_t *systray_atom_reply; + + systray_atom_cookie = xcb_get_property_unchecked(m_connection->xcb_connection(), false, m_trayWindow, + tray_atom, XCB_ATOM_VISUALID, 0, 1); + systray_atom_reply = xcb_get_property_reply(m_connection->xcb_connection(), systray_atom_cookie, 0); + + if (!systray_atom_reply) + return false; + + xcb_visualid_t systrayVisualId; + if (systray_atom_reply->value_len > 0 && xcb_get_property_value_length(systray_atom_reply) > 0) { + xcb_visualid_t * vids = (uint32_t *)xcb_get_property_value(systray_atom_reply); + systrayVisualId = vids[0]; + } + + free(systray_atom_reply); + + if (systrayVisualId != XCB_NONE) { + quint8 depth = m_connection->primaryScreen()->depthOfVisual(systrayVisualId); + return depth == 32; + } + + return false; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h index 9c20f1729a..b619afb9c4 100644 --- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h +++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h @@ -57,14 +57,14 @@ public: void handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *) Q_DECL_OVERRIDE; + bool visualHasAlphaChannel(); signals: void systemTrayWindowChanged(QScreen *screen); private: explicit QXcbSystemTrayTracker(QXcbConnection *connection, xcb_atom_t trayAtom, - xcb_atom_t selection, - QObject *parent = 0); + xcb_atom_t selection); static xcb_window_t locateTrayWindow(const QXcbConnection *connection, xcb_atom_t selection); void emitSystemTrayWindowChanged(); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index e2b104e3f1..222f6c1170 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -46,6 +46,7 @@ #include "qxcbwmsupport.h" #include "qxcbimage.h" #include "qxcbnativeinterface.h" +#include "qxcbsystemtraytracker.h" #include <qpa/qplatformintegration.h> @@ -1676,6 +1677,48 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types) xcb_flush(xcb_connection()); } +void QXcbWindow::setParentRelativeBackPixmapStatic(QWindow *window) +{ + if (window->handle()) + static_cast<QXcbWindow *>(window->handle())->setParentRelativeBackPixmap(); +} + +void QXcbWindow::setParentRelativeBackPixmap() +{ + const quint32 mask = XCB_CW_BACK_PIXMAP; + const quint32 values[] = { XCB_BACK_PIXMAP_PARENT_RELATIVE }; + Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values)); +} + +bool QXcbWindow::requestSystemTrayWindowDockStatic(const QWindow *window) +{ + if (window->handle()) + return static_cast<QXcbWindow *>(window->handle())->requestSystemTrayWindowDock(); + return false; +} + +bool QXcbWindow::requestSystemTrayWindowDock() const +{ + if (!connection()->systemTrayTracker()) + return false; + connection()->systemTrayTracker()->requestSystemTrayWindowDock(m_window); + return true; +} + +QRect QXcbWindow::systemTrayWindowGlobalGeometryStatic(const QWindow *window) +{ + if (window->handle()) + return static_cast<QXcbWindow *>(window->handle())->systemTrayWindowGlobalGeometry(); + return QRect(); +} + +QRect QXcbWindow::systemTrayWindowGlobalGeometry() const +{ + if (!connection()->systemTrayTracker()) + return QRect(); + return connection()->systemTrayTracker()->systemTrayWindowGlobalGeometry(m_window); +} + class ExposeCompressor { public: diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 8f78be573c..20c7d5a7b2 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -142,6 +142,15 @@ public: QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types); + static void setParentRelativeBackPixmapStatic(QWindow *window); + void setParentRelativeBackPixmap(); + + static bool requestSystemTrayWindowDockStatic(const QWindow *window); + bool requestSystemTrayWindowDock() const; + + static QRect systemTrayWindowGlobalGeometryStatic(const QWindow *window); + QRect systemTrayWindowGlobalGeometry() const; + bool needsSync() const; void postSyncWindowRequest(); diff --git a/src/tools/qdoc/config.cpp b/src/tools/qdoc/config.cpp index 5ab3cb0d7d..e3b2f0325d 100644 --- a/src/tools/qdoc/config.cpp +++ b/src/tools/qdoc/config.cpp @@ -912,8 +912,10 @@ QStringList Config::loadMaster(const QString& fileName) */ void Config::load(Location location, const QString& fileName) { - pushWorkingDir(QFileInfo(fileName).path()); - QDir::setCurrent(QFileInfo(fileName).path()); + QFileInfo fileInfo(fileName); + QString path = fileInfo.canonicalPath(); + pushWorkingDir(path); + QDir::setCurrent(path); QRegExp keySyntax(QLatin1String("\\w+(?:\\.\\w+)*")); #define SKIP_CHAR() \ @@ -935,7 +937,7 @@ void Config::load(Location location, const QString& fileName) if (location.depth() > 16) location.fatal(tr("Too many nested includes")); - QFile fin(fileName); + QFile fin(fileInfo.fileName()); if (!fin.open(QFile::ReadOnly | QFile::Text)) { if (!Config::installDir.isEmpty()) { int prefix = location.filePath().length() - location.fileName().length(); @@ -1030,7 +1032,7 @@ void Config::load(Location location, const QString& fileName) /* Here is the recursive call. */ - load(location, QFileInfo(QFileInfo(fileName).dir(), includeFile).filePath()); + load(location, QFileInfo(QDir(path), includeFile).filePath()); } else { /* diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index 74d706efe1..4a99ec39de 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -227,6 +227,8 @@ static void processQdocconfFile(const QString &fileName) config.setStringList(CONFIG_AUTOLINKERRORS, QStringList(autolinkErrors ? "true" : "false")); config.setStringList(CONFIG_OBSOLETELINKS, QStringList(obsoleteLinks ? "true" : "false")); + prevCurrentDir = QDir::currentPath(); + /* With the default configuration values in place, load the qdoc configuration file. Note that the configuration @@ -236,7 +238,6 @@ static void processQdocconfFile(const QString &fileName) in the file being processed, mainly for error reporting purposes. */ - currentDir = QFileInfo(fileName).path(); Location::initialize(config); config.load(fileName); QString project = config.getString(CONFIG_PROJECT); @@ -248,7 +249,6 @@ static void processQdocconfFile(const QString &fileName) config.setStringList(CONFIG_DEFINES,defs); Location::terminate(); - prevCurrentDir = QDir::currentPath(); currentDir = QFileInfo(fileName).path(); if (!currentDir.isEmpty()) QDir::setCurrent(currentDir); diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp index 7080dd6f8d..f283c0ea34 100644 --- a/src/widgets/accessible/qaccessiblewidgets.cpp +++ b/src/widgets/accessible/qaccessiblewidgets.cpp @@ -776,7 +776,42 @@ QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *end QFont::Style style = charFormat.font().style(); attrs["font-style"] = QString::fromLatin1((style == QFont::StyleItalic) ? "italic" : ((style == QFont::StyleOblique) ? "oblique": "normal")); - attrs["text-underline-style"] = QString::fromLatin1(charFormat.font().underline() ? "solid" : "none"); + QTextCharFormat::UnderlineStyle underlineStyle = charFormat.underlineStyle(); + if (underlineStyle == QTextCharFormat::NoUnderline && charFormat.font().underline()) // underline could still be set in the default font + underlineStyle = QTextCharFormat::SingleUnderline; + QString underlineStyleValue; + switch (underlineStyle) { + case QTextCharFormat::NoUnderline: + break; + case QTextCharFormat::SingleUnderline: + underlineStyleValue = QStringLiteral("solid"); + break; + case QTextCharFormat::DashUnderline: + underlineStyleValue = QStringLiteral("dash"); + break; + case QTextCharFormat::DotLine: + underlineStyleValue = QStringLiteral("dash"); + break; + case QTextCharFormat::DashDotLine: + underlineStyleValue = QStringLiteral("dot-dash"); + break; + case QTextCharFormat::DashDotDotLine: + underlineStyleValue = QStringLiteral("dot-dot-dash"); + break; + case QTextCharFormat::WaveUnderline: + underlineStyleValue = QStringLiteral("wave"); + break; + case QTextCharFormat::SpellCheckUnderline: + underlineStyleValue = QStringLiteral("wave"); // this is not correct, but provides good approximation at least + break; + default: + qWarning() << "Unknown QTextCharFormat::​UnderlineStyle value " << underlineStyle << " could not be translated to IAccessible2 value"; + break; + } + if (!underlineStyleValue.isNull()) { + attrs["text-underline-style"] = underlineStyleValue; + attrs["text-underline-type"] = QStringLiteral("single"); // if underlineStyleValue is set, there is an underline, and Qt does not support other than single ones + } // else both are "none" which is the default - no need to set them QTextCharFormat::VerticalAlignment alignment = charFormat.verticalAlignment(); attrs["text-position"] = QString::fromLatin1((alignment == QTextCharFormat::AlignSubScript) ? "sub" : ((alignment == QTextCharFormat::AlignSuperScript) ? "super" : "baseline" )); diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp index 2b153d53d9..2752c56c65 100644 --- a/src/widgets/util/qsystemtrayicon_x11.cpp +++ b/src/widgets/util/qsystemtrayicon_x11.cpp @@ -52,6 +52,8 @@ #include <private/qguiapplication_p.h> #include <qdebug.h> +#include <QtPlatformHeaders/qxcbwindowfunctions.h> +#include <QtPlatformHeaders/qxcbintegrationfunctions.h> #ifndef QT_NO_SYSTEMTRAYICON QT_BEGIN_NAMESPACE @@ -112,17 +114,11 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn) // window to ParentRelative (so that it inherits the background of its X11 parent window), call // xcb_clear_region before painting (so that the inherited background is visible) and then grab // the just-drawn background from the X11 server. - bool hasAlphaChannel = false; - QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), - "systrayVisualHasAlphaChannel", Qt::DirectConnection, - Q_RETURN_ARG(bool, hasAlphaChannel)); + bool hasAlphaChannel = QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannel(); setAttribute(Qt::WA_TranslucentBackground, hasAlphaChannel); if (!hasAlphaChannel) { createWinId(); - QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), - "setParentRelativeBackPixmap", Qt::DirectConnection, - Q_ARG(const QWindow *, windowHandle()) - ); + QXcbWindowFunctions::setParentRelativeBackPixmap(windowHandle()); // XXX: This is actually required, but breaks things ("QWidget::paintEngine: Should no // longer be called"). Why is this needed? When the widget is drawn, we use tricks to grab @@ -143,15 +139,9 @@ bool QSystemTrayIconSys::addToTray() createWinId(); setMouseTracking(true); - bool requestResult = false; - if (!QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), - "requestSystemTrayWindowDock", Qt::DirectConnection, - Q_RETURN_ARG(bool, requestResult), - Q_ARG(const QWindow *, windowHandle())) - || !requestResult) { - qWarning("requestSystemTrayWindowDock failed."); + if (!QXcbWindowFunctions::requestSystemTrayWindowDock(windowHandle())) return false; - } + if (!background.isNull()) background = QPixmap(); show(); @@ -171,15 +161,7 @@ void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *) QRect QSystemTrayIconSys::globalGeometry() const { - QRect result; - if (!QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), - "systemTrayWindowGlobalGeometry", Qt::DirectConnection, - Q_RETURN_ARG(QRect, result), - Q_ARG(const QWindow *, windowHandle())) - || !result.isValid()) { - qWarning("systemTrayWindowGlobalGeometry failed."); - } - return result; + return QXcbWindowFunctions::systemTrayWindowGlobalGeometry(windowHandle()); } void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev) diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp index bdbb291d7f..cd77b188cc 100644 --- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp @@ -120,6 +120,7 @@ private slots: void loadGarbage(); #endif void relativePath(); + void absolutePath(); void reloadPlugin(); void preloadedPlugin_data(); void preloadedPlugin(); @@ -406,6 +407,20 @@ void tst_QPluginLoader::relativePath() QVERIFY(loader.unload()); } +void tst_QPluginLoader::absolutePath() +{ + // Windows binaries run from release and debug subdirs, so we can't rely on the current dir. + const QString binDir = QFINDTESTDATA("bin"); + QVERIFY(!binDir.isEmpty()); + QVERIFY(QDir::isAbsolutePath(binDir)); + QPluginLoader loader(binDir + "/theplugin"); + loader.load(); // not recommended, instance() should do the job. + PluginInterface *instance = qobject_cast<PluginInterface*>(loader.instance()); + QVERIFY(instance); + QCOMPARE(instance->pluginName(), QLatin1String("Plugin ok")); + QVERIFY(loader.unload()); +} + void tst_QPluginLoader::reloadPlugin() { QPluginLoader loader; diff --git a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp b/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp index 7b1b7ce963..6e09ebb09b 100644 --- a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp +++ b/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.cpp @@ -73,6 +73,12 @@ int main(int argc, char *argv[]) "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz")); parser.addOption(newlineOption); + // A hidden option + QCommandLineOption hiddenOption(QStringList() << QStringLiteral("hidden")); + hiddenOption.setDescription(QStringLiteral("THIS SHOULD NEVER APPEAR")); + hiddenOption.setHidden(true); + parser.addOption(hiddenOption); + // This program supports different options depending on the "command" (first argument). // Call parse() to find out the positional arguments. parser.parse(QCoreApplication::arguments()); diff --git a/tests/auto/network/socket/qabstractsocket/tst_qabstractsocket.cpp b/tests/auto/network/socket/qabstractsocket/tst_qabstractsocket.cpp index 76c36831bd..1c79b6c016 100644 --- a/tests/auto/network/socket/qabstractsocket/tst_qabstractsocket.cpp +++ b/tests/auto/network/socket/qabstractsocket/tst_qabstractsocket.cpp @@ -37,11 +37,6 @@ #include <qcoreapplication.h> #include <qdebug.h> #include <qabstractsocket.h> -#include <qtcpserver.h> -#include <qtcpsocket.h> -#ifndef QT_NO_SSL -#include <qsslsocket.h> -#endif class tst_QAbstractSocket : public QObject { @@ -52,9 +47,7 @@ public: virtual ~tst_QAbstractSocket(); private slots: - void initTestCase(); void getSetCheck(); - void serverDisconnectWithBuffered(); }; tst_QAbstractSocket::tst_QAbstractSocket() @@ -73,11 +66,6 @@ public: void setPeerPort(quint16 port) { QAbstractSocket::setPeerPort(port); } }; -void tst_QAbstractSocket::initTestCase() -{ - qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState"); -} - // Testing get/set functions void tst_QAbstractSocket::getSetCheck() { @@ -106,46 +94,5 @@ void tst_QAbstractSocket::getSetCheck() QCOMPARE(quint16(0xffff), obj1.peerPort()); } -// Test buffered socket being properly closed on remote disconnect -void tst_QAbstractSocket::serverDisconnectWithBuffered() -{ - QTcpServer tcpServer; -#ifndef QT_NO_SSL - QSslSocket testSocket; -#else - QTcpSocket testSocket; -#endif - - QVERIFY(tcpServer.listen(QHostAddress::LocalHost)); - testSocket.connectToHost(tcpServer.serverAddress(), tcpServer.serverPort()); - // Accept connection on server side - QVERIFY(tcpServer.waitForNewConnection(5000)); - QTcpSocket *newConnection = tcpServer.nextPendingConnection(); - // Send one char and drop link - QVERIFY(newConnection != NULL); - QVERIFY(newConnection->putChar(0)); - QVERIFY(newConnection->flush()); - delete newConnection; - - QVERIFY(testSocket.waitForConnected(5000)); // ready for write - QVERIFY(testSocket.state() == QAbstractSocket::ConnectedState); - - QSignalSpy spyStateChanged(&testSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState))); - QSignalSpy spyDisconnected(&testSocket, SIGNAL(disconnected())); - - QVERIFY(testSocket.waitForReadyRead(5000)); // have one char already in internal buffer - char buf[128]; - QCOMPARE(testSocket.read(buf, sizeof(buf)), Q_INT64_C(1)); - if (testSocket.state() != QAbstractSocket::UnconnectedState) { - QVERIFY(testSocket.waitForDisconnected(5000)); - QVERIFY(testSocket.state() == QAbstractSocket::UnconnectedState); - } - // Test signal emitting - QVERIFY(spyDisconnected.count() == 1); - QVERIFY(spyStateChanged.count() > 0); - QVERIFY(qvariant_cast<QAbstractSocket::SocketState>(spyStateChanged.last().first()) - == QAbstractSocket::UnconnectedState); -} - QTEST_MAIN(tst_QAbstractSocket) #include "tst_qabstractsocket.moc" diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 878d5875b5..13d8a21794 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -197,6 +197,7 @@ private slots: void setSocketOption(); void clientSendDataOnDelayedDisconnect(); + void serverDisconnectWithBuffered(); protected slots: void nonBlockingIMAP_hostFound(); @@ -2847,5 +2848,50 @@ void tst_QTcpSocket::clientSendDataOnDelayedDisconnect() delete socket; } +// Test buffered socket being properly closed on remote disconnect +void tst_QTcpSocket::serverDisconnectWithBuffered() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState"); + + QTcpServer tcpServer; + QTcpSocket *socket = newSocket(); + + QVERIFY(tcpServer.listen(QHostAddress::LocalHost)); + socket->connectToHost(tcpServer.serverAddress(), tcpServer.serverPort()); + // Accept connection on server side + QVERIFY(tcpServer.waitForNewConnection(5000)); + QTcpSocket *newConnection = tcpServer.nextPendingConnection(); + // Send one char and drop link + QVERIFY(newConnection != NULL); + QVERIFY(newConnection->putChar(0)); + QVERIFY(newConnection->flush()); + delete newConnection; + + QVERIFY(socket->waitForConnected(5000)); // ready for write + QVERIFY(socket->state() == QAbstractSocket::ConnectedState); + + QSignalSpy spyStateChanged(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState))); + QSignalSpy spyDisconnected(socket, SIGNAL(disconnected())); + + QVERIFY(socket->waitForReadyRead(5000)); // have one char already in internal buffer + char buf[128]; + QCOMPARE(socket->read(buf, sizeof(buf)), Q_INT64_C(1)); + if (socket->state() != QAbstractSocket::UnconnectedState) { + QVERIFY(socket->waitForDisconnected(5000)); + QVERIFY(socket->state() == QAbstractSocket::UnconnectedState); + } + // Test signal emitting + QVERIFY(spyDisconnected.count() == 1); + QVERIFY(spyStateChanged.count() > 0); + QVERIFY(qvariant_cast<QAbstractSocket::SocketState>(spyStateChanged.last().first()) + == QAbstractSocket::UnconnectedState); + + delete socket; +} + QTEST_MAIN(tst_QTcpSocket) #include "tst_qtcpsocket.moc" diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 9937b6f7f8..98cbfa00f3 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -668,7 +668,7 @@ void tst_QAccessibility::textAttributes_data() defaultComplexFont.setStyle(QFont::StyleItalic); defaultComplexFont.setUnderline(true); - static QStringList defaults = QString("font-style:normal;font-weight:normal;text-align:left;text-position:baseline;text-underline-style:none;font-size:13pt").split(';'); + static QStringList defaults = QString("font-style:normal;font-weight:normal;text-align:left;text-position:baseline;font-size:13pt").split(';'); static QStringList bold = defaults; bold[1] = QString::fromLatin1("font-weight:bold"); @@ -683,7 +683,7 @@ void tst_QAccessibility::textAttributes_data() monospace.append(QLatin1String("font-family:\"monospace\"")); static QStringList font8pt = defaults; - font8pt[5] = (QLatin1String("font-size:8pt")); + font8pt[4] = (QLatin1String("font-size:8pt")); static QStringList color = defaults; color << QLatin1String("color:rgb(240,241,242)") << QLatin1String("background-color:rgb(20,240,30)"); @@ -694,8 +694,9 @@ void tst_QAccessibility::textAttributes_data() static QStringList defaultFontDifferent = defaults; defaultFontDifferent[0] = QString::fromLatin1("font-style:italic"); defaultFontDifferent[1] = QString::fromLatin1("font-weight:bold"); - defaultFontDifferent[4] = QString::fromLatin1("text-underline-style:solid"); - defaultFontDifferent[5] = QString::fromLatin1("font-size:20pt"); + defaultFontDifferent[4] = QString::fromLatin1("font-size:20pt"); + defaultFontDifferent.append("text-underline-style:solid"); + defaultFontDifferent.append("text-underline-type:single"); defaultFontDifferent.append("font-family:\"Arial\""); static QStringList defaultFontDifferentBoldItalic = defaultFontDifferent; @@ -703,10 +704,10 @@ void tst_QAccessibility::textAttributes_data() defaultFontDifferentBoldItalic[1] = QString::fromLatin1("font-weight:bold"); static QStringList defaultFontDifferentMonospace = defaultFontDifferent; - defaultFontDifferentMonospace[6] = (QLatin1String("font-family:\"monospace\"")); + defaultFontDifferentMonospace[7] = (QLatin1String("font-family:\"monospace\"")); static QStringList defaultFontDifferentFont8pt = defaultFontDifferent; - defaultFontDifferentFont8pt[5] = (QLatin1String("font-size:8pt")); + defaultFontDifferentFont8pt[4] = (QLatin1String("font-size:8pt")); static QStringList defaultFontDifferentColor = defaultFontDifferent; defaultFontDifferentColor << QLatin1String("color:rgb(240,241,242)") << QLatin1String("background-color:rgb(20,240,30)"); |