From 97a6f28200f7c4c3c7285ac687aee542ae290c28 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 22 May 2015 09:13:21 +0200 Subject: Fixed compilation of auto tests using vc(x)proj files As the defines looked like -DQT_TESTCASE_BUILDDIR=""C:\..."" compilation from Visual Studio (vcxproj) failed due to the two quotation marks at the beginning/end of the actual path. So for the vc(x)proj we do not use shell_quote but add the quotes manually. Change-Id: I186258d82a56928cd0316bff1ec9f60147044165 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/testlib_defines.prf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/testlib_defines.prf b/mkspecs/features/testlib_defines.prf index 9176beb9dd..901e03a91d 100644 --- a/mkspecs/features/testlib_defines.prf +++ b/mkspecs/features/testlib_defines.prf @@ -1 +1,2 @@ -DEFINES += QT_TESTCASE_BUILDDIR=$$shell_quote(\"$$OUT_PWD\") +contains(TEMPLATE, vc.*): DEFINES += QT_TESTCASE_BUILDDIR=\"$$OUT_PWD\" +else: DEFINES += QT_TESTCASE_BUILDDIR=$$shell_quote(\"$$OUT_PWD\") -- cgit v1.2.3 From 7c7c815a1adddfb5a958eefe44724c7395b1a15b Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 20 May 2015 09:29:11 +0200 Subject: MSVC2015: Compile fix Q_DECL_NOTHROW needs to be present at the definition as well in VS2015. Change-Id: I8a6def607aa4ae9c9fe64386a38fc1c728edd8d1 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/network/ssl/qsslellipticcurve_dummy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/ssl/qsslellipticcurve_dummy.cpp b/src/network/ssl/qsslellipticcurve_dummy.cpp index d05c920a49..16b7a3cd00 100644 --- a/src/network/ssl/qsslellipticcurve_dummy.cpp +++ b/src/network/ssl/qsslellipticcurve_dummy.cpp @@ -57,7 +57,7 @@ QSslEllipticCurve QSslEllipticCurve::fromLongName(const QString &name) return QSslEllipticCurve(); } -bool QSslEllipticCurve::isTlsNamedCurve() const +bool QSslEllipticCurve::isTlsNamedCurve() const Q_DECL_NOTHROW { return false; } -- cgit v1.2.3 From 11838622e53537dae61245cb51f100cae9f77b9b Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Wed, 6 May 2015 12:42:28 +0200 Subject: Fix compile error with VS 2015 Change-Id: Ib3b61de27feccb980e5efdf02f0372602d7ffb5a Task-number: QTBUG-45961 Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/windows/accessible/iaccessible2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 99c44c69ef..5ed8d30e67 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -102,7 +102,7 @@ HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitName(/* [retval][out HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitVersion(/* [retval][out] */ BSTR *version) { - *version = ::SysAllocString(QT_UNICODE_LITERAL(QT_VERSION_STR)); + *version = ::SysAllocString(TEXT(QT_VERSION_STR)); return S_OK; } -- cgit v1.2.3 From 6a72afa5f7f362c7053f707b94528e7c01460a19 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 22 May 2015 11:03:19 +0200 Subject: Blacklist tst_qwindow tests that are failing on Ubuntu 14.04 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should allow us to make the rest of 14.04 enforcing Change-Id: I37f6751e8b966b047d1bd2e49ba9482e5846acb1 Reviewed-by: Tony Sarajärvi --- tests/auto/gui/kernel/qwindow/BLACKLIST | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/auto/gui/kernel/qwindow/BLACKLIST diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST new file mode 100644 index 0000000000..ee9709e68b --- /dev/null +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -0,0 +1,6 @@ +[positioning:default] +ubuntu-14.04 +[modalWindowPosition] +ubuntu-14.04 +[modalWithChildWindow] +ubuntu-14.04 -- cgit v1.2.3 From 21b5298d15755258bdedd5ab6c38acbd67c41b5f Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 21 May 2015 12:04:53 +0200 Subject: WinRT: Windows 10 compilation fix Header is required for successful compilation. Change-Id: I401b7c6fbc594b3cd0c9a4b25afc8ff918d8bddd Reviewed-by: Andrew Knight --- src/network/socket/qnativesocketengine_winrt_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 361fcf7ca2..42920c96f2 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -46,6 +46,7 @@ // #include #include +#include #include "QtNetwork/qhostaddress.h" #include "private/qabstractsocketengine_p.h" #include -- cgit v1.2.3 From 79ad3de7bfdb5da56e815993216852a6f3db2809 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 21 May 2015 17:11:26 +0200 Subject: QCoreWlanEngine - null the pointer QCoreWlanEngine is using a global variable but fails to reset it to nil when deleted, thus re-creating this WLAN manager we use a dangling pointer (found in qnetworkconfigurationmanagerqappless). Since our API allows to (re)create object(s) of these class, the pointer must be set to nil after -release call. Ideally, of course, this class has to be re-factored. Change-Id: I08662f55dc6cd2ceb0e0cad2574ee3dee6b8e3fd Reviewed-by: Alex Blasche --- src/plugins/bearer/corewlan/qcorewlanengine.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 9530dd83d0..a30d8f69c4 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -85,8 +85,11 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time return self; } +static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0; + -(void)dealloc { + listener = nil; [super dealloc]; } @@ -117,7 +120,6 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time } @end -static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0; QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 1e2829f5bff1dd50603b9bed48b387a00f208774 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 May 2015 12:06:23 +0200 Subject: remove vestiges of .private_depends amends 16f4bc5b6. Change-Id: I5a9acb2fb57e92a152656be196e55c830031988e Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_functions.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 78be2e8473..a1c499610b 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -185,7 +185,7 @@ defineTest(qtAddRpathLink) { # paths OTOH need to be put there. pubqt = $$replace(1, -private$, _private) pubdep = $$resolve_depends(pubqt, "QT.") - privdep = $$resolve_depends(pubqt, "QT.", ".depends" ".private_depends" ".run_depends") + privdep = $$resolve_depends(pubqt, "QT.", ".depends" ".run_depends") privdep -= $$pubdep rpaths = for(dep, privdep): \ @@ -259,7 +259,7 @@ defineTest(qtAddToolEnv) { # target variable, dependency var name, [non-empty: prepare for system(), not make] defineTest(qtAddTargetEnv) { deps = $$replace($$2, -private$, _private) - deps = $$resolve_depends(deps, "QT.", ".depends" ".private_depends" ".run_depends") + deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends") !isEmpty(deps) { ptypes = for(dep, deps) { -- cgit v1.2.3 From bcf3a3c113321bcfc547894539ed976ad525b7eb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 May 2015 14:03:01 +0200 Subject: fix quoting of qmake parameters in 'qmake' target we need to do full shell quoting, not the limited whitespace quoting. Task-number: QTBUG-46224 Change-Id: I41bc9aee556ca680dce0875b58159a31db962452 Reviewed-by: Joerg Bornemann --- qmake/generators/makefile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 728be67acc..4a03fafd77 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2240,7 +2240,7 @@ QString MakefileGenerator::buildArgs() QString ret; foreach (const QString &arg, Option::globals->qmake_args) - ret += " " + escapeFilePath(arg); + ret += " " + shellQuote(arg); return ret; } -- cgit v1.2.3 From 8e797477b9dae664a7d0009dd635435741bb8852 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 May 2015 21:07:23 +0200 Subject: remove vestiges of -prebind magic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit since commit 22edeb3f4 (private; anno 2002), the generator would extract -prebind and translate it into a PREBINDING property in the pbx file. the writeout to the pbx file got lost in the rewrite for Xcode 3.2 (commit 66f6e5b1; anno 2012). this isn't particularly bad, as prebinding is obsolete since OS X 10.3.4. we now go the last mile and remove the handling of the flag. that means that remaining projects which still use it (meaninglessly) will get a warning from Xcode, which is kinda what we want. QMAKE_LFLAGS should have never been part of the library iteration loop. it was added there in the prebind handling commit, so we can get rid of it again now. Change-Id: Id7dee2b1e248bb2bd7aa7a3e66f82057921afffd Reviewed-by: Tor Arne Vestbø --- qmake/generators/mac/pbuilder_pbx.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index d9eb149177..adf6ca5fb0 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -810,7 +810,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES ProStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"), &frameworkdirs = project->values("QMAKE_FRAMEWORKPATH"); - static const char * const libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; + static const char * const libs[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; for (int i = 0; libs[i]; i++) { tmp = project->values(libs[i]); for(int x = 0; x < tmp.count();) { @@ -821,9 +821,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString r = opt.mid(2).toQString(); fixForOutput(r); libdirs.append(r); - } else if(opt == "-prebind") { - project->values("QMAKE_DO_PREBINDING").append("TRUE"); - remove = true; } else if(opt.startsWith("-l")) { name = opt.mid(2).toQString(); QString lib("lib" + name); -- cgit v1.2.3 From 4476966e0469dfdf372f6b1c119407acef37a6f2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 22 May 2015 11:56:23 +0200 Subject: Direct2D: Fix MSVC2015 warnings. qwindowsdirect2dpaintengine.cpp(365): warning C4838: conversion from 'const qreal' to 'FLOAT' requires a narrowing conversion qwindowsdirect2dpaintengine.cpp(928): warning C4838: conversion from 'const qreal' to 'FLOAT' requires a narrowing conversion qwindowsdirect2dpaintengine.cpp(928): warning C4838: conversion from 'int' to 'UINT32' requires a narrowing conversion qwindowsdirect2dpaintengine.cpp(1398): warning C4838: conversion from 'qreal' to 'FLOAT' requires a narrowing conversion qwindowsdirect2dpaintengine.cpp(1426): warning C4838: conversion from 'double' to 'FLOAT' requires a narrowing conversion qwindowsdirect2dbitmap.cpp(78): warning C4838: conversion from 'int' to 'UINT32' requires a narrowing conversion qwindowsdirect2dwindow.cpp(166): warning C4838: conversion from 'double' to 'BYTE' requires a narrowing conversion Change-Id: I6992260ed2696fa4c47c1c0dd666f448f115879a Reviewed-by: Joerg Bornemann --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 22 +++++++++++----------- .../platforms/direct2d/qwindowsdirect2dwindow.cpp | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index d439196dc1..16c05329de 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -358,10 +358,10 @@ public: } else if (path.isRect() && (q->state()->matrix.type() <= QTransform::TxScale)) { const qreal * const points = path.points(); D2D_RECT_F rect = { - points[0], // left - points[1], // top - points[2], // right, - points[5] // bottom + FLOAT(points[0]), // left + FLOAT(points[1]), // top + FLOAT(points[2]), // right, + FLOAT(points[5]) // bottom }; dc()->PushAxisAlignedClip(rect, antialiasMode()); @@ -918,13 +918,13 @@ public: DWRITE_GLYPH_RUN glyphRun = { fontFace, // IDWriteFontFace *fontFace; - fontDef.pixelSize, // FLOAT fontEmSize; - numGlyphs, // UINT32 glyphCount; + FLOAT(fontDef.pixelSize), // FLOAT fontEmSize; + UINT32(numGlyphs), // UINT32 glyphCount; glyphIndices, // const UINT16 *glyphIndices; glyphAdvances, // const FLOAT *glyphAdvances; glyphOffsets, // const DWRITE_GLYPH_OFFSET *glyphOffsets; FALSE, // BOOL isSideways; - rtl ? 1 : 0 // UINT32 bidiLevel; + rtl ? 1u : 0u // UINT32 bidiLevel; }; const bool antiAlias = bool((q->state()->renderHints & QPainter::TextAntialiasing) @@ -1393,8 +1393,8 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRectF &r) D2D1_ELLIPSE ellipse = { to_d2d_point_2f(p), - r.width() / 2.0, - r.height() / 2.0 + FLOAT(r.width() / 2.0), + FLOAT(r.height() / 2.0) }; if (d->brush.brush) @@ -1421,8 +1421,8 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRect &r) D2D1_ELLIPSE ellipse = { to_d2d_point_2f(p), - r.width() / 2.0, - r.height() / 2.0 + FLOAT(r.width() / 2.0), + FLOAT(r.height() / 2.0) }; if (d->brush.brush) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index e762eab711..ba23526447 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -163,7 +163,7 @@ void QWindowsDirect2DWindow::present(const QRegion ®ion) const SIZE size = { bounds.width(), bounds.height() }; const POINT ptDst = { bounds.x(), bounds.y() }; const POINT ptSrc = { 0, 0 }; - const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255.0 * opacity(), AC_SRC_ALPHA }; + const BLENDFUNCTION blend = { AC_SRC_OVER, 0, BYTE(255.0 * opacity()), AC_SRC_ALPHA }; const QRect r = region.boundingRect(); const RECT dirty = { r.left(), r.top(), r.left() + r.width(), r.top() + r.height() }; UPDATELAYEREDWINDOWINFO info = { sizeof(UPDATELAYEREDWINDOWINFO), NULL, -- cgit v1.2.3 From cab7e7858ae97eedc122fdfa7df082cbdb590d7c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 18 May 2015 10:31:33 +0200 Subject: Make OpenGL legacy examples hellogl and overpainting work with Dynamic GL. Call GL functions using QOpenGLFunctions_1_1. Task-number: QTBUG-46103 Change-Id: I1cbacf9c192c17d96d96aa861bb16e2918a0c053 Reviewed-by: Laszlo Agocs --- examples/opengl/legacy/hellogl/glwidget.cpp | 4 ++- examples/opengl/legacy/hellogl/glwidget.h | 3 +- examples/opengl/legacy/hellogl/hellogl.pro | 2 +- examples/opengl/legacy/overpainting/glwidget.cpp | 4 ++- examples/opengl/legacy/overpainting/glwidget.h | 3 +- .../opengl/legacy/overpainting/overpainting.pro | 2 +- examples/opengl/legacy/shared/qtlogo.cpp | 37 +++++++++++----------- examples/opengl/legacy/shared/qtlogo.h | 3 +- 8 files changed, 33 insertions(+), 25 deletions(-) diff --git a/examples/opengl/legacy/hellogl/glwidget.cpp b/examples/opengl/legacy/hellogl/glwidget.cpp index 02501cd99e..122f7ddfe1 100644 --- a/examples/opengl/legacy/hellogl/glwidget.cpp +++ b/examples/opengl/legacy/hellogl/glwidget.cpp @@ -128,6 +128,8 @@ void GLWidget::setZRotation(int angle) //! [6] void GLWidget::initializeGL() { + initializeOpenGLFunctions(); + qglClearColor(qtPurple.dark()); logo = new QtLogo(this, 64); @@ -153,7 +155,7 @@ void GLWidget::paintGL() glRotatef(xRot / 16.0, 1.0, 0.0, 0.0); glRotatef(yRot / 16.0, 0.0, 1.0, 0.0); glRotatef(zRot / 16.0, 0.0, 0.0, 1.0); - logo->draw(); + logo->draw(static_cast(this)); } //! [7] diff --git a/examples/opengl/legacy/hellogl/glwidget.h b/examples/opengl/legacy/hellogl/glwidget.h index 994e38e13d..9aca4451df 100644 --- a/examples/opengl/legacy/hellogl/glwidget.h +++ b/examples/opengl/legacy/hellogl/glwidget.h @@ -42,11 +42,12 @@ #define GLWIDGET_H #include +#include class QtLogo; //! [0] -class GLWidget : public QGLWidget +class GLWidget : public QGLWidget, public QOpenGLFunctions_1_1 { Q_OBJECT diff --git a/examples/opengl/legacy/hellogl/hellogl.pro b/examples/opengl/legacy/hellogl/hellogl.pro index bb75b07200..c211242fd2 100644 --- a/examples/opengl/legacy/hellogl/hellogl.pro +++ b/examples/opengl/legacy/hellogl/hellogl.pro @@ -14,4 +14,4 @@ QT += opengl widgets target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/hellogl INSTALLS += target -contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") +contains(QT_CONFIG, opengles.|angle):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/overpainting/glwidget.cpp b/examples/opengl/legacy/overpainting/glwidget.cpp index b41bc31126..52b6c35801 100644 --- a/examples/opengl/legacy/overpainting/glwidget.cpp +++ b/examples/opengl/legacy/overpainting/glwidget.cpp @@ -115,6 +115,8 @@ void GLWidget::setZRotation(int angle) //! [2] void GLWidget::initializeGL() { + initializeOpenGLFunctions(); + glEnable(GL_MULTISAMPLE); logo = new QtLogo(this); @@ -173,7 +175,7 @@ void GLWidget::paintEvent(QPaintEvent *event) glRotatef(yRot / 16.0, 0.0, 1.0, 0.0); glRotatef(zRot / 16.0, 0.0, 0.0, 1.0); - logo->draw(); + logo->draw(static_cast(this)); //! [7] //! [8] diff --git a/examples/opengl/legacy/overpainting/glwidget.h b/examples/opengl/legacy/overpainting/glwidget.h index dd5c0ba9ff..7e62a00170 100644 --- a/examples/opengl/legacy/overpainting/glwidget.h +++ b/examples/opengl/legacy/overpainting/glwidget.h @@ -42,13 +42,14 @@ #define GLWIDGET_H #include +#include #include class Bubble; class QtLogo; //! [0] -class GLWidget : public QGLWidget +class GLWidget : public QGLWidget, public QOpenGLFunctions_1_1 { Q_OBJECT diff --git a/examples/opengl/legacy/overpainting/overpainting.pro b/examples/opengl/legacy/overpainting/overpainting.pro index cbed7eed2b..cc46f18889 100644 --- a/examples/opengl/legacy/overpainting/overpainting.pro +++ b/examples/opengl/legacy/overpainting/overpainting.pro @@ -16,4 +16,4 @@ SOURCES = bubble.cpp \ target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/overpainting INSTALLS += target -contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") +contains(QT_CONFIG, opengles.|angle):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/shared/qtlogo.cpp b/examples/opengl/legacy/shared/qtlogo.cpp index efe3fb0201..0d960dd4b6 100644 --- a/examples/opengl/legacy/shared/qtlogo.cpp +++ b/examples/opengl/legacy/shared/qtlogo.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -60,7 +61,7 @@ struct Geometry void appendSmooth(const QVector3D &a, const QVector3D &n, int from); void appendFaceted(const QVector3D &a, const QVector3D &n); void finalize(); - void loadArrays() const; + void loadArrays(QOpenGLFunctions_1_1 *functions) const; }; //! [0] @@ -73,7 +74,7 @@ public: void setSmoothing(Smoothing s) { sm = s; } void translate(const QVector3D &t); void rotate(qreal deg, QVector3D axis); - void draw() const; + void draw(QOpenGLFunctions_1_1 *functions) const; void addTri(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &n); void addQuad(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &d); @@ -96,10 +97,10 @@ static inline void qSetColor(float colorVec[], QColor c) colorVec[3] = c.alphaF(); } -void Geometry::loadArrays() const +void Geometry::loadArrays(QOpenGLFunctions_1_1 *functions) const { - glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); - glNormalPointer(GL_FLOAT, 0, normals.constData()); + functions->glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); + functions->glNormalPointer(GL_FLOAT, 0, normals.constData()); } void Geometry::finalize() @@ -170,15 +171,15 @@ void Patch::translate(const QVector3D &t) } //! [2] -void Patch::draw() const +void Patch::draw(QOpenGLFunctions_1_1 *functions) const { - glPushMatrix(); - glMultMatrixf(mat.constData()); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); + functions->glPushMatrix(); + functions->glMultMatrixf(mat.constData()); + functions->glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); const GLushort *indices = geom->faces.constData(); - glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices + start); - glPopMatrix(); + functions->glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices + start); + functions->glPopMatrix(); } //! [2] @@ -371,17 +372,17 @@ void QtLogo::buildGeometry(int divisions, qreal scale) //! [3] //! [4] -void QtLogo::draw() const +void QtLogo::draw(QOpenGLFunctions_1_1 *functions) const { - geom->loadArrays(); + geom->loadArrays(functions); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); + functions->glEnableClientState(GL_VERTEX_ARRAY); + functions->glEnableClientState(GL_NORMAL_ARRAY); for (int i = 0; i < parts.count(); ++i) - parts[i]->draw(); + parts[i]->draw(functions); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + functions->glDisableClientState(GL_VERTEX_ARRAY); + functions->glDisableClientState(GL_NORMAL_ARRAY); } //! [4] diff --git a/examples/opengl/legacy/shared/qtlogo.h b/examples/opengl/legacy/shared/qtlogo.h index 562435daed..9bd15a1431 100644 --- a/examples/opengl/legacy/shared/qtlogo.h +++ b/examples/opengl/legacy/shared/qtlogo.h @@ -44,6 +44,7 @@ #include #include +class QOpenGLFunctions_1_1; class Patch; struct Geometry; @@ -54,7 +55,7 @@ public: explicit QtLogo(QObject *parent, int d = 64, qreal s = 1.0); ~QtLogo(); void setColor(QColor c); - void draw() const; + void draw(QOpenGLFunctions_1_1 *functions) const; private: void buildGeometry(int d, qreal s); -- cgit v1.2.3 From 06de0da1e8429f8174cfa78b644a09c0c23c478d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 18 May 2015 16:19:48 +0200 Subject: Make warnings of QIODevice more verbose. Include class name, object name and file name when available. For the bug in question: QIODevice::read: device not open becomes QIODevice::read (QTcpSocket, "QFtpDTP Passive state socket"): device not open Adding a static function also makes it easier to set a breakpoint and find the culprit. Task-number: QTBUG-46112 Change-Id: Ic181d8ab292912d1acbcc3cb84d9679fe4842ca0 Reviewed-by: Laszlo Papp Reviewed-by: Alex Trotsenko Reviewed-by: Kai Koehne --- src/corelib/io/qiodevice.cpp | 40 ++++++++++++++++------ tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp | 2 +- tests/auto/corelib/io/qfile/tst_qfile.cpp | 4 +-- tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp | 2 +- .../auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 10 +++--- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index e73a200fb4..872e004d2f 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -38,6 +38,7 @@ #include "qiodevice_p.h" #include "qfile.h" #include "qstringlist.h" +#include "qdir.h" #include #include @@ -80,10 +81,29 @@ void debugBinaryString(const char *data, qint64 maxlen) #define Q_VOID +static void checkWarnMessage(const QIODevice *device, const char *function, const char *what) +{ + QDebug d = qWarning(); + d.noquote(); + d.nospace(); + d << "QIODevice::" << function; +#ifndef QT_NO_QOBJECT + d << " (" << device->metaObject()->className(); + if (!device->objectName().isEmpty()) + d << ", \"" << device->objectName() << '"'; + if (const QFile *f = qobject_cast(device)) + d << ", \"" << QDir::toNativeSeparators(f->fileName()) << '"'; + d << ')'; +#else + Q_UNUSED(device) +#endif // !QT_NO_QOBJECT + d << ": " << what; +} + #define CHECK_MAXLEN(function, returnType) \ do { \ if (maxSize < 0) { \ - qWarning("QIODevice::"#function": Called with maxSize < 0"); \ + checkWarnMessage(this, #function, "Called with maxSize < 0"); \ return returnType; \ } \ } while (0) @@ -92,10 +112,10 @@ void debugBinaryString(const char *data, qint64 maxlen) do { \ if ((d->openMode & WriteOnly) == 0) { \ if (d->openMode == NotOpen) { \ - qWarning("QIODevice::"#function": device not open"); \ + checkWarnMessage(this, #function, "device not open"); \ return returnType; \ } \ - qWarning("QIODevice::"#function": ReadOnly device"); \ + checkWarnMessage(this, #function, "ReadOnly device"); \ return returnType; \ } \ } while (0) @@ -104,10 +124,10 @@ void debugBinaryString(const char *data, qint64 maxlen) do { \ if ((d->openMode & ReadOnly) == 0) { \ if (d->openMode == NotOpen) { \ - qWarning("QIODevice::"#function": device not open"); \ + checkWarnMessage(this, #function, "device not open"); \ return returnType; \ } \ - qWarning("QIODevice::"#function": WriteOnly device"); \ + checkWarnMessage(this, #function, "WriteOnly device"); \ return returnType; \ } \ } while (0) @@ -462,7 +482,7 @@ void QIODevice::setTextModeEnabled(bool enabled) { Q_D(QIODevice); if (!isOpen()) { - qWarning("QIODevice::setTextModeEnabled: The device is not open"); + checkWarnMessage(this, "setTextModeEnabled", "The device is not open"); return; } if (enabled) @@ -621,11 +641,11 @@ bool QIODevice::seek(qint64 pos) { Q_D(QIODevice); if (d->isSequential()) { - qWarning("QIODevice::seek: Cannot call seek on a sequential device"); + checkWarnMessage(this, "seek", "Cannot call seek on a sequential device"); return false; } if (d->openMode == NotOpen) { - qWarning("QIODevice::seek: The device is not open"); + checkWarnMessage(this, "seek", "The device is not open"); return false; } if (pos < 0) { @@ -923,7 +943,7 @@ QByteArray QIODevice::read(qint64 maxSize) #endif if (maxSize != qint64(int(maxSize))) { - qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit"); + checkWarnMessage(this, "read", "maxSize argument exceeds QByteArray size limit"); maxSize = INT_MAX; } @@ -1055,7 +1075,7 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize) { Q_D(QIODevice); if (maxSize < 2) { - qWarning("QIODevice::readLine: Called with maxSize < 2"); + checkWarnMessage(this, "readLine", "Called with maxSize < 2"); return qint64(-1); } diff --git a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp index f792b34d48..3b730d97f9 100644 --- a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp +++ b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp @@ -151,7 +151,7 @@ void tst_QBuffer::readBlock() QCOMPARE(b.bytesAvailable(), (qint64) arraySize); b.open(QIODevice::WriteOnly); QCOMPARE(b.bytesAvailable(), (qint64) arraySize); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::read (QBuffer): WriteOnly device"); QCOMPARE(b.read(a, arraySize), (qint64) -1); // no read access b.close(); diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 98963108be..5025dd38db 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -2334,7 +2334,7 @@ void tst_QFile::readFromWriteOnlyFile() QFile file("writeonlyfile"); QVERIFY(file.open(QFile::WriteOnly)); char c; - QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::read (QFile, \"writeonlyfile\"): WriteOnly device"); QCOMPARE(file.read(&c, 1), qint64(-1)); } @@ -2343,7 +2343,7 @@ void tst_QFile::writeToReadOnlyFile() QFile file("readonlyfile"); QVERIFY(file.open(QFile::ReadOnly)); char c = 0; - QTest::ignoreMessage(QtWarningMsg, "QIODevice::write: ReadOnly device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::write (QFile, \"readonlyfile\"): ReadOnly device"); QCOMPARE(file.write(&c, 1), qint64(-1)); } diff --git a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp index f756588e80..565ca18899 100644 --- a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp +++ b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp @@ -224,7 +224,7 @@ void tst_QIODevice::unget() buf[0] = '@'; buf[1] = '@'; QTest::ignoreMessage(QtWarningMsg, - "QIODevice::readLine: Called with maxSize < 2"); + "QIODevice::readLine (QBuffer): Called with maxSize < 2"); QCOMPARE(buffer.readLine(buf, 1), qint64(-1)); QCOMPARE(buffer.readLine(buf, 2), qint64(i < 4 ? 1 : -1)); switch (i) { diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index f4d3555531..b0a19a6c2d 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -401,8 +401,8 @@ void tst_QSslSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthent void tst_QSslSocket::constructing() { - const char readNotOpenMessage[] = "QIODevice::read: device not open"; - const char writeNotOpenMessage[] = "QIODevice::write: device not open"; + const char readNotOpenMessage[] = "QIODevice::read (QSslSocket): device not open"; + const char writeNotOpenMessage[] = "QIODevice::write (QSslSocket): device not open"; if (!QSslSocket::supportsSsl()) return; @@ -440,13 +440,13 @@ void tst_QSslSocket::constructing() QCOMPARE(socket.read(0, 0), qint64(-1)); QTest::ignoreMessage(QtWarningMsg, readNotOpenMessage); QVERIFY(socket.readAll().isEmpty()); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine: Called with maxSize < 2"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine (QSslSocket): Called with maxSize < 2"); QCOMPARE(socket.readLine(0, 0), qint64(-1)); char buf[10]; QCOMPARE(socket.readLine(buf, sizeof(buf)), qint64(-1)); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: Cannot call seek on a sequential device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek (QSslSocket): Cannot call seek on a sequential device"); QVERIFY(!socket.reset()); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: Cannot call seek on a sequential device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek (QSslSocket): Cannot call seek on a sequential device"); QVERIFY(!socket.seek(2)); QCOMPARE(socket.size(), qint64(0)); QVERIFY(!socket.waitForBytesWritten(10)); -- cgit v1.2.3 From 0c85cdb8c2601981ce313f262f7d6db951bf61ac Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 19 May 2015 15:25:14 +0200 Subject: QFtp: Suppress warning about reading from closed QIODevice. Clear bytesFromSocket when the socket is not open instead of reading in QFtpDTP::socketConnectionClosed(), which is connected to QTcpSocket::disconnected(). Task-number: QTBUG-46112 Change-Id: I0e5e47448f88601eb5c62fe9ba92e1a461323364 Reviewed-by: Timur Pocheptsov --- src/network/access/qftp.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index bb89eece4b..a83d56f31f 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -736,7 +736,10 @@ void QFtpDTP::socketConnectionClosed() clearData(); } - bytesFromSocket = socket->readAll(); + if (socket->isOpen()) + bytesFromSocket = socket->readAll(); + else + bytesFromSocket.clear(); #if defined(QFTPDTP_DEBUG) qDebug("QFtpDTP::connectState(CsClosed)"); #endif -- cgit v1.2.3 From 431e5d9f47515b51dfde582f28ea6bfed5bf82dd Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 14 May 2015 18:45:33 +0300 Subject: fingerpaint example: Use the maximum diameter for the touch spot by default The result doesn't look good when you paint with the MinimumDiameter (3 px). Also don't paint released touch points, because we can't get neither the touch rect not the pressure for them. Change-Id: I8d17c4884ae41545b2cd3f208afa73262133456c Reviewed-by: Laszlo Agocs --- examples/touch/fingerpaint/scribblearea.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/touch/fingerpaint/scribblearea.cpp b/examples/touch/fingerpaint/scribblearea.cpp index 469c6b1a70..05598c134c 100644 --- a/examples/touch/fingerpaint/scribblearea.cpp +++ b/examples/touch/fingerpaint/scribblearea.cpp @@ -187,13 +187,14 @@ bool ScribbleArea::event(QEvent *event) foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) { switch (touchPoint.state()) { case Qt::TouchPointStationary: - // don't do anything if this touch point hasn't moved + case Qt::TouchPointReleased: + // don't do anything if this touch point hasn't moved or has been released continue; default: { QRectF rect = touchPoint.rect(); if (rect.isEmpty()) { - qreal diameter = MinimumDiameter; + qreal diameter = MaximumDiameter; if (touch->device()->capabilities() & QTouchDevice::Pressure) diameter = MinimumDiameter + (MaximumDiameter - MinimumDiameter) * touchPoint.pressure(); rect.setSize(QSizeF(diameter, diameter)); -- cgit v1.2.3 From d0b1c646b4a351f7eea2137c68993ae63b2b6bab Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 15 May 2015 13:12:45 +0300 Subject: xcb: Properly calculate the size of the touch rect ABS_MT_TOUCH_MAJOR is given in surface units rather than in finger units. Also it's not the width of the touch rect but the length of the major axis of the contact. Currently we don't support the orientation of touch rects, so report square rects with side length of ABS_MT_TOUCH_MAJOR. Change-Id: I16c861f30128438ec4a1cae983700f8da4b7b4b7 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index c43816fa05..1848fc14f0 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -43,7 +43,6 @@ #include #include -#define FINGER_MAX_WIDTH_MM 10 struct XInput2TouchDeviceData { XInput2TouchDeviceData() @@ -517,7 +516,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; qreal x = fixed1616ToReal(xiDeviceEvent->root_x); qreal y = fixed1616ToReal(xiDeviceEvent->root_y); - qreal nx = -1.0, ny = -1.0, w = 0.0, h = 0.0; + qreal nx = -1.0, ny = -1.0, d = 0.0; QXcbScreen* screen = m_screens.at(0); for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; @@ -543,13 +542,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { ny = valuatorNormalized(value, vci); } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { - // Convert the value within its range as a fraction of a finger's max (contact patch) - // width in mm, and from there to pixels depending on screen resolution - w = valuatorNormalized(value, vci) * FINGER_MAX_WIDTH_MM * - screen->geometry().width() / screen->physicalSize().width(); - } else if (vci->label == atom(QXcbAtom::AbsMTTouchMinor)) { - h = valuatorNormalized(value, vci) * FINGER_MAX_WIDTH_MM * - screen->geometry().height() / screen->physicalSize().height(); + d = valuatorNormalized(value, vci) * screen->geometry().width(); } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || vci->label == atom(QXcbAtom::AbsPressure)) { touchPoint.pressure = valuatorNormalized(value, vci); @@ -566,10 +559,8 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) ny = y / screen->geometry().height(); } if (xiEvent->evtype != XI_TouchEnd) { - if (w == 0.0) - w = touchPoint.area.width(); - if (h == 0.0) - h = touchPoint.area.height(); + if (d == 0.0) + d = touchPoint.area.width(); } switch (xiEvent->evtype) { @@ -606,7 +597,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) } dev->pointPressedPosition.remove(touchPoint.id); } - touchPoint.area = QRectF(x - w/2, y - h/2, w, h); + touchPoint.area = QRectF(x - d/2, y - d/2, d, d); touchPoint.normalPosition = QPointF(nx, ny); if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) -- cgit v1.2.3 From 75af24a2d121ab56c5b60524bf1d7f2af1613025 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Sat, 23 May 2015 14:04:09 +0200 Subject: QMetaType: Do not automatically register types that derives from a Q_GADGET Otherwise the type is registered with the wrong name Change-Id: I68ec3a05e2528816626e648b46ccc9d70b004866 Reviewed-by: Simon Hausmann --- src/corelib/kernel/qmetatype.h | 12 ++++++++---- src/corelib/kernel/qobjectdefs.h | 1 + tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index b854dc16fd..9ad8702e79 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1357,12 +1357,16 @@ namespace QtPrivate enum { Value = sizeof(checkType(static_cast(0))) == sizeof(yes_type) }; }; + template + struct IsGadgetHelper { enum { Value = false }; }; + template - struct IsGadgetHelper + struct IsGadgetHelper { - template static typename X::QtGadgetHelper *checkType(X*); - static char checkType(void*); - enum { Value = sizeof(checkType(static_cast(0))) == sizeof(void*) }; + template + static char checkType(void (X::*)()); + static void *checkType(void (T::*)()); + enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; }; diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 31e8a670e9..4d01264906 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -172,6 +172,7 @@ private: \ #define Q_GADGET \ public: \ static const QMetaObject staticMetaObject; \ + void qt_check_for_QGADGET_macro(); \ typedef void QtGadgetHelper; \ private: \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index b3333c6d68..691a4e819d 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -144,6 +144,7 @@ class CustomGadget { }; class CustomNonQObject {}; +class GadgetDerived : public CustomGadget {}; void tst_QMetaType::defined() { @@ -153,6 +154,7 @@ void tst_QMetaType::defined() QCOMPARE(int(QMetaTypeId2::Defined), 0); QCOMPARE(int(QMetaTypeId2::Defined), 1); QCOMPARE(int(QMetaTypeId2::Defined), 1); + QVERIFY(!QMetaTypeId2::Defined); QVERIFY(int(QMetaTypeId2::Defined)); QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); -- cgit v1.2.3 From bd1f5b268a1095ec6a4856cef46bc8550a8a8af8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 19 May 2015 11:56:24 -0700 Subject: Make sure we don't call dbus_connection_can_send_type on too old libdbus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function was introduced alongside the support for Unix file descriptors, so it's a good indicator of whether Unix FDs are supported. Ever since dbus_minimal_p.h, however, DBUS_TYPE_UNIX_FD may be defined even if the system libs don't support it. In order to fix this issue, I had to fix what was apparently a merge conflict resolution mistake and remove the #ifdef around the test. Doing the latter is a good idea due to moc being unable to find . This was tested with both linked and dynamically-loaded libdbus-1. Task-number: QTBUG-46199 Change-Id: I66a35ce5f88941f29aa6ffff13dfb4b5438613a3 Reviewed-by: Jani Vähäkangas Reviewed-by: Alex Blasche --- src/dbus/qdbus_symbols_p.h | 3 -- .../auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp | 33 ++++++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index cec8ad62cb..32b76ee5bd 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -183,9 +183,6 @@ DEFINEFUNC(dbus_bool_t , dbus_connection_add_filter, (DBusConnection void *user_data, DBusFreeFunction free_data_function), (connection, function, user_data, free_data_function), return) -DEFINEFUNC(dbus_bool_t , dbus_connection_can_send_type, (DBusConnection *connection, - int type), - (connection, type), return) DEFINEFUNC(void , dbus_connection_close, (DBusConnection *connection), (connection), return) DEFINEFUNC(DBusDispatchStatus , dbus_connection_dispatch, (DBusConnection *connection), diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index 76e740dc5f..16314a5dc5 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -39,10 +39,7 @@ #include #include - -#define QT_LINKED_LIBDBUS -#include -#include +#include static const char serviceName[] = "org.qtproject.autotests.qpong"; static const char objectPath[] = "/org/qtproject/qpong"; @@ -85,10 +82,8 @@ private slots: void sendCallErrors_data(); void sendCallErrors(); -#ifdef DBUS_TYPE_UNIX_FD void receiveUnknownType_data(); void receiveUnknownType(); -#endif void demarshallPrimitives_data(); void demarshallPrimitives(); @@ -1017,7 +1012,6 @@ void tst_QDBusMarshall::sendCallErrors() QCOMPARE(reply.errorMessage(), errorMsg); } -#ifdef DBUS_TYPE_UNIX_FD // If DBUS_TYPE_UNIX_FD is not defined, it means the current system's D-Bus library is too old for this test void tst_QDBusMarshall::receiveUnknownType_data() { @@ -1075,6 +1069,27 @@ public: } }; +// mostly the same as qdbusintegrator.cpp:connectionCapabilies +static bool canSendUnixFd(DBusConnection *connection) +{ + typedef dbus_bool_t (*can_send_type_t)(DBusConnection *, int); + static can_send_type_t can_send_type = 0; + +#if defined(QT_LINKED_LIBDBUS) +# if DBUS_VERSION-0 >= 0x010400 + can_send_type = dbus_connection_can_send_type; +# endif +#else + // run-time check if the next functions are available + can_send_type = (can_send_type_t)qdbus_resolve_conditionally("dbus_connection_can_send_type"); +#endif + +#ifndef DBUS_TYPE_UNIX_FD +# define DBUS_TYPE_UNIX_FD int('h') +#endif + return can_send_type && can_send_type(connection, DBUS_TYPE_UNIX_FD); +} + void tst_QDBusMarshall::receiveUnknownType() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -1088,7 +1103,8 @@ void tst_QDBusMarshall::receiveUnknownType() QVERIFY2(rawcon.data(), error.name); // check if this bus supports passing file descriptors - if (!q_dbus_connection_can_send_type(rawcon.data(), DBUS_TYPE_UNIX_FD)) + + if (!canSendUnixFd(rawcon.data())) QSKIP("Your session bus does not allow sending Unix file descriptors"); // make sure this QDBusConnection won't handle Unix file descriptors @@ -1184,7 +1200,6 @@ void tst_QDBusMarshall::receiveUnknownType() QCOMPARE(spy.list.at(0).arguments().at(0).userType(), receivedTypeId); } } -#endif void tst_QDBusMarshall::demarshallPrimitives_data() { -- cgit v1.2.3 From a0e5210d8b6b21d33800e1fac30efbf2868f9f5b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 Apr 2015 12:34:16 +0200 Subject: Windows: Clean Qt::WindowFullscreenButtonHint in fixTopLevelWindowFlags(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do the correction of top level window flags also in case Qt::Window|Qt::WindowFullscreenButtonHint is passed, since it is not supported by the platform anyways. Task-number: QTBUG-31111 Change-Id: If035d7086e48174873b6b91acf90f730ea40b5a8 Reviewed-by: Morten Johan Sørvig Reviewed-by: J-P Nurmi --- src/plugins/platforms/windows/qwindowswindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 923040fd71..543c08135f 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -438,6 +438,8 @@ QDebug operator<<(QDebug debug, const WindowCreationData &d) // Fix top level window flags in case only the type flags are passed. static inline void fixTopLevelWindowFlags(Qt::WindowFlags &flags) { + // Not supported on Windows, also do correction when it is set. + flags &= ~Qt::WindowFullscreenButtonHint; switch (flags) { case Qt::Window: flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint -- cgit v1.2.3 From 80c8d324b335753d5b1758f29775b844904bb2c6 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 29 Apr 2015 14:36:24 +0200 Subject: take process name into account for QLockFile's pid clash resolution To cover the situation that the process ID got reused, the current process name is compared to the name of the process that corresponds to the process ID from the lock file. If the process names differ, the lock file is considered stale. [ChangeLog][QtCore][QLockFile] Detection of stale lock files got more robust and takes the name of the process that belongs to the stored PID into account. Task-number: QTBUG-45497 Change-Id: Ic3c0d7e066435451203e77b9b9ce2d70bfb9c570 Reviewed-by: Friedemann Kleint Reviewed-by: David Faure --- src/corelib/io/qlockfile.cpp | 12 ++++-- src/corelib/io/qlockfile_p.h | 1 + src/corelib/io/qlockfile_unix.cpp | 48 +++++++++++++++++++++++ src/corelib/io/qlockfile_win.cpp | 45 +++++++++++++++++++++ tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp | 48 +++++++++++++++++++++++ 5 files changed, 150 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index 4f5aeff395..2bd996d213 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -66,9 +67,12 @@ QT_BEGIN_NAMESPACE If the process holding the lock crashes, the lock file stays on disk and can prevent any other process from accessing the shared resource, ever. For this reason, QLockFile - tries to detect such a "stale" lock file, based on the process ID written into the file, - and (in case that process ID got reused meanwhile), on the last modification time of - the lock file (30s by default, for the use case of a short-lived operation). + tries to detect such a "stale" lock file, based on the process ID written into the file. + To cover the situation that the process ID got reused meanwhile, the current process name is + compared to the name of the process that corresponds to the process ID from the lock file. + If the process names differ, the lock file is considered stale. + Additionally, the last modification time of the lock file (30s by default, for the use case of a + short-lived operation) is taken into account. If the lock file is found to be stale, it will be deleted. For the use case of protecting a resource over a long time, you should therefore call @@ -122,7 +126,7 @@ QLockFile::~QLockFile() The value of \a staleLockTime is used by lock() and tryLock() in order to determine when an existing lock file is considered stale, i.e. left over by a crashed process. This is useful for the case where the PID got reused - meanwhile, so the only way to detect a stale lock file is by the fact that + meanwhile, so one way to detect a stale lock file is by the fact that it has been around for a long time. \sa staleLockTime() diff --git a/src/corelib/io/qlockfile_p.h b/src/corelib/io/qlockfile_p.h index 0cfaa42849..168062f467 100644 --- a/src/corelib/io/qlockfile_p.h +++ b/src/corelib/io/qlockfile_p.h @@ -75,6 +75,7 @@ public: // Returns \c true if the lock belongs to dead PID, or is old. // The attempt to delete it will tell us if it was really stale or not, though. bool isApparentlyStale() const; + static QString processNameByPid(qint64 pid); #ifdef Q_OS_UNIX static int checkFcntlWorksAfterFlock(); diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index d1804f2cb6..d6ea2f1f2d 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -48,6 +49,15 @@ #include // kill #include // gethostname +#if defined(Q_OS_OSX) +# include +#elif defined(Q_OS_LINUX) +# include +# include +#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) +# include +#endif + QT_BEGIN_NAMESPACE static QByteArray localHostName() // from QHostInfo::localHostName(), modified to return a QByteArray @@ -189,12 +199,50 @@ bool QLockFilePrivate::isApparentlyStale() const if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { if (::kill(pid, 0) == -1 && errno == ESRCH) return true; // PID doesn't exist anymore + const QString processName = processNameByPid(pid); + if (!processName.isEmpty()) { + QFileInfo fi(appname); + if (fi.isSymLink()) + fi.setFile(fi.symLinkTarget()); + if (processName != fi.fileName()) + return true; // PID got reused by a different application. + } } } const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); return staleLockTime > 0 && age > staleLockTime; } +QString QLockFilePrivate::processNameByPid(qint64 pid) +{ +#if defined(Q_OS_OSX) + char name[1024]; + proc_name(pid, name, sizeof(name) / sizeof(char)); + return QString::fromUtf8(name); +#elif defined(Q_OS_LINUX) + if (!QFile::exists(QStringLiteral("/proc/version"))) + return QString(); + char exePath[64]; + char buf[PATH_MAX]; + memset(buf, 0, sizeof(buf)); + sprintf(exePath, "/proc/%lld/exe", pid); + if (readlink(exePath, buf, sizeof(buf)) < 0) { + // The pid is gone. Return some invalid process name to fail the test. + return QStringLiteral("/ERROR/"); + } + return QFileInfo(QString::fromUtf8(buf)).fileName(); +#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) + kinfo_proc *proc = kinfo_getproc(pid); + if (!proc) + return QString(); + QString name = QString::fromUtf8(proc->ki_comm); + free(proc); + return name; +#else + return QString(); +#endif +} + void QLockFile::unlock() { Q_D(QLockFile); diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index 4e0d8134ec..8cbe0a9dfd 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -140,6 +141,9 @@ bool QLockFilePrivate::isApparentlyStale() const ::CloseHandle(procHandle); if (dwR == WAIT_TIMEOUT) return true; + const QString processName = processNameByPid(pid); + if (!processName.isEmpty() && processName != appname) + return true; // PID got reused by a different application. } } #else // !Q_OS_WINRT @@ -151,6 +155,47 @@ bool QLockFilePrivate::isApparentlyStale() const return staleLockTime > 0 && age > staleLockTime; } +QString QLockFilePrivate::processNameByPid(qint64 pid) +{ +#if !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) + typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD); + + HMODULE hPsapi = LoadLibraryA("psapi"); + if (!hPsapi) + return QString(); + + GetModuleFileNameExFunc qGetModuleFileNameEx + = (GetModuleFileNameExFunc)GetProcAddress(hPsapi, "GetModuleFileNameExW"); + if (!qGetModuleFileNameEx) { + FreeLibrary(hPsapi); + return QString(); + } + + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, DWORD(pid)); + if (!hProcess) { + FreeLibrary(hPsapi); + return QString(); + } + wchar_t buf[MAX_PATH]; + const DWORD length = qGetModuleFileNameEx(hProcess, NULL, buf, sizeof(buf) / sizeof(wchar_t)); + CloseHandle(hProcess); + FreeLibrary(hPsapi); + if (!length) + return QString(); + QString name = QString::fromWCharArray(buf, length); + int i = name.lastIndexOf(QLatin1Char('\\')); + if (i >= 0) + name.remove(0, i + 1); + i = name.lastIndexOf(QLatin1Char('.')); + if (i >= 0) + name.truncate(i); + return name; +#else + Q_UNUSED(pid); + return QString(); +#endif +} + void QLockFile::unlock() { Q_D(QLockFile); diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp index 8d890e81fa..27614e0eb8 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -57,6 +57,7 @@ private slots: void waitForLock(); void staleLockFromCrashedProcess_data(); void staleLockFromCrashedProcess(); + void staleLockFromCrashedProcessReusedPid(); void staleShortLockFromBusyProcess(); void staleLongLockFromBusyProcess(); void staleLockRace(); @@ -64,6 +65,9 @@ private slots: void noPermissionsWindows(); void corruptedLockFile(); +private: + static bool overwritePidInLockFile(const QString &filePath, qint64 pid); + public: QString m_helperApp; QTemporaryDir dir; @@ -277,6 +281,30 @@ void tst_QLockFile::staleLockFromCrashedProcess() #endif // !QT_NO_PROCESS } +void tst_QLockFile::staleLockFromCrashedProcessReusedPid() +{ +#if defined(QT_NO_PROCESS) + QSKIP("This test requires QProcess support"); +#elif defined(Q_OS_WINRT) || defined(Q_OS_WINCE) || defined(Q_OS_IOS) + QSKIP("We cannot retrieve information about other processes on this platform."); +#else + const QString fileName = dir.path() + "/staleLockFromCrashedProcessReusedPid"; + + int ret = QProcess::execute(m_helperApp, QStringList() << fileName << "-crash"); + QCOMPARE(ret, int(QLockFile::NoError)); + QVERIFY(QFile::exists(fileName)); + QVERIFY(overwritePidInLockFile(fileName, QCoreApplication::applicationPid())); + + QLockFile secondLock(fileName); + qint64 pid = 0; + secondLock.getLockInfo(&pid, 0, 0); + QCOMPARE(pid, QCoreApplication::applicationPid()); + secondLock.setStaleLockTime(0); + QVERIFY(secondLock.tryLock()); + QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); +#endif // !QT_NO_PROCESS +} + void tst_QLockFile::staleShortLockFromBusyProcess() { #ifdef QT_NO_PROCESS @@ -497,5 +525,25 @@ void tst_QLockFile::corruptedLockFile() QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); } +bool tst_QLockFile::overwritePidInLockFile(const QString &filePath, qint64 pid) +{ + QFile f(filePath); + if (!f.open(QFile::ReadWrite)) { + qWarning("Cannot open %s.", qPrintable(filePath)); + return false; + } + QByteArray buf = f.readAll(); + int i = buf.indexOf('\n'); + if (i < 0) { + qWarning("Unexpected lockfile content."); + return false; + } + buf.remove(0, i); + buf.prepend(QByteArray::number(pid)); + f.seek(0); + f.resize(buf.size()); + return f.write(buf) == buf.size(); +} + QTEST_MAIN(tst_QLockFile) #include "tst_qlockfile.moc" -- cgit v1.2.3 From 99b08dd9d2a9030fe44c3e634b0baf38c163dcc2 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 17 Apr 2015 02:53:28 -0700 Subject: WinRT: Add qmake support for Windows 10 This allows creation of applications for - x86 - x64 - arm While the arm build theoretically also allows to launch on a mobile, it currently asserts on runtime. Either we will create a new mkspec for Windows 10 Mobile in the future, or do runtime checks for the environment. That also depends on whether there will be a separate SDK by Microsoft. Change-Id: I510bfc88410a5b5a1eb7c37f7f43888d1e5dda0d Reviewed-by: Oswald Buddenhagen Reviewed-by: Oliver Wolff Reviewed-by: Andrew Knight --- .../manifests/10.0/AppxManifest.xml.in | 49 ++++++++++++++++++++++ mkspecs/winrt-arm-msvc2015/qmake.conf | 32 ++++++++++++++ mkspecs/winrt-arm-msvc2015/qplatformdefs.h | 34 +++++++++++++++ mkspecs/winrt-x64-msvc2015/qmake.conf | 32 ++++++++++++++ mkspecs/winrt-x64-msvc2015/qplatformdefs.h | 34 +++++++++++++++ mkspecs/winrt-x86-msvc2015/qmake.conf | 32 ++++++++++++++ mkspecs/winrt-x86-msvc2015/qplatformdefs.h | 34 +++++++++++++++ qmake/generators/win32/msbuild_objectmodel.cpp | 7 +++- qmake/generators/win32/msvc_nmake.cpp | 28 +++++++++++-- qmake/generators/win32/msvc_objectmodel.h | 3 +- qmake/generators/win32/msvc_vcproj.cpp | 11 +++++ 11 files changed, 290 insertions(+), 6 deletions(-) create mode 100644 mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in create mode 100644 mkspecs/winrt-arm-msvc2015/qmake.conf create mode 100644 mkspecs/winrt-arm-msvc2015/qplatformdefs.h create mode 100644 mkspecs/winrt-x64-msvc2015/qmake.conf create mode 100644 mkspecs/winrt-x64-msvc2015/qplatformdefs.h create mode 100644 mkspecs/winrt-x86-msvc2015/qmake.conf create mode 100644 mkspecs/winrt-x86-msvc2015/qplatformdefs.h diff --git a/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in new file mode 100644 index 0000000000..c6419660c1 --- /dev/null +++ b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in @@ -0,0 +1,49 @@ + + + + + + + + + + $${WINRT_MANIFEST.name} + $${WINRT_MANIFEST.publisher} + $${WINRT_MANIFEST.logo_store} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mkspecs/winrt-arm-msvc2015/qmake.conf b/mkspecs/winrt-arm-msvc2015/qmake.conf new file mode 100644 index 0000000000..fcb6d99aa9 --- /dev/null +++ b/mkspecs/winrt-arm-msvc2015/qmake.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for winrt-arm-msvc2015 +# +# Written for Microsoft Visual C++ 2015 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1900 +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP ARM __ARM__ __arm__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:ARM /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib + +# Note that the order is important, ucrt(d) has to be first +# Otherwise the linker might use malloc from a different library +# but free_dbg() from the runtime, causing assert when deleting +# items from different heaps +CONFIG(debug, debug|release) { + QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS +} else { + QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS +} + +VCPROJ_ARCH = ARM +MSVC_VER = 14.0 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = arm diff --git a/mkspecs/winrt-arm-msvc2015/qplatformdefs.h b/mkspecs/winrt-arm-msvc2015/qplatformdefs.h new file mode 100644 index 0000000000..c8f88524d9 --- /dev/null +++ b/mkspecs/winrt-arm-msvc2015/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x64-msvc2015/qmake.conf b/mkspecs/winrt-x64-msvc2015/qmake.conf new file mode 100644 index 0000000000..e8062f5364 --- /dev/null +++ b/mkspecs/winrt-x64-msvc2015/qmake.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for winrt-x64-msvc2015 +# +# Written for Microsoft Visual C++ 2015 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1900 _WIN32 +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X64 __X64__ __x64__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:X64 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib + +# Note that the order is important, ucrt(d) has to be first +# Otherwise the linker might use malloc from a different library +# but free_dbg() from the runtime, causing assert when deleting +# items from different heaps +CONFIG(debug, debug|release) { + QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS +} else { + QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS +} + +VCPROJ_ARCH = x64 +MSVC_VER = 14.0 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x64 diff --git a/mkspecs/winrt-x64-msvc2015/qplatformdefs.h b/mkspecs/winrt-x64-msvc2015/qplatformdefs.h new file mode 100644 index 0000000000..c8f88524d9 --- /dev/null +++ b/mkspecs/winrt-x64-msvc2015/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x86-msvc2015/qmake.conf b/mkspecs/winrt-x86-msvc2015/qmake.conf new file mode 100644 index 0000000000..5b44a97e8d --- /dev/null +++ b/mkspecs/winrt-x86-msvc2015/qmake.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for winrt-x86-msvc2015 +# +# Written for Microsoft Visual C++ 2015 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1900 _WIN32 +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X86 __X86__ __x86__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib + +# Note that the order is important, ucrt(d) has to be first +# Otherwise the linker might use malloc from a different library +# but free_dbg() from the runtime, causing assert when deleting +# items from different heaps +CONFIG(debug, debug|release) { + QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS +} else { + QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS +} + +VCPROJ_ARCH = Win32 +MSVC_VER = 14.0 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x86 diff --git a/mkspecs/winrt-x86-msvc2015/qplatformdefs.h b/mkspecs/winrt-x86-msvc2015/qplatformdefs.h new file mode 100644 index 0000000000..c8f88524d9 --- /dev/null +++ b/mkspecs/winrt-x86-msvc2015/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 6c2d2c6206..cbf7cf26dc 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -608,10 +608,13 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xml.setIndentString(" "); + const QString toolsVersion = (tool.SdkVersion == QStringLiteral("10.0")) ? QStringLiteral("14.0") + : QStringLiteral("4.0"); + xml << decl("1.0", "utf-8") << tag("Project") << attrTag("DefaultTargets","Build") - << attrTag("ToolsVersion", "4.0") + << attrTag("ToolsVersion", toolsVersion) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") << tag("ItemGroup") << attrTag("Label", "ProjectConfigurations"); @@ -640,7 +643,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << tagValue("DefaultLanguage", "en") << tagValue("AppContainerApplication", "true") << tagValue("ApplicationType", isWinPhone ? "Windows Phone" : "Windows Store") - << tagValue("ApplicationTypeRevision", tool.SdkVersion); + << tagValue("ApplicationTypeRevision", tool.SdkVersion == "10.0" ? "8.2" : tool.SdkVersion); } xml << closetag(); diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index eb8ae23384..dfa8f8837b 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -176,11 +176,34 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) const QString vcInstallDir = "/fake/vc_install_dir"; const QString kitDir = "/fake/sdk_install_dir"; #endif // Q_OS_WIN - QStringList incDirs; QStringList libDirs; QStringList binDirs; - if (isPhone) { + if (msvcVer == QStringLiteral("14.0")) { + binDirs << vcInstallDir + QStringLiteral("bin/") + compiler; + binDirs << vcInstallDir + QStringLiteral("bin/"); // Maybe remove for x86 again? + binDirs << kitDir + QStringLiteral("bin/") + (arch == QStringLiteral("arm") ? QStringLiteral("x86") : arch); + binDirs << vcInstallDir + QStringLiteral("../Common7/Tools/bin"); + binDirs << vcInstallDir + QStringLiteral("../Common7/Tools"); + binDirs << vcInstallDir + QStringLiteral("../Common7/ide"); + binDirs << kitDir + QStringLiteral("Windows Performance Toolkit/"); + + incDirs << vcInstallDir + QStringLiteral("include"); + incDirs << vcInstallDir + QStringLiteral("atlmfc/include"); + // ### Investigate why VS uses 10056 first + incDirs << kitDir + QStringLiteral("Include/10.0.10056.0/ucrt"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/ucrt"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/um"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/shared"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/winrt"); + + libDirs << vcInstallDir + QStringLiteral("lib/store/") + compilerArch; + libDirs << vcInstallDir + QStringLiteral("atlmfc/lib") + compilerArch; + // ### Investigate why VS uses 10056 first + libDirs << kitDir + QStringLiteral("lib/10.0.10056.0/ucrt/") + arch; + libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/ucrt/") + arch; + libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/um/") + arch; + } else if (isPhone) { QString sdkDir = vcInstallDir; if (!QDir(sdkDir).exists()) { fprintf(stderr, "Failed to find the Windows Phone SDK in %s.\n" @@ -208,7 +231,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) << kitDir + QStringLiteral("/include/shared") << kitDir + QStringLiteral("/include/winrt"); } - // Inherit PATH binDirs << QString::fromLocal8Bit(qgetenv("PATH")).split(QLatin1Char(';')); diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 59136b16c8..7092da3e59 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -56,7 +56,8 @@ enum DotNET { NET2008 = 0x90, NET2010 = 0xa0, NET2012 = 0xb0, - NET2013 = 0xc0 + NET2013 = 0xc0, + NET2015 = 0xd0 }; /* diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 1fa117afda..fd2fc2eb94 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -71,6 +71,7 @@ struct DotNetCombo { const char *regKey; } dotNetCombo[] = { #ifdef Q_OS_WIN64 + {NET2015, "MSVC.NET 2015 (14.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 (12.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Wow6432Node\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"}, {NET2012, "MSVC.NET 2012 (11.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir"}, @@ -84,6 +85,7 @@ struct DotNetCombo { {NET2003, "MSVC.NET 2003 (7.1)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir"}, {NET2002, "MSVC.NET 2002 (7.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"}, #else + {NET2015, "MSVC.NET 2015 (14.0)", "Software\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 (12.0)", "Software\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"}, {NET2012, "MSVC.NET 2012 (11.0)", "Software\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir"}, @@ -175,6 +177,8 @@ const char _slnHeader110[] = "Microsoft Visual Studio Solution File, Format "\n# Visual Studio 2012"; const char _slnHeader120[] = "Microsoft Visual Studio Solution File, Format Version 12.00" "\n# Visual Studio 2013"; +const char _slnHeader140[] = "Microsoft Visual Studio Solution File, Format Version 12.00" + "\n# Visual Studio 2015"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects @@ -401,6 +405,8 @@ QString VcprojGenerator::retrievePlatformToolSet() const return QStringLiteral("v110") + suffix; case NET2013: return QStringLiteral("v120") + suffix; + case NET2015: + return QStringLiteral("v140") + suffix; default: return QString(); } @@ -647,6 +653,8 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2015: + t << _slnHeader140; case NET2013: t << _slnHeader120; break; @@ -972,6 +980,9 @@ void VcprojGenerator::initProject() // Own elements ----------------------------- vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString(); switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2015: + vcProject.Version = "14.00"; + break; case NET2013: vcProject.Version = "12.00"; break; -- cgit v1.2.3 From a8dda3b8b06f86ec3fbf845c5397c746b83e0c11 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Fri, 10 Apr 2015 14:27:06 +0200 Subject: Tests: Use blacklist for failing tst_qwidget tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the insignificant_tests CONFIG option in favor of a BLACKLIST file. The tests blacklisted have been found using CI builds logs. Change-Id: Iffc9043654a9dcd97d55e262011c8daff6f4e60f Task-number: QTBUG-25300 Task-number: QTBUG-45502 Task-number: QTBUG-46325 Reviewed-by: Morten Johan Sørvig --- tests/auto/widgets/kernel/qwidget/BLACKLIST | 121 ++++++++++++++++++++++++++ tests/auto/widgets/kernel/qwidget/qwidget.pro | 2 - 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index ed40f98051..591aa9e40f 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -1,11 +1,16 @@ +# OSX QTBUG-25300 QTBUG-45502 [normalGeometry] ubuntu-14.04 +osx [saveRestoreGeometry] ubuntu-14.04 +osx [restoreVersion1Geometry] ubuntu-14.04 +osx [updateWhileMinimized] ubuntu-14.04 +osx [focusProxyAndInputMethods] ubuntu-14.04 [touchEventSynthesizedMouseEvent] @@ -14,3 +19,119 @@ ubuntu-14.04 ubuntu-14.04 [largerThanScreen_QTBUG30142] ubuntu-14.04 +[windowState] +osx +[showMaximized] +osx +[setGeometry] +osx +[stackUnder] +osx +[raise] +osx-10.9 +[widgetAt] +osx +[sheetOpacity] +osx +[resizeEvent] +osx +[setWindowGeometry:100,123 200x200, flags 0] +osx-10.10 +[windowMoveResize:100,123 200x200, flags 0] +osx-10.10 +[setWindowGeometry:100,122 200x200, flags 0] +osx-10.9 +[windowMoveResize:100,122 200x200, flags 0] +osx-10.9 +[setWindowGeometry:100,100 824x564, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x564, flags 0] +osx-10.10 +[setWindowGeometry:100,100 824x516, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x516, flags 0] +osx-10.10 +[setWindowGeometry:100,73 200x0, flags 0] +osx-10.10 +[windowMoveResize:100,73 200x0, flags 0] +osx-10.10 +[setWindowGeometry:100,100 824x519, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x519, flags 0] +osx-10.10 +[setWindowGeometry:100,100 824x518, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x518, flags 0] +osx-10.10 +[setWindowGeometry:100,72 200x0, flags 0] +osx-10.9 +[windowMoveResize:100,72 200x0, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x574, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x574, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x578, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x578, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x576, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x576, flags 0] +osx-10.9 +[setWindowGeometry:100,100 824x521, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x521, flags 0] +osx-10.10 +[setWindowGeometry:100,122 952x577, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x577, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x580, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x580, flags 0] +osx-10.9 +[windowMoveResize:130,72 0x0, flags 0] +osx-10.9 +[windowMoveResize:130,122 0x200, flags 0] +osx-10.9 +[childEvents] +osx +[renderInvisible] +osx +[optimizedResizeMove] +osx +[optimizedResize_topLevel] +osx +[render_systemClip] +osx +[update] +osx +[doubleRepaint] +osx +[childAt_unifiedToolBar] +osx +[showMinimizedKeepsFocus] +osx-10.10 +[moveWindowInShowEvent:1] +osx-10.9 +[moveWindowInShowEvent:2] +osx-10.9 +[taskQTBUG_4055_sendSyntheticEnterLeave] +osx +[syntheticEnterLeave] +osx +[maskedUpdate] +osx +[hideWhenFocusWidgetIsChild] +osx-10.10 +[hideOpaqueChildWhileHidden] +osx +[resizeStaticContentsChildWidget_QTBUG35282] +osx-10.9 +[lower] +osx +[setClearAndResizeMask] +osx +[setToolTip] +osx-10.9 diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.pro b/tests/auto/widgets/kernel/qwidget/qwidget.pro index 30e1048247..aae083d45e 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.pro +++ b/tests/auto/widgets/kernel/qwidget/qwidget.pro @@ -21,5 +21,3 @@ x11 { } !wince*:win32:!winrt: LIBS += -luser32 -lgdi32 - -mac:CONFIG+=insignificant_test # QTBUG-25300, QTBUG-23695 -- cgit v1.2.3 From fe6eeab5618d9f42929872faff94dacdc0890fd2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 26 May 2015 12:08:17 +0200 Subject: QWindowsVistaStyle: Do not stop animations when falling back to XP. Otherwise, progress bar animations are stopped. Task-number: QTBUG-46308 Change-Id: I7b6a2b26afb885db6bc9aea719a002f0ebe7274d Reviewed-by: J-P Nurmi --- src/widgets/styles/qwindowsvistastyle.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index f715d93298..daa8ab12a9 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -250,8 +250,6 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt int state = option->state; if (!QWindowsVistaStylePrivate::useVista()) { - foreach (const QObject *target, d->animationTargets()) - d->stopAnimation(target); QWindowsStyle::drawPrimitive(element, option, painter, widget); return; } @@ -810,8 +808,6 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QWindowsVistaStylePrivate *d = const_cast(d_func()); if (!QWindowsVistaStylePrivate::useVista()) { - foreach (const QObject *target, d->animationTargets()) - d->stopAnimation(target); QWindowsStyle::drawControl(element, option, painter, widget); return; } @@ -1494,8 +1490,6 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle { QWindowsVistaStylePrivate *d = const_cast(d_func()); if (!QWindowsVistaStylePrivate::useVista()) { - foreach (const QObject *target, d->animationTargets()) - d->stopAnimation(target); QWindowsStyle::drawComplexControl(control, option, painter, widget); return; } -- cgit v1.2.3 From 5d707bff3d2b01532ccfc429096e3fd34988e619 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 21 May 2015 15:45:44 +0200 Subject: Make Qt Edition available to qmake Allow .pro, .prf ... files to check the edition (OpenSource, Evaluation, Preview, Enterprise ...) of the Qt installation. Change-Id: If2a8e3877d066b225b1777916cef1d23c65f8512 Reviewed-by: Oswald Buddenhagen --- configure | 2 ++ tools/configure/configureapp.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/configure b/configure index dddb40f485..19802a367c 100755 --- a/configure +++ b/configure @@ -6763,6 +6763,8 @@ QT_PATCH_VERSION = $QT_PATCH_VERSION QT_LIBINFIX = $QT_LIBINFIX QT_NAMESPACE = $QT_NAMESPACE +QT_EDITION = $Edition + EOF if [ "$CFG_SHARED" = "no" ]; then diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 08ec943563..4d1ce3d113 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3460,6 +3460,9 @@ void Configure::generateQConfigPri() << "QT_MINOR_VERSION = " << dictionary["VERSION_MINOR"] << endl << "QT_PATCH_VERSION = " << dictionary["VERSION_PATCH"] << endl; + configStream << endl + << "QT_EDITION = " << dictionary["EDITION"] << endl; + if (!dictionary["CFG_SYSROOT"].isEmpty() && dictionary["CFG_GCC_SYSROOT"] == "yes") { configStream << endl << "# sysroot" << endl -- cgit v1.2.3 From 40327b6febf268ace25c0d5f372a4811c4867a93 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 22 May 2015 12:45:47 +0200 Subject: Resolve path to right licheck In the unix commercial packages, licheck so far has been a shell script that redirected to the 'right' licheck. To simplify things we now resolve the right executable path in configure itself. Change-Id: I1183d000a11bf42729f3e0405a0bc1d4b618933c Reviewed-by: Oswald Buddenhagen --- configure | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 19802a367c..db4abf977b 100755 --- a/configure +++ b/configure @@ -2962,8 +2962,20 @@ if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ]; Edition="Preview" EditionString="Technology Preview" elif [ $COMMERCIAL_USER = "yes" ]; then - if test -x "$relpath/bin/licheck"; then - LicheckOutput=`$relpath/bin/licheck $OPT_CONFIRM_LICENSE $relpath $outpath\ + if [ $UNAME_SYSTEM = "Linux" ]; then + if file -L /bin/sh | grep -q "64-bit" ; then + Licheck=licheck64 + else + Licheck=licheck32 + fi + elif [ $UNAME_SYSTEM = "Darwin" ]; then + Licheck=licheck_mac + else + echo >&2 "Host operating system not supported by this edition of Qt." + exit 1 + fi + if [ -x "$relpath/bin/$Licheck" ]; then + LicheckOutput=`$relpath/bin/$Licheck $OPT_CONFIRM_LICENSE $relpath $outpath\ $PLATFORM $XPLATFORM` if [ $? -ne 0 ]; then exit 1 -- cgit v1.2.3 From 63660402d8d803b97c676395895c25e550c07f94 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 22 May 2015 15:02:23 +0200 Subject: Run license checker in qmake Check for a valid license not only in configure, but also in qmake. To limit the runtime overhead we cache the day of the last run in a .stash file. This allows us to run licheck only for the top-level qmake call, and only once per day. This requires an updated licheck executable that supports the new check mode. [ChangeLog][Tools][qmake] For commercial builds, qmake now checks for a valid Qt license. This requires setting up a Qt Account (or .qt-license file) on the development machine. Change-Id: I2c2a05a4602cc661560568b76ddf520cb8134769 Reviewed-by: Oswald Buddenhagen --- configure | 7 ++++++- mkspecs/features/default_pre.prf | 15 +++++++++++++++ qtbase.pro | 5 +++++ tools/configure/configureapp.cpp | 5 +++++ tools/configure/tools.cpp | 2 ++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/configure b/configure index db4abf977b..234ddc6971 100755 --- a/configure +++ b/configure @@ -6776,9 +6776,14 @@ QT_LIBINFIX = $QT_LIBINFIX QT_NAMESPACE = $QT_NAMESPACE QT_EDITION = $Edition - EOF +if [ "$Edition" != "OpenSource" ] && [ "$Edition" != "Preview" ]; then + echo "QT_LICHECK = $Licheck" >> "$QTCONFIG.tmp" + echo "QT_RELEASE_DATE = $ReleaseDate" >> "$QTCONFIG.tmp" +fi +echo >> "$QTCONFIG.tmp" + if [ "$CFG_SHARED" = "no" ]; then echo "QT_DEFAULT_QPA_PLUGIN = q$QT_QPA_DEFAULT_PLATFORM" >> "$QTCONFIG.tmp" echo >> "$QTCONFIG.tmp" diff --git a/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf index b06b9d6cfc..eb3281ea1d 100644 --- a/mkspecs/features/default_pre.prf +++ b/mkspecs/features/default_pre.prf @@ -7,3 +7,18 @@ CONFIG = \ lex yacc debug exceptions depend_includepath \ testcase_targets import_plugins import_qpa_plugin \ $$CONFIG + +!build_pass:defined(QT_EDITION, var):!equals(QT_EDITION, "OpenSource"):!equals(QT_EDITION, "Preview") { + # + # call license checker (but cache result for one day) + # + today = $$section(_DATE_, " ", 0, 2) + !isEqual(QMAKE_LICHECK_TIMESTAMP, $$today) { + !system("$$system_quote($$system_path($$[QT_HOST_BINS/src]/$$QT_LICHECK)) check" \ + "$$QT_RELEASE_DATE $$[QMAKE_SPEC] $$[QMAKE_XSPEC]"): \ + error("License check failed! Giving up ...") + + cache(QMAKE_LICHECK_TIMESTAMP, set stash, today) + } + unset(today) +} diff --git a/qtbase.pro b/qtbase.pro index bae2641404..51e8fb8760 100644 --- a/qtbase.pro +++ b/qtbase.pro @@ -46,6 +46,11 @@ equals(QMAKE_HOST.os, Windows) { } INSTALLS += qmake +#licheck +licheck.path = $$[QT_HOST_BINS] +licheck.files = $$PWD/bin/$$QT_LICHECK +exists($$licheck.files): INSTALLS += licheck + #syncqt syncqt.path = $$[QT_HOST_BINS] syncqt.files = $$PWD/bin/syncqt.pl diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 4d1ce3d113..6bf0646378 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3463,6 +3463,11 @@ void Configure::generateQConfigPri() configStream << endl << "QT_EDITION = " << dictionary["EDITION"] << endl; + if (dictionary["EDITION"] != "OpenSource" && dictionary["EDITION"] != "Preview") { + configStream << "QT_LICHECK = " << dictionary["LICHECK"] << endl; + configStream << "QT_RELEASE_DATE = " << dictionary["RELEASEDATE"] << endl; + } + if (!dictionary["CFG_SYSROOT"].isEmpty() && dictionary["CFG_GCC_SYSROOT"] == "yes") { configStream << endl << "# sysroot" << endl diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index 83d969ce16..095e798332 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.cpp @@ -54,6 +54,8 @@ void Tools::checkLicense(QMap &dictionary, return; } + dictionary["LICHECK"] = "licheck.exe"; + const QString licenseChecker = QDir::toNativeSeparators(sourcePath + "/bin/licheck.exe"); -- cgit v1.2.3 From 02f6b21bbc4f1f7afc30a87227c3a0787a5d2225 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 23 Apr 2015 12:02:40 +0200 Subject: QMetaType: Fix compilation with non default constructible Q_GADGET Do not try to automatically register the meta type for Q_GADGET that are not default constructible. This fixes a source incompatibility in the function pointer syntax of QObject::connect when such types are used as an argument of a signal. Task-number: QTBUG-45721 Change-Id: I3065f6d57bc1f37e16988d2dee99118de250ca56 Reviewed-by: Thiago Macieira --- src/corelib/global/qtypetraits.h | 21 +++++++++++++++++++ src/corelib/kernel/qmetatype.h | 2 +- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 7 ++++++- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 24 ++++++++++++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qtypetraits.h b/src/corelib/global/qtypetraits.h index 3a305713e6..488e257e0f 100644 --- a/src/corelib/global/qtypetraits.h +++ b/src/corelib/global/qtypetraits.h @@ -506,6 +506,27 @@ Q_STATIC_ASSERT((!is_unsigned::value)); Q_STATIC_ASSERT((!is_signed::value)); Q_STATIC_ASSERT(( is_signed::value)); +template struct is_default_constructible; + +template<> struct is_default_constructible +{ +protected: + template struct test { typedef char type; }; +public: + static bool const value = false; +}; +template<> struct is_default_constructible<>::test { typedef double type; }; + +template struct is_default_constructible : is_default_constructible<> +{ +private: + template static typename test::type sfinae(U*); + template static char sfinae(...); +public: + static bool const value = sizeof(sfinae(0)) > 1; +}; + + } // namespace QtPrivate QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 9ad8702e79..1b214e9f74 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1773,7 +1773,7 @@ template struct QMetaTypeIdQObject { enum { - Defined = 1 + Defined = QtPrivate::is_default_constructible::value }; static int qt_metatype_id() diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 691a4e819d..9cdb1f47f8 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -142,6 +142,11 @@ public: class CustomGadget { Q_GADGET }; +class CustomGadget_NonDefaultConstructible { + Q_GADGET +public: + CustomGadget_NonDefaultConstructible(int) {}; +}; class CustomNonQObject {}; class GadgetDerived : public CustomGadget {}; @@ -159,7 +164,7 @@ void tst_QMetaType::defined() QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); - QVERIFY(!QMetaTypeId2::Defined); + QVERIFY(!QMetaTypeId2::Defined); } struct Bar diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 263cc5a07a..3ec84b5198 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -128,6 +128,7 @@ private slots: void connectWithReference(); void connectManyArguments(); void connectForwardDeclare(); + void connectNoDefaultConstructorArg(); void returnValue_data(); void returnValue(); void returnValue2_data(); @@ -5227,6 +5228,29 @@ void tst_QObject::connectForwardDeclare() QVERIFY(connect(&ob, &ForwardDeclareArguments::mySignal, &ob, &ForwardDeclareArguments::mySlot, Qt::QueuedConnection)); } +class NoDefaultConstructor +{ + Q_GADGET +public: + NoDefaultConstructor(int) {} +}; + +class NoDefaultContructorArguments : public QObject +{ + Q_OBJECT +signals: + void mySignal(const NoDefaultConstructor&); +public slots: + void mySlot(const NoDefaultConstructor&) {} +}; + +void tst_QObject::connectNoDefaultConstructorArg() +{ + NoDefaultContructorArguments ob; + // it should compile + QVERIFY(connect(&ob, &NoDefaultContructorArguments::mySignal, &ob, &NoDefaultContructorArguments::mySlot, Qt::QueuedConnection)); +} + class ReturnValue : public QObject { friend class tst_QObject; Q_OBJECT -- cgit v1.2.3 From 310b7ef010f524e8d3cde5605cd495a4ffed5862 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Tue, 19 May 2015 10:48:21 +0300 Subject: QIODevice::read(): limit the size of result buffer with a proper value Now its maximum size is QByteArray::MaxSize not INT_MAX. Change-Id: Id548b3cb94f910a3212665182280a3a2948dd93e Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qiodevice.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 872e004d2f..b908ae3145 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -41,7 +41,6 @@ #include "qdir.h" #include -#include #ifdef QIODEVICE_DEBUG # include @@ -942,9 +941,9 @@ QByteArray QIODevice::read(qint64 maxSize) Q_UNUSED(d); #endif - if (maxSize != qint64(int(maxSize))) { + if (quint64(maxSize) >= QByteArray::MaxSize) { checkWarnMessage(this, "read", "maxSize argument exceeds QByteArray size limit"); - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; } qint64 readBytes = 0; @@ -996,7 +995,7 @@ QByteArray QIODevice::readAll() // flush internal read buffer if (!(d->openMode & Text) && !d->buffer.isEmpty()) { - if (d->buffer.size() >= INT_MAX) + if (quint64(d->buffer.size()) >= QByteArray::MaxSize) return QByteArray(); result = d->buffer.readAll(); readBytes = result.size(); @@ -1179,9 +1178,9 @@ QByteArray QIODevice::readLine(qint64 maxSize) Q_UNUSED(d); #endif - if (maxSize > INT_MAX) { + if (quint64(maxSize) >= QByteArray::MaxSize) { qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit"); - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; } result.resize(int(maxSize)); @@ -1189,7 +1188,7 @@ QByteArray QIODevice::readLine(qint64 maxSize) if (!result.size()) { // If resize fails or maxSize == 0, read incrementally if (maxSize == 0) - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; // The first iteration needs to leave an extra byte for the terminating null result.resize(1); -- cgit v1.2.3 From 42b7a7c6097825e9fa4a11abac3ad61db051162d Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 27 May 2015 12:27:19 +0200 Subject: Fix crash due to QTreeView accessing deleted model indexes. QTreeViewPrivate::updateScrollBars depends on a correctly set up viewItems vector. If a delayed layout is pending, we must call QTreeViewPrivate::executePostedLayout before accessing any stored model indices. Task-number: QTBUG-45697 Change-Id: I55fcbaf81f225b26181c2cf739283740b85dd16a Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/itemviews/qtreeview.cpp | 1 + .../widgets/itemviews/qtreeview/tst_qtreeview.cpp | 78 ++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 43db43fcd4..9b3e270fdd 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -3658,6 +3658,7 @@ void QTreeViewPrivate::updateScrollBars() if (!viewportSize.isValid()) viewportSize = QSize(0, 0); + executePostedLayout(); if (viewItems.isEmpty()) { q->doItemsLayout(); } diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 3ead172d82..1324027af6 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -255,6 +255,7 @@ private slots: void taskQTBUG_8176_emitOnExpandAll(); void taskQTBUG_34717_collapseAtBottom(); void taskQTBUG_37813_crash(); + void taskQTBUG_45697_crash(); void testInitialFocus(); }; @@ -4385,5 +4386,82 @@ void tst_QTreeView::taskQTBUG_37813_crash() #endif // QT_BUILD_INTERNAL } +// QTBUG-45697: Using a QTreeView with a multi-column model filtered by QSortFilterProxyModel, +// when sorting the source model while the widget is not yet visible and showing the widget +// later on, corruption occurs in QTreeView. +class Qtbug45697TestWidget : public QWidget +{ + Q_OBJECT +public: + static const int columnCount = 3; + + explicit Qtbug45697TestWidget(); + int timerTick() const { return m_timerTick; } + +public slots: + void slotTimer(); + +private: + QTreeView *m_treeView; + QStandardItemModel *m_model; + QSortFilterProxyModel *m_sortFilterProxyModel; + int m_timerTick; +}; + +Qtbug45697TestWidget::Qtbug45697TestWidget() + : m_treeView(new QTreeView(this)) + , m_model(new QStandardItemModel(0, Qtbug45697TestWidget::columnCount, this)) + , m_sortFilterProxyModel(new QSortFilterProxyModel(this)) + , m_timerTick(0) + { + QVBoxLayout *vBoxLayout = new QVBoxLayout(this); + vBoxLayout->addWidget(m_treeView); + + for (char sortChar = 'z'; sortChar >= 'a' ; --sortChar) { + QList items; + for (int column = 0; column < Qtbug45697TestWidget::columnCount; ++column) { + const QString text = QLatin1Char(sortChar) + QLatin1String(" ") + QString::number(column); + items.append(new QStandardItem(text)); + } + m_model->appendRow(items); + } + + m_sortFilterProxyModel->setSourceModel(m_model); + m_treeView->setModel(m_sortFilterProxyModel); + + QHeaderView *headerView = m_treeView->header(); + for (int s = 1, lastSection = headerView->count() - 1; s < lastSection; ++s ) + headerView->setSectionResizeMode(s, QHeaderView::ResizeToContents); + + QTimer *timer = new QTimer(this); + timer->setInterval(50); + connect(timer, &QTimer::timeout, this, &Qtbug45697TestWidget::slotTimer); + timer->start(); +} + +void Qtbug45697TestWidget::slotTimer() +{ + switch (m_timerTick++) { + case 0: + m_model->sort(0); + break; + case 1: + show(); + break; + default: + close(); + break; + } +} + +void tst_QTreeView::taskQTBUG_45697_crash() +{ + Qtbug45697TestWidget testWidget; + testWidget.setWindowTitle(QTest::currentTestFunction()); + testWidget.resize(400, 400); + testWidget.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(100, 100)); + QTRY_VERIFY(testWidget.timerTick() >= 2); +} + QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" -- cgit v1.2.3 From 9749ddeb4b2eb083413441a9403d7b5ffab1f6c1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 May 2015 17:02:57 +0200 Subject: Remove test other/baselineexample. baselineexample.pro is missing CONFIG += testcase, so, make check succeeds without doing anything. The test seems to connect to some network server to retrieve baseline images, but that infrastructure apparently no longer exists. Change-Id: I98f4fe5ef8a508fda90e408df2781a944eb99a60 Reviewed-by: Simon Hausmann --- .../auto/other/baselineexample/baselineexample.pro | 19 --- .../other/baselineexample/tst_baselineexample.cpp | 138 --------------------- tests/auto/other/other.pro | 3 - 3 files changed, 160 deletions(-) delete mode 100644 tests/auto/other/baselineexample/baselineexample.pro delete mode 100644 tests/auto/other/baselineexample/tst_baselineexample.cpp diff --git a/tests/auto/other/baselineexample/baselineexample.pro b/tests/auto/other/baselineexample/baselineexample.pro deleted file mode 100644 index c1c4b31bfe..0000000000 --- a/tests/auto/other/baselineexample/baselineexample.pro +++ /dev/null @@ -1,19 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-12-09T14:55:13 -# -#------------------------------------------------- - -QT += testlib widgets - -TARGET = tst_baselineexample -CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - -SOURCES += tst_baselineexample.cpp -DEFINES += SRCDIR=\\\"$$PWD/\\\" - -include($$PWD/../../../baselineserver/shared/qbaselinetest.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/other/baselineexample/tst_baselineexample.cpp b/tests/auto/other/baselineexample/tst_baselineexample.cpp deleted file mode 100644 index 9059989015..0000000000 --- a/tests/auto/other/baselineexample/tst_baselineexample.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite 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$ -** -****************************************************************************/ - -#include -#include - -class tst_BaselineExample : public QObject -{ - Q_OBJECT - -public: - tst_BaselineExample(); - -private Q_SLOTS: - void testBasicUsage(); - void testMultipleImages(); - void testDataDriven_data(); - void testDataDriven(); - void testDataDrivenChecksum_data(); - void testDataDrivenChecksum(); -}; - - -tst_BaselineExample::tst_BaselineExample() -{ -} - - -void tst_BaselineExample::testBasicUsage() -{ - // Generate an image: - QPushButton b("Press me!"); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QImage img1 = b.grab().toImage(); - QVERIFY(!img1.isNull()); - - // Compare it to baseline on server: - QBASELINE_CHECK(img1, "button"); -} - - -void tst_BaselineExample::testMultipleImages() -{ - QPushButton b("Press me!"); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QBASELINE_CHECK(b.grab().toImage(), "text1"); - - b.setText("Kick me!"); - QTest::qWait(50); - QBASELINE_CHECK(b.grab().toImage(), "text2"); -} - - -void tst_BaselineExample::testDataDriven_data() -{ - QTest::addColumn("label"); - QBaselineTest::newRow("short") << "Ok!"; - QBaselineTest::newRow("long") << "A really long button text that just does not seem to end"; - QBaselineTest::newRow("empty") << ""; - QBaselineTest::newRow("signs") << "!@#$%^&*()_"; - QBaselineTest::newRow("html") << "BOLD"; -} - - -void tst_BaselineExample::testDataDriven() -{ - QFETCH(QString, label); - QPushButton b(label); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QBASELINE_TEST(b.grab().toImage()); -} - - -void tst_BaselineExample::testDataDrivenChecksum_data() -{ - QTest::addColumn("label"); - - const int numItems = 5; - const char *tags[numItems] = {"short", "long", "empty", "signs", "html"}; - const char *labels[numItems] = {"Ok!", "A really long button text that just does not seem to end", "", "!@#$%^&*()_", "BOLD"}; - - for (int i = 0; i Date: Sun, 24 May 2015 09:04:24 -0700 Subject: Fix forkfd on OS X 10.7 and earlier by avoiding waitid altogether On OS X 10.7 and earlier, waitid() never sets si_pid, even when using P_PID. So on OS X, check if waitid() works, and if not, use the same codepath as if HAVE_WAITID were not defined. Change-Id: I64331a090f9358bb01f435954d3dfd3ab430a96c Reviewed-by: Thiago Macieira --- src/3rdparty/forkfd/forkfd.c | 56 +++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 017ae0741e..8d08f403ec 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -63,7 +63,7 @@ # include # include # if MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 -# define HAVE_BROKEN_WAITID_ALL 1 +# define HAVE_BROKEN_WAITID 1 # endif #endif @@ -109,10 +109,10 @@ static struct sigaction old_sigaction; static pthread_once_t forkfd_initialization = PTHREAD_ONCE_INIT; static ffd_atomic_int forkfd_status = FFD_ATOMIC_INIT(0); -#ifdef HAVE_BROKEN_WAITID_ALL -static int waitid_p_all_works = 0; +#ifdef HAVE_BROKEN_WAITID +static int waitid_works = 0; #else -static const int waitid_p_all_works = 1; +static const int waitid_works = 1; #endif static ProcessInfo *tryAllocateInSection(Header *header, ProcessInfo entries[], int maxCount) @@ -183,10 +183,13 @@ static int tryReaping(pid_t pid, siginfo_t *info) { /* reap the child */ #ifdef HAVE_WAITID - // we have waitid(2), which fills in siginfo_t for us - info->si_pid = 0; - return waitid(P_PID, pid, info, WEXITED | WNOHANG) == 0 && info->si_pid == pid; -#else + if (waitid_works) { + // we have waitid(2), which fills in siginfo_t for us + info->si_pid = 0; + return waitid(P_PID, pid, info, WEXITED | WNOHANG) == 0 && info->si_pid == pid; + } +#endif + int status; if (waitpid(pid, &status, WNOHANG) <= 0) return 0; // child did not change state @@ -206,7 +209,6 @@ static int tryReaping(pid_t pid, siginfo_t *info) } return 1; -#endif } static void freeInfo(Header *header, ProcessInfo *entry) @@ -246,7 +248,7 @@ static void sigchld_handler(int signum) memset(&info, 0, sizeof info); #ifdef HAVE_WAITID - if (!waitid_p_all_works) + if (!waitid_works) goto search_arrays; /* be optimistic: try to see if we can get the child that exited */ @@ -310,12 +312,14 @@ search_arrays: if (pid <= 0) continue; #ifdef HAVE_WAITID - /* The child might have been reaped by the block above in another thread, - * so first check if it's ready and, if it is, lock it */ - if (!isChildReady(pid, &info) || - !ffd_atomic_compare_exchange(&children.entries[i].pid, &pid, -1, - FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) - continue; + if (waitid_works) { + /* The child might have been reaped by the block above in another thread, + * so first check if it's ready and, if it is, lock it */ + if (!isChildReady(pid, &info) || + !ffd_atomic_compare_exchange(&children.entries[i].pid, &pid, -1, + FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) + continue; + } #endif if (tryReaping(pid, &info)) { /* this is our child, send notification and free up this entry */ @@ -331,12 +335,14 @@ search_arrays: if (pid <= 0) continue; #ifdef HAVE_WAITID - /* The child might have been reaped by the block above in another thread, - * so first check if it's ready and, if it is, lock it */ - if (!isChildReady(pid, &info) || - !ffd_atomic_compare_exchange(&array->entries[i].pid, &pid, -1, - FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) - continue; + if (waitid_works) { + /* The child might have been reaped by the block above in another thread, + * so first check if it's ready and, if it is, lock it */ + if (!isChildReady(pid, &info) || + !ffd_atomic_compare_exchange(&array->entries[i].pid, &pid, -1, + FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) + continue; + } #endif if (tryReaping(pid, &info)) { /* this is our child, send notification and free up this entry */ @@ -357,17 +363,19 @@ chain_handler: static void forkfd_initialize() { -#if defined(HAVE_BROKEN_WAITID_ALL) +#if defined(HAVE_BROKEN_WAITID) pid_t pid = fork(); if (pid == 0) { _exit(0); } else if (pid > 0) { siginfo_t info; waitid(P_ALL, 0, &info, WNOWAIT | WEXITED); - waitid_p_all_works = (info.si_pid != 0); + waitid_works = (info.si_pid != 0); + info.si_pid = 0; // now really reap the child waitid(P_PID, pid, &info, WEXITED); + waitid_works = waitid_works && (info.si_pid != 0); } #endif -- cgit v1.2.3 From 5449589b7c45a5ce1374c358bbcb1eba130d390d Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 27 May 2015 14:08:04 +0200 Subject: tst_QApplication - quitOnLastWindowClosed (fix for OS X) Two (?) tests can fail: what they actually try to test is that our application quits on the second single shot timer (2 s. timeout) and not on the first one (timeout 1 s.) - on the first timeout we either ignore event, or we still have another window and should not quit yet, on the second timeout we actually do quit the app. The test checks this in a quite fragile way, counting the number of timeouts for the third 100 ms timer. It looks like on OS X (VM-only) there is some delay (~500-600 ms) before we receive the first timeout so the count is always 14 or less, making the test to fail. Change-Id: I9e8728e6c956025d91528f4195982767a5d3d320 Task-number: QTBUG-46164 Reviewed-by: Simon Hausmann Reviewed-by: Gabriel de Dietrich --- .../kernel/qapplication/tst_qapplication.cpp | 34 +++++++++++++--------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index c9a1a64135..c33fd5a951 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -178,6 +178,12 @@ private slots: void settableStyleHints_data(); void settableStyleHints(); // Needs to run last as it changes style hints. + +protected slots: + void quitApplication(); + +private: + bool quitApplicationTriggered; }; class EventSpy : public QObject @@ -235,6 +241,7 @@ public: static char *argv0; tst_QApplication::tst_QApplication() + : quitApplicationTriggered(false) { #ifdef Q_OS_WINCE // Clean up environment previously to launching test @@ -719,11 +726,8 @@ void tst_QApplication::quitOnLastWindowClosed() { int argc = 0; QApplication app(argc, 0); - QTimer timer; - timer.setInterval(100); QSignalSpy spy(&app, SIGNAL(aboutToQuit())); - QSignalSpy spy2(&timer, SIGNAL(timeout())); CloseEventTestWindow mainWindow; @@ -733,14 +737,14 @@ void tst_QApplication::quitOnLastWindowClosed() mainWindow.show(); QVERIFY(QTest::qWaitForWindowExposed(&mainWindow)); - timer.start(); - QTimer::singleShot(1000, &mainWindow, SLOT(close())); // This should quit the application - QTimer::singleShot(2000, &app, SLOT(quit())); // This makes sure we quit even if it didn't + QTimer::singleShot(1000, &mainWindow, SLOT(close())); // This should NOT quit the application (see CloseEventTestWindow) + quitApplicationTriggered = false; + QTimer::singleShot(2000, this, SLOT(quitApplication())); // This actually quits the application. app.exec(); QCOMPARE(spy.count(), 1); - QVERIFY(spy2.count() > 15); // Should be around 20 if closing did not caused the quit + QVERIFY(quitApplicationTriggered); } { int argc = 0; @@ -768,24 +772,20 @@ void tst_QApplication::quitOnLastWindowClosed() QApplication app(argc, 0); QVERIFY(app.quitOnLastWindowClosed()); - QTimer timer; - timer.setInterval(100); - QSignalSpy timerSpy(&timer, SIGNAL(timeout())); - QWindow w; w.show(); QWidget wid; wid.show(); - timer.start(); QTimer::singleShot(1000, &wid, SLOT(close())); // This should NOT quit the application because the // QWindow is still there. - QTimer::singleShot(2000, &app, SLOT(quit())); // This causes the quit. + quitApplicationTriggered = false; + QTimer::singleShot(2000, this, SLOT(quitApplication())); // This causes the quit. app.exec(); - QVERIFY(timerSpy.count() > 15); // Should be around 20 if closing did not caused the quit + QVERIFY(quitApplicationTriggered); // Should be around 20 if closing did not caused the quit } { // QTBUG-31569: If the last widget with Qt::WA_QuitOnClose set is closed, other // widgets that don't have the attribute set should be closed automatically. @@ -2406,6 +2406,12 @@ void tst_QApplication::globalStaticObjectDestruction() #endif } +void tst_QApplication::quitApplication() +{ + quitApplicationTriggered = true; + qApp->quit(); +} + //QTEST_APPLESS_MAIN(tst_QApplication) int main(int argc, char *argv[]) { -- cgit v1.2.3 From 73d3f1b116a584b97ec0defc9df68bc3507d5cc7 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Tue, 26 May 2015 17:05:35 +0900 Subject: Doc fix typo in QT_MESSAGE_PATTERN Change-Id: I1850c3eb07b06a4174c0e6819074040c4d62c423 Reviewed-by: Kai Koehne --- src/corelib/global/qlogging.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 447a875655..88882bbe8f 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1737,7 +1737,7 @@ void qErrnoWarning(int code, const char *msg, ...) Example: \code - QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D{%endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" + QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" \endcode The default \a pattern is "%{if-category}%{category}: %{endif}%{message}". -- cgit v1.2.3 From 270313d06848e20dffdfae8951838a63e6cb204c Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 26 May 2015 14:33:25 +0200 Subject: Fix wording of error message This broke with commit 83a5694dc21b8 . Change-Id: Ib641cef9639f1c70a5f38ce0e5d9d9e3071373e4 Reviewed-by: Oswald Buddenhagen --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 234ddc6971..de0a1bd5d7 100755 --- a/configure +++ b/configure @@ -2986,7 +2986,7 @@ elif [ $COMMERCIAL_USER = "yes" ]; then echo echo "Error: This is the Open Source version of Qt." echo "If you want to use Enterprise features of Qt," - echo "information use the contact form at http://www.qt.io/contact-us" + echo "use the contact form at http://www.qt.io/contact-us" echo "to purchase a license." echo exit 1 -- cgit v1.2.3 From e63dde49678baf8041e32254a7b6b35d871d201f Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 22 May 2015 15:33:34 +0200 Subject: configure: Remove traces of "Snapshot" edition Change-Id: I7f2511e224d848bb820321be5dd190d8b3b8f1c4 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 6bf0646378..10b33f41e4 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -4389,7 +4389,7 @@ bool Configure::showLicense(QString orgLicenseFile) bool showLgpl2 = true; QString licenseFile = orgLicenseFile; QString theLicense; - if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") { + if (dictionary["EDITION"] == "OpenSource") { if (platform() != ANDROID || dictionary["ANDROID_STYLE_ASSETS"] == "no") { theLicense = "GNU Lesser General Public License (LGPL) version 2.1" "\nor the GNU Lesser General Public License (LGPL) version 3"; @@ -4412,7 +4412,7 @@ bool Configure::showLicense(QString orgLicenseFile) cout << "You are licensed to use this software under the terms of" << endl << "the " << theLicense << "." << endl << endl; - if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") { + if (dictionary["EDITION"] == "OpenSource") { cout << "Type '3' to view the Lesser GNU General Public License version 3 (LGPLv3)." << endl; if (showLgpl2) cout << "Type 'L' to view the Lesser GNU General Public License version 2.1 (LGPLv2.1)." << endl; @@ -4431,7 +4431,7 @@ bool Configure::showLicense(QString orgLicenseFile) } else if (accept == 'n') { return false; } else { - if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") { + if (dictionary["EDITION"] == "OpenSource") { if (accept == '3') licenseFile = orgLicenseFile + "/LICENSE.LGPLv3"; else -- cgit v1.2.3 From d2da14a9e05381eb3dd70071001dce72b2a465f3 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 22 May 2015 15:38:00 +0200 Subject: configure: Remove COMMERCIAL_VERSION define Not used anymore. Change-Id: I7db671008758e79598697e06e12f1b959bf479c6 Reviewed-by: Oswald Buddenhagen --- tools/configure/Makefile.mingw | 2 +- tools/configure/Makefile.win32 | 2 +- tools/configure/configure.pro | 2 -- tools/configure/configureapp.cpp | 14 +------------- 4 files changed, 3 insertions(+), 17 deletions(-) diff --git a/tools/configure/Makefile.mingw b/tools/configure/Makefile.mingw index 40c2112132..9ac99fd678 100644 --- a/tools/configure/Makefile.mingw +++ b/tools/configure/Makefile.mingw @@ -4,7 +4,7 @@ CONFSRC = $(TOOLSRC)/configure RAW_PCH = configure_pch.h PCH = $(RAW_PCH).gch/c++ -DEFINES = -DUNICODE -DQT_NO_DATASTREAM -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DCOMMERCIAL_VERSION +DEFINES = -DUNICODE -DQT_NO_DATASTREAM -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE INCPATH = -I"../../include" -I"../../include/QtCore" -I"../../include/QtCore/$(QTVERSION)" -I"../../include/QtCore/$(QTVERSION)/QtCore" -I"$(TOOLSRC)/shared" -I"$(QTSRC)mkspecs/win32-g++" CXXFLAGS_BARE = -fno-rtti -fno-exceptions -mthreads -Wall -Wextra $(DEFINES) $(INCPATH) CXXFLAGS = -include $(RAW_PCH) $(CXXFLAGS_BARE) diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32 index b74b0bc82d..8c6d213e42 100644 --- a/tools/configure/Makefile.win32 +++ b/tools/configure/Makefile.win32 @@ -3,7 +3,7 @@ TOOLSRC = $(QTSRC)tools CONFSRC = $(TOOLSRC)\configure PCH = configure_pch.pch -DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DCOMMERCIAL_VERSION +DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE INCPATH = -I"..\..\include" -I"..\..\include\QtCore" -I"..\..\include\QtCore\$(QTVERSION)" -I"..\..\include\QtCore\$(QTVERSION)\QtCore" -I"$(TOOLSRC)\shared" -I"$(QTSRC)mkspecs\win32-msvc2008" CXXFLAGS_BARE = -nologo -Zc:wchar_t -W3 -GR -EHsc -w34100 -w34189 $(CFLAGS_CRT) $(EXTRA_CXXFLAGS) $(DEFINES) $(INCPATH) CXXFLAGS = -FIconfigure_pch.h -Yuconfigure_pch.h -Fp$(PCH) -MP $(CXXFLAGS_BARE) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index d3237d472b..e4901bacde 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -132,5 +132,3 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/plugin/quuid.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qcryptographichash.cpp \ $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp - -DEFINES += COMMERCIAL_VERSION diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 10b33f41e4..faeb45417b 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -34,9 +34,7 @@ #include "configureapp.h" #include "environment.h" -#ifdef COMMERCIAL_VERSION -# include "tools.h" -#endif +#include "tools.h" #include #include @@ -4507,19 +4505,9 @@ void Configure::readLicense() cout << endl << "Cannot find the GPL license files! Please download the Open Source version of the library." << endl; dictionary["DONE"] = "error"; } -#ifdef COMMERCIAL_VERSION else { Tools::checkLicense(dictionary, sourcePath, buildPath); } -#else // !COMMERCIAL_VERSION - else { - cout << endl << "Error: This is the Open Source version of Qt." - << endl << "If you want to use Enterprise features of Qt," - << endl << "information use the contact form at http://www.qt.io/contact-us" - << endl << "to purchase a license." << endl << endl; - dictionary["DONE"] = "error"; - } -#endif } void Configure::reloadCmdLine() -- cgit v1.2.3 From 3311d92d8ed46426e19000d1e3b94029b9058983 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 13 May 2015 13:20:23 +0200 Subject: Fix failing input device notifications on embedded The connection to the deviceListChanged() signal may be queued. To make it work our custom types have to be registered. The problem is only visible with input backends like evdevtouch that live on their own thread. Task-number: QTBUG-46069 Change-Id: I4c03e8031e4337b5e711a3bd2cf405d15d6ce214 Reviewed-by: Gatis Paeglis --- src/gui/kernel/qinputdevicemanager.cpp | 1 + src/gui/kernel/qinputdevicemanager_p.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/gui/kernel/qinputdevicemanager.cpp b/src/gui/kernel/qinputdevicemanager.cpp index d0dd8a4e7c..dbdb03adbb 100644 --- a/src/gui/kernel/qinputdevicemanager.cpp +++ b/src/gui/kernel/qinputdevicemanager.cpp @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE QInputDeviceManager::QInputDeviceManager(QObject *parent) : QObject(*new QInputDeviceManagerPrivate, parent) { + qRegisterMetaType(); } int QInputDeviceManager::deviceCount(DeviceType type) const diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h index 15c84d1a82..d64793c23c 100644 --- a/src/gui/kernel/qinputdevicemanager_p.h +++ b/src/gui/kernel/qinputdevicemanager_p.h @@ -77,4 +77,6 @@ signals: QT_END_NAMESPACE +Q_DECLARE_METATYPE(QInputDeviceManager::DeviceType) + #endif // QINPUTDEVICEMANAGER_P_H -- cgit v1.2.3 From 43e82a3b094b8894b1cade6a6b871dd57aaa6c83 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 11 May 2015 13:53:37 +0200 Subject: QOpenGLWindow: initializeGL is to be called before resizeGL This involves deinlining some private class stuff to keep things readable and maintainable. Task-number: QTBUG-46002 Change-Id: Ie2888aa6c16a6f5182b61fbaa43288cfcc96cbc4 Reviewed-by: Gunnar Sletta --- src/gui/kernel/qopenglwindow.cpp | 245 +++++++++++++++++++++------------------ 1 file changed, 131 insertions(+), 114 deletions(-) diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index 7113345a75..b2025faaf1 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -175,141 +175,156 @@ public: this->shareContext = qt_gl_global_share_context(); } - ~QOpenGLWindowPrivate() - { - Q_Q(QOpenGLWindow); - if (q->isValid()) { - q->makeCurrent(); // this works even when the platformwindow is destroyed - paintDevice.reset(0); - fbo.reset(0); - blitter.destroy(); - q->doneCurrent(); - } - } + ~QOpenGLWindowPrivate(); static QOpenGLWindowPrivate *get(QOpenGLWindow *w) { return w->d_func(); } - void bindFBO() - { - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); - else - QOpenGLFramebufferObject::bindDefault(); + void bindFBO(); + void initialize(); + + void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; + void endPaint() Q_DECL_OVERRIDE; + void flush(const QRegion ®ion) Q_DECL_OVERRIDE; + + QOpenGLWindow::UpdateBehavior updateBehavior; + bool hasFboBlit; + QScopedPointer context; + QOpenGLContext *shareContext; + QScopedPointer fbo; + QScopedPointer paintDevice; + QOpenGLTextureBlitter blitter; + QColor backgroundColor; + QScopedPointer offscreenSurface; +}; + +QOpenGLWindowPrivate::~QOpenGLWindowPrivate() +{ + Q_Q(QOpenGLWindow); + if (q->isValid()) { + q->makeCurrent(); // this works even when the platformwindow is destroyed + paintDevice.reset(0); + fbo.reset(0); + blitter.destroy(); + q->doneCurrent(); } +} - void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE - { - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - - if (!context) { - context.reset(new QOpenGLContext); - context->setShareContext(shareContext); - context->setFormat(q->requestedFormat()); - context->setScreen(q->screen()); - if (!context->create()) - qWarning("QOpenGLWindow::beginPaint: Failed to create context"); - if (!context->makeCurrent(q)) - qWarning("QOpenGLWindow::beginPaint: Failed to make context current"); - - paintDevice.reset(new QOpenGLWindowPaintDevice(q)); - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) - hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); - - q->initializeGL(); - } else { - context->makeCurrent(q); - } +void QOpenGLWindowPrivate::initialize() +{ + Q_Q(QOpenGLWindow); - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - const QSize deviceSize(deviceWidth, deviceHeight); - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (!fbo || fbo->size() != deviceSize) { - QOpenGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - if (q->requestedFormat().samples() > 0) { - if (updateBehavior != QOpenGLWindow::PartialUpdateBlend) - fboFormat.setSamples(q->requestedFormat().samples()); - else - qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); - } - fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); - markWindowAsDirty(); + if (context) + return; + + context.reset(new QOpenGLContext); + context->setShareContext(shareContext); + context->setFormat(q->requestedFormat()); + if (!context->create()) + qWarning("QOpenGLWindow::beginPaint: Failed to create context"); + if (!context->makeCurrent(q)) + qWarning("QOpenGLWindow::beginPaint: Failed to make context current"); + + paintDevice.reset(new QOpenGLWindowPaintDevice(q)); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) + hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); + + q->initializeGL(); +} + +void QOpenGLWindowPrivate::beginPaint(const QRegion ®ion) +{ + Q_UNUSED(region); + Q_Q(QOpenGLWindow); + + initialize(); + context->makeCurrent(q); + + const int deviceWidth = q->width() * q->devicePixelRatio(); + const int deviceHeight = q->height() * q->devicePixelRatio(); + const QSize deviceSize(deviceWidth, deviceHeight); + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { + if (!fbo || fbo->size() != deviceSize) { + QOpenGLFramebufferObjectFormat fboFormat; + fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + if (q->requestedFormat().samples() > 0) { + if (updateBehavior != QOpenGLWindow::PartialUpdateBlend) + fboFormat.setSamples(q->requestedFormat().samples()); + else + qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); } - } else { + fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); markWindowAsDirty(); } + } else { + markWindowAsDirty(); + } - paintDevice->setSize(QSize(deviceWidth, deviceHeight)); - paintDevice->setDevicePixelRatio(q->devicePixelRatio()); - context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); + paintDevice->setSize(QSize(deviceWidth, deviceHeight)); + paintDevice->setDevicePixelRatio(q->devicePixelRatio()); + context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); + context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - q->paintUnderGL(); + q->paintUnderGL(); - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); - } + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->bind(); +} - void endPaint() Q_DECL_OVERRIDE - { - Q_Q(QOpenGLWindow); - - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->release(); - - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - QOpenGLExtensions extensions(context.data()); - extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle()); - extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject()); - extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, - 0, 0, deviceWidth, deviceHeight, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { - context->functions()->glEnable(GL_BLEND); - context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - if (!blitter.isCreated()) - blitter.create(); +void QOpenGLWindowPrivate::endPaint() +{ + Q_Q(QOpenGLWindow); + + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->release(); - QRect windowRect(QPoint(0, 0), fbo->size()); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); - blitter.bind(); - blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); - blitter.release(); + context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) - context->functions()->glDisable(GL_BLEND); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { + const int deviceWidth = q->width() * q->devicePixelRatio(); + const int deviceHeight = q->height() * q->devicePixelRatio(); + QOpenGLExtensions extensions(context.data()); + extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle()); + extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject()); + extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, + 0, 0, deviceWidth, deviceHeight, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { + if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { + context->functions()->glEnable(GL_BLEND); + context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } + if (!blitter.isCreated()) + blitter.create(); - q->paintOverGL(); - } + QRect windowRect(QPoint(0, 0), fbo->size()); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); + blitter.bind(); + blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); + blitter.release(); - void flush(const QRegion ®ion) Q_DECL_OVERRIDE - { - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - context->swapBuffers(q); - emit q->frameSwapped(); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) + context->functions()->glDisable(GL_BLEND); } - QOpenGLWindow::UpdateBehavior updateBehavior; - bool hasFboBlit; - QScopedPointer context; - QOpenGLContext *shareContext; - QScopedPointer fbo; - QScopedPointer paintDevice; - QOpenGLTextureBlitter blitter; - QColor backgroundColor; - QScopedPointer offscreenSurface; -}; + q->paintOverGL(); +} + +void QOpenGLWindowPrivate::bindFBO() +{ + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->bind(); + else + QOpenGLFramebufferObject::bindDefault(); +} + +void QOpenGLWindowPrivate::flush(const QRegion ®ion) +{ + Q_UNUSED(region); + Q_Q(QOpenGLWindow); + context->swapBuffers(q); + emit q->frameSwapped(); +} void QOpenGLWindowPaintDevice::ensureActiveTarget() { @@ -632,6 +647,8 @@ void QOpenGLWindow::paintEvent(QPaintEvent *event) void QOpenGLWindow::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); + Q_D(QOpenGLWindow); + d->initialize(); resizeGL(width(), height()); } -- cgit v1.2.3 From dd02c1eb38c6dfc8367f2c692e11897b6c00b097 Mon Sep 17 00:00:00 2001 From: Marko Kangas Date: Wed, 6 May 2015 13:51:04 +0300 Subject: Add support to disable close button from the tool window in Cocoa. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed regression from Qt4 that close button could't be disabled from the tool window. With this patch buttons are hidden before using button hints like it's on Windows. Change-Id: I00f03ff9528ccae3b1136312404452b9415953b4 Task-number: QTBUG-45971 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index cbe4227b63..86959869cc 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -799,9 +799,22 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) if (flags & Qt::FramelessWindowHint) return styleMask; if ((type & Qt::Popup) == Qt::Popup) { - if (!windowIsPopupType(type)) - styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSTitledWindowMask); + if (!windowIsPopupType(type)) { + styleMask = NSUtilityWindowMask; + if (!(flags & Qt::CustomizeWindowHint)) { + styleMask |= NSResizableWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSTitledWindowMask; + } else { + if (flags & Qt::WindowMaximizeButtonHint) + styleMask |= NSResizableWindowMask; + if (flags & Qt::WindowTitleHint) + styleMask |= NSTitledWindowMask; + if (flags & Qt::WindowCloseButtonHint) + styleMask |= NSClosableWindowMask; + if (flags & Qt::WindowMinimizeButtonHint) + styleMask |= NSMiniaturizableWindowMask; + } + } } else { if (type == Qt::Window && !(flags & Qt::CustomizeWindowHint)) { styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); -- cgit v1.2.3 From 765fea8dad269872a7fbb80a253367ac5e905259 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 27 May 2015 10:49:52 +0200 Subject: QtGui/Windows: Fix static build. qtbase\src\gui\kernel\qgenericpluginfactory.cpp:70: error: C2220: warning treated as error - no 'object' file generated qtbase\src\gui\kernel\qgenericpluginfactory.cpp:70: warning: C4100: 'specification' : unreferenced formal parameter Change-Id: I2dbb114fa9feaf862b4554b128caca0dcb5e291e Reviewed-by: Kai Koehne --- src/gui/kernel/qgenericpluginfactory.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qgenericpluginfactory.cpp b/src/gui/kernel/qgenericpluginfactory.cpp index 7e4727df8c..d7b9bfba06 100644 --- a/src/gui/kernel/qgenericpluginfactory.cpp +++ b/src/gui/kernel/qgenericpluginfactory.cpp @@ -69,13 +69,13 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, */ QObject *QGenericPluginFactory::create(const QString& key, const QString &specification) { +#if (!defined(Q_OS_WIN32) || defined(QT_SHARED)) && !defined(QT_NO_LIBRARY) const QString driver = key.toLower(); - -#if !defined(Q_OS_WIN32) || defined(QT_SHARED) -#ifndef QT_NO_LIBRARY if (QObject *object = qLoadPlugin1(loader(), driver, specification)) return object; -#endif +#else // (!Q_OS_WIN32 || QT_SHARED) && !QT_NO_LIBRARY + Q_UNUSED(key) + Q_UNUSED(specification) #endif return 0; } -- cgit v1.2.3 From e22d75d0b139fe9e4b11f32ebc5fb1024f493fbe Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 2 Jan 2015 10:09:21 +0100 Subject: Translate AM/PM under the QDateTimeParser context so it is consistent In order to ensure that the same text will be used in both QDateTimeParser and QDateTimeEdit, use the QDateTimeParser context for the AM and PM strings. Task-number: QTBUG-251 Change-Id: I89b0809825251181440bf19cbe5828024a43acfb Reviewed-by: Oswald Buddenhagen --- src/corelib/tools/qdatetimeparser.cpp | 14 +++++++------- src/corelib/tools/qdatetimeparser_p.h | 3 ++- src/widgets/widgets/qdatetimeedit.cpp | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 255e9557e2..eaa695ef27 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1362,11 +1362,11 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex \internal returns - 0 if str == QDateTimeEdit::tr("AM") - 1 if str == QDateTimeEdit::tr("PM") - 2 if str can become QDateTimeEdit::tr("AM") - 3 if str can become QDateTimeEdit::tr("PM") - 4 if str can become QDateTimeEdit::tr("PM") and can become QDateTimeEdit::tr("AM") + 0 if str == tr("AM") + 1 if str == tr("PM") + 2 if str can become tr("AM") + 3 if str can become tr("PM") + 4 if str can become tr("PM") and can become tr("AM") -1 can't become anything sensible */ @@ -1737,9 +1737,9 @@ QDateTime QDateTimeParser::getMaximum() const QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const { if (ap == AmText) { - return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am")); + return (cs == UpperCase ? tr("AM") : tr("am")); } else { - return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm")); + return (cs == UpperCase ? tr("PM") : tr("pm")); } } diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index 55dc3bf7a0..9457e35ad5 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -54,7 +54,7 @@ # include "QtCore/qvariant.h" #endif #include "QtCore/qvector.h" - +#include "QtCore/qcoreapplication.h" #define QDATETIMEEDIT_TIME_MIN QTime(0, 0, 0, 0) #define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999) @@ -72,6 +72,7 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QDateTimeParser { + Q_DECLARE_TR_FUNCTIONS(QDateTimeParser) public: enum Context { FromString, diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index b1749fa5d3..a8da78a025 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -2316,9 +2316,9 @@ void QDateTimeEdit::paintEvent(QPaintEvent *event) QString QDateTimeEditPrivate::getAmPmText(AmPm ap, Case cs) const { if (ap == AmText) { - return (cs == UpperCase ? QDateTimeEdit::tr("AM") : QDateTimeEdit::tr("am")); + return (cs == UpperCase ? QDateTimeParser::tr("AM") : QDateTimeParser::tr("am")); } else { - return (cs == UpperCase ? QDateTimeEdit::tr("PM") : QDateTimeEdit::tr("pm")); + return (cs == UpperCase ? QDateTimeParser::tr("PM") : QDateTimeParser::tr("pm")); } } -- cgit v1.2.3 From 347cc69cb2caa5f2f682bd213429394f4d668f4b Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 27 May 2015 12:57:58 +0300 Subject: ANGLE: fix DllMain collision in static builds The symbol is simply renamed in static builds, allowing wrappers of the library to still call the function if needed. Task-number: QTBUG-46209 Change-Id: I5d4ad2df59f206a3794b99364d122f9d0f12f8c6 Reviewed-by: Friedemann Kleint Reviewed-by: Tim Blechmann Reviewed-by: Kai Koehne --- src/angle/src/libGLESv2/libGLESv2.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro index 1bf9af0436..5979b68098 100644 --- a/src/angle/src/libGLESv2/libGLESv2.pro +++ b/src/angle/src/libGLESv2/libGLESv2.pro @@ -329,6 +329,8 @@ angle_d3d11 { !static { DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}.def mingw:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}_mingw32.def +} else { + DEFINES += DllMain=DllMain_ANGLE # prevent symbol from conflicting with the user's DllMain } float_converter.target = float_converter -- cgit v1.2.3 From 584576aeeefd9c0b53de6fd5fc83b3316dce7fd7 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 11 May 2015 15:17:12 +0200 Subject: ANGLE: Fix compilation without d3d11 Change-Id: I0b772698cf521083e5ecf35a395af57100a50131 Reviewed-by: Friedemann Kleint Reviewed-by: Andrew Knight --- .../src/libANGLE/renderer/d3d/d3d11/NativeWindow.h | 4 +- .../renderer/d3d/d3d11/win32/NativeWindow.cpp | 2 + .../0007-ANGLE-Fix-compilation-without-d3d11.patch | 57 ++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h index 81b9ea748d..0f70fe4615 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h @@ -38,7 +38,7 @@ class InspectableNativeWindow; using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; -#else +#elif defined(ANGLE_ENABLE_D3D11) typedef IDXGISwapChain DXGISwapChain; typedef IDXGIFactory DXGIFactory; #endif @@ -60,9 +60,11 @@ class NativeWindow #endif static bool isValidNativeWindow(EGLNativeWindowType window); +#if defined(ANGLE_ENABLE_D3D11) HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, DXGI_FORMAT format, UINT width, UINT height, DXGISwapChain** swapChain); +#endif inline EGLNativeWindowType getNativeWindow() const { return mWindow; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp index 9d8f0bb96c..0a4f45b5b7 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp @@ -37,6 +37,7 @@ bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window) return IsWindow(window) == TRUE; } +#if defined(ANGLE_ENABLE_D3D11) HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain** swapChain) @@ -65,4 +66,5 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory return factory->CreateSwapChain(device, &swapChainDesc, swapChain); } +#endif } diff --git a/src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch b/src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch new file mode 100644 index 0000000000..eca7d0e162 --- /dev/null +++ b/src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch @@ -0,0 +1,57 @@ +From 1f993a2492a618becd4bf89ef0d6cb5d2c9aa67a Mon Sep 17 00:00:00 2001 +From: Kai Koehne +Date: Mon, 11 May 2015 15:17:12 +0200 +Subject: [PATCH] ANGLE: Fix compilation without d3d11 + +Change-Id: I0b772698cf521083e5ecf35a395af57100a50131 +--- + src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h | 4 +++- + .../angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp | 2 ++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +index 81b9ea7..0f70fe4 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +@@ -38,7 +38,7 @@ class InspectableNativeWindow; + using namespace Microsoft::WRL; + using namespace Microsoft::WRL::Wrappers; + +-#else ++#elif defined(ANGLE_ENABLE_D3D11) + typedef IDXGISwapChain DXGISwapChain; + typedef IDXGIFactory DXGIFactory; + #endif +@@ -60,9 +60,11 @@ class NativeWindow + #endif + static bool isValidNativeWindow(EGLNativeWindowType window); + ++#if defined(ANGLE_ENABLE_D3D11) + HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, + DXGI_FORMAT format, UINT width, UINT height, + DXGISwapChain** swapChain); ++#endif + + inline EGLNativeWindowType getNativeWindow() const { return mWindow; } + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +index 9d8f0bb..0a4f45b 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +@@ -37,6 +37,7 @@ bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window) + return IsWindow(window) == TRUE; + } + ++#if defined(ANGLE_ENABLE_D3D11) + HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, + DXGI_FORMAT format, unsigned int width, unsigned int height, + DXGISwapChain** swapChain) +@@ -65,4 +66,5 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory + + return factory->CreateSwapChain(device, &swapChainDesc, swapChain); + } ++#endif + } +-- +1.9.5.msysgit.0 + -- cgit v1.2.3 From 5f2e4d3116593a566c03707d35c8a18b1e461855 Mon Sep 17 00:00:00 2001 From: Caner Altinbasak Date: Fri, 15 May 2015 22:06:02 +0100 Subject: Fix for eglfs context sharing problem in qtwebengine widget EGLFS backend does not use global sharing context. WebEngineWidgets was failing to access textures created by WebEngineChromium and textures were ending up as black rectangles. This fix initialises window surface context with shared context and fixes the bug. Change-Id: I97189c06ee593ba55f353f44c23233175ebd3cba Reviewed-by: Laszlo Agocs --- src/plugins/platforms/eglfs/qeglfswindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 30fdce9fd3..c0d51c94a5 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,7 @@ void QEglFSWindow::create() if (isRaster()) { QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance()); + context->setShareContext(qt_gl_global_share_context()); context->setFormat(m_format); context->setScreen(window()->screen()); if (!context->create()) -- cgit v1.2.3 From 22ecebcc72e418b6bf22562bd8a247261a7a4a37 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Mon, 18 May 2015 11:26:32 +0300 Subject: Add QMAKE_LIBDIR_EGL only if it exists Must not add -L without a directory path, so check that QMAKE_LIBDIR_EGL actually has a directory to add. Change-Id: I81920e3427f348739ced045a83f53265d72b261a Reviewed-by: Laszlo Agocs --- config.tests/qpa/eglfs-brcm/eglfs-brcm.pro | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro index b63c75c070..ce16a3a391 100644 --- a/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro +++ b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro @@ -4,4 +4,8 @@ CONFIG -= qt INCLUDEPATH += $$QMAKE_INCDIR_EGL -LIBS += -L$$QMAKE_LIBDIR_EGL -lEGL -lGLESv2 -lbcm_host +for(p, QMAKE_LIBDIR_EGL) { + exists($$p):LIBS += -L$$p +} + +LIBS += -lEGL -lGLESv2 -lbcm_host -- cgit v1.2.3 From bccdb62340659cfdf4e0f8b53180fb73fda6ea39 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Wed, 27 May 2015 15:12:54 +0300 Subject: Improve QHeaderView::sectionsInserted performance Old implementation had complexity O(oldSectionCount); replace it with O(hiddenSectionCount) algorithm. This boosts performance in case of the vertical headers for models with big row count. Change-Id: I7bb02f5579ce83fbdecf5f8c3aa7dcc0ac60dd40 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/itemviews/qheaderview.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 66ff472724..bca315f80b 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -1879,13 +1879,13 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent, // insert sections into hiddenSectionSize QHash newHiddenSectionSize; // from logical index to section size - for (int i = 0; i < logicalFirst; ++i) - if (isSectionHidden(i)) - newHiddenSectionSize[i] = d->hiddenSectionSize[i]; - for (int j = logicalLast + 1; j < d->sectionCount(); ++j) - if (isSectionHidden(j)) - newHiddenSectionSize[j] = d->hiddenSectionSize[j - insertCount]; - d->hiddenSectionSize = newHiddenSectionSize; + for (QHash::const_iterator it = d->hiddenSectionSize.cbegin(), + end = d->hiddenSectionSize.cend(); it != end; ++it) { + const int oldIndex = it.key(); + const int newIndex = (oldIndex < logicalFirst) ? oldIndex : oldIndex + insertCount; + newHiddenSectionSize[newIndex] = it.value(); + } + d->hiddenSectionSize.swap(newHiddenSectionSize); d->doDelayedResizeSections(); emit sectionCountChanged(oldCount, count()); -- cgit v1.2.3 From a47dbb010f2bf423a6f0a63bae6676a2788cdfdb Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 May 2015 16:12:57 +0200 Subject: windows: Use EGL extensions as they ought to be used We take some shortcuts still because we know that with ANGLE the header with the extension constants is always available. A proper implementation would not rely on the constants being available and would dynamically check for the extension and would take care of defining the constants if not available. However, just getting the extension list to check if the functions needed to get the display are available is already a chicken-egg problem so we won't go there. Using eglGetProcAddress properly solves the issues with static builds too since this always works. Task-number: QTBUG-46284 Change-Id: Iff23669ebacaffa0c5f76fd2c928af689307874f Reviewed-by: Friedemann Kleint Reviewed-by: Gunnar Roth Reviewed-by: Andrew Knight --- src/plugins/platforms/windows/qwindowseglcontext.cpp | 16 +++++++++++----- src/plugins/platforms/windows/qwindowseglcontext.h | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 0184877fdd..06c9985cac 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -39,7 +39,6 @@ #include #if defined(QT_OPENGL_ES_2_ANGLE) || defined(QT_OPENGL_DYNAMIC) -# define EGL_EGLEXT_PROTOTYPES # include #endif @@ -137,7 +136,6 @@ bool QWindowsLibEGL::init() eglGetError = RESOLVE((EGLint (EGLAPIENTRY *)(void)), eglGetError); eglGetDisplay = RESOLVE((EGLDisplay (EGLAPIENTRY *)(EGLNativeDisplayType)), eglGetDisplay); - eglGetPlatformDisplayEXT = RESOLVE((EGLDisplay (EGLAPIENTRY *)(EGLenum platform, void *native_display, const EGLint *attrib_list)), eglGetPlatformDisplayEXT); eglInitialize = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLint *, EGLint *)), eglInitialize); eglTerminate = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay)), eglTerminate); eglChooseConfig = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)), eglChooseConfig); @@ -156,7 +154,15 @@ bool QWindowsLibEGL::init() eglSwapBuffers = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface)), eglSwapBuffers); eglGetProcAddress = RESOLVE((__eglMustCastToProperFunctionPointerType (EGLAPIENTRY * )(const char *)), eglGetProcAddress); - return eglGetError && eglGetDisplay && eglInitialize; + if (!eglGetError || !eglGetDisplay || !eglInitialize || !eglGetProcAddress) + return false; + + eglGetPlatformDisplayEXT = 0; +#ifdef EGL_ANGLE_platform_angle + eglGetPlatformDisplayEXT = reinterpret_cast(eglGetProcAddress("eglGetPlatformDisplayEXT")); +#endif + + return true; } #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) @@ -360,7 +366,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: EGLDisplay display = EGL_NO_DISPLAY; EGLint major = 0; EGLint minor = 0; -#ifdef EGL_ANGLE_platform_angle_opengl +#ifdef EGL_ANGLE_platform_angle if (libEGL.eglGetPlatformDisplayEXT && (preferredType & QWindowsOpenGLTester::AngleBackendMask)) { const EGLint anglePlatformAttributes[][5] = { @@ -384,7 +390,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: } } } -#else // EGL_ANGLE_platform_angle_opengl +#else // EGL_ANGLE_platform_angle Q_UNUSED(preferredType) #endif if (display == EGL_NO_DISPLAY) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 2b249348c3..d8302c97a7 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -46,7 +46,6 @@ struct QWindowsLibEGL EGLint (EGLAPIENTRY * eglGetError)(void); EGLDisplay (EGLAPIENTRY * eglGetDisplay)(EGLNativeDisplayType display_id); - EGLDisplay (EGLAPIENTRY * eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list); EGLBoolean (EGLAPIENTRY * eglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor); EGLBoolean (EGLAPIENTRY * eglTerminate)(EGLDisplay dpy); EGLBoolean (EGLAPIENTRY * eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, @@ -74,6 +73,8 @@ struct QWindowsLibEGL EGLBoolean (EGLAPIENTRY * eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface); __eglMustCastToProperFunctionPointerType (EGLAPIENTRY * eglGetProcAddress)(const char *procname); + EGLDisplay (EGLAPIENTRY * eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list); + private: #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) void *resolve(const char *name); -- cgit v1.2.3 From 0a7fcfd61263bc156b780c5e48656c00c64721ed Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 28 May 2015 10:00:45 +0200 Subject: Windows: Fix font metrics of Vista style wizards. QVistaHelper::drawTitleBar() used the font returned by QApplication::font("QMdiSubWindowTitleBar") (typically "MS Shell Dlg 2",16) to calculate the bounding rectangle of the title text. However, if the window is a toplevel QVistaHelper::drawTitleText() uses the theme font obtained for WIZ_TMT_CAPTIONFONT (typically "Segoe UI",11.25) to draw the title (since it is a window title). This causes the font to be cropped when changing the application font or spurious black rectangles to occur. Fix this by exposing QWindowsFontDatabase::LOGFONT_to_QFont() via QWindowsNativeInterface, and creating a QFont from the LOGFONT obtained for WIZ_TMT_CAPTIONFONT and using that for the bounding rectangle in the case of toplevel windows. Split up the HFONT QVistaHelper::getCaptionFont(HANDLE hTheme) into static LOGFONT getCaptionLogFont(HANDLE hTheme) and use that to obtain the HFONT in drawTitleText() or QFont in static QFont getCaptionQFont(), respectively. Task-number: QTBUG-46360 Change-Id: I9069b403f7f948b6738eec452cb7584be45b8a29 Reviewed-by: Oliver Wolff --- .../platforms/windows/qwindowsnativeinterface.cpp | 6 +++ .../platforms/windows/qwindowsnativeinterface.h | 2 + src/widgets/dialogs/qwizard_win.cpp | 50 +++++++++++++++------- src/widgets/dialogs/qwizard_win_p.h | 1 - 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 9691156403..6e58c55bbe 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -34,6 +34,7 @@ #include "qwindowsnativeinterface.h" #include "qwindowswindow.h" #include "qwindowscontext.h" +#include "qwindowsfontdatabase.h" #include "qwindowsopenglcontext.h" #include "qwindowsopengltester.h" #include "qwindowsintegration.h" @@ -222,6 +223,11 @@ int QWindowsNativeInterface::registerMimeType(const QString &mimeType) return QWindowsMime::registerMimeType(mimeType); } +QFont QWindowsNativeInterface::logFontToQFont(const void *logFont, int verticalDpi) +{ + return QWindowsFontDatabase::LOGFONT_to_QFont(*reinterpret_cast(logFont), verticalDpi); +} + QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &function) const { if (function == QWindowsWindowFunctions::setTouchWindowTouchTypeIdentifier()) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index be8418b769..97839ae1ae 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -34,6 +34,7 @@ #ifndef QWINDOWSNATIVEINTERFACE_H #define QWINDOWSNATIVEINTERFACE_H +#include #include QT_BEGIN_NAMESPACE @@ -77,6 +78,7 @@ public: Q_INVOKABLE void registerWindowsMime(void *mimeIn); Q_INVOKABLE void unregisterWindowsMime(void *mime); Q_INVOKABLE int registerMimeType(const QString &mimeType); + Q_INVOKABLE QFont logFontToQFont(const void *logFont, int verticalDpi); bool asyncExpose() const; void setAsyncExpose(bool value); diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 701fea1c03..a4b37f360b 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -361,6 +361,36 @@ bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type) Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &); +static LOGFONT getCaptionLogFont(HANDLE hTheme) +{ + LOGFONT result = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } }; + + if (!hTheme || FAILED(pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &result))) { + NONCLIENTMETRICS ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false); + result = ncm.lfMessageFont; + } + return result; +} + +static bool getCaptionQFont(int dpi, QFont *result) +{ + if (!pOpenThemeData) + return false; + const HANDLE hTheme = + pOpenThemeData(QApplicationPrivate::getHWNDForWidget(QApplication::desktop()), L"WINDOW"); + if (!hTheme) + return false; + // Call into QWindowsNativeInterface to convert the LOGFONT into a QFont. + const LOGFONT logFont = getCaptionLogFont(hTheme); + QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); + return ni && QMetaObject::invokeMethod(ni, "logFontToQFont", Qt::DirectConnection, + Q_RETURN_ARG(QFont, *result), + Q_ARG(const void *, &logFont), + Q_ARG(int, dpi)); +} + void QVistaHelper::drawTitleBar(QPainter *painter) { Q_ASSERT(backButton_); @@ -378,7 +408,9 @@ void QVistaHelper::drawTitleBar(QPainter *painter) const int verticalCenter = (btnTop + btnHeight / 2) - 1; const QString text = wizard->window()->windowTitle(); - const QFont font = QApplication::font("QMdiSubWindowTitleBar"); + QFont font; + if (!isWindow || !getCaptionQFont(wizard->logicalDpiY() * wizard->devicePixelRatio(), &font)) + font = QApplication::font("QMdiSubWindowTitleBar"); const QFontMetrics fontMetrics(font); const QRect brect = fontMetrics.boundingRect(text); int textHeight = brect.height(); @@ -649,19 +681,6 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event) return false; } -HFONT QVistaHelper::getCaptionFont(HANDLE hTheme) -{ - LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } }; - - if (!hTheme || FAILED(pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &lf))) { - NONCLIENTMETRICS ncm; - ncm.cbSize = sizeof(NONCLIENTMETRICS); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false); - lf = ncm.lfMessageFont; - } - return CreateFontIndirect(&lf); -} - // Return a HDC for the wizard along with the transformation if the // wizard is a child window. HDC QVistaHelper::backingStoreDC(const QWidget *wizard, QPoint *offset) @@ -713,7 +732,8 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0); // Set up the DC - HFONT hCaptionFont = getCaptionFont(hTheme); + const LOGFONT captionLogFont = getCaptionLogFont(hTheme); + const HFONT hCaptionFont = CreateFontIndirect(&captionLogFont); HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp); HFONT hOldFont = (HFONT)SelectObject(dcMem, (HGDIOBJ) hCaptionFont); diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h index 8c36472bee..84b795d506 100644 --- a/src/widgets/dialogs/qwizard_win_p.h +++ b/src/widgets/dialogs/qwizard_win_p.h @@ -105,7 +105,6 @@ public: static HDC backingStoreDC(const QWidget *wizard, QPoint *offset); private: - static HFONT getCaptionFont(HANDLE hTheme); HWND wizardHWND() const; bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc); static bool drawBlackRect(const QRect &rect, HDC hdc); -- cgit v1.2.3 From f5d1c329ce9c2c81e3bf59017fb2cdd4261b5336 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 May 2015 15:00:00 +0200 Subject: Emphasize the need for calling setDefaultFormat early on OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-46067 Change-Id: I0fe6e7ba309306a8fc471424b30eed4491bd39e7 Reviewed-by: Topi Reiniö --- src/widgets/kernel/qopenglwidget.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index b8df25b38f..9bfdc62e60 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -104,6 +104,12 @@ QT_BEGIN_NAMESPACE non-sharable. To overcome this issue, prefer using QSurfaceFormat::setDefaultFormat() instead of setFormat(). + \note Calling QSurfaceFormat::setDefaultFormat() before constructing + the QApplication instance is mandatory on some platforms (for example, + OS X) when an OpenGL core profile context is requested. This is to + ensure that resource sharing between contexts stays functional as all + internal contexts are created using the correct version and profile. + \section1 Painting Techniques As described above, subclass QOpenGLWidget to render pure 3D content in the -- cgit v1.2.3 From 4964c895406b8316d15668affd32cc5eb7b6c7ea Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 29 May 2015 15:53:02 +0200 Subject: tst_QDockWidget::restoreDockWidget: Add QSKIP for XCB. The positioning test has been observed to fail on X11. Change-Id: I58727126a8742de93ec203e9992a9ae1b454f731 Reviewed-by: Simon Hausmann --- tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index ade9f72543..2bbc2e05b7 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -764,6 +764,8 @@ void tst_QDockWidget::restoreDockWidget() restoreWindow.show(); QVERIFY(QTest::qWaitForWindowExposed(&restoreWindow)); QTRY_VERIFY(dock->isFloating()); + if (!QGuiApplication::platformName().compare("xcb", Qt::CaseInsensitive)) + QSKIP("Skip due to Window manager positioning issues", Abort); QTRY_COMPARE(dock->pos(), dockPos); } } -- cgit v1.2.3 From 0c5befa129ad913c5934e72f19abbff553aee6da Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 May 2015 16:45:37 +0200 Subject: Reanimate test gui/kernel/qtouchevent/tst_qtouchevent. Add CONFIG += testcase to the .pro file which was missing. The test thus was never executed by make check and left to rot. Fix up code: - Remove module includes. - Introduce explicit constructors taking parent object for helper classes, removing calls to setParent(). - Ensure test does not leak objects by converting pointers to stack variables or introducing QScopedPointer, verify by checking for an empty window list in cleanup(). - Simplify code by removing unneeded variables. - Split up conditions in QVERIFY(). Fix tests: - Show windows were required when events are sent to QWidget::windowHandle(). - Invert the conditions checking whether touch events are accepted by widgets since widgets no longer accept them by defaults in Qt 5 after e50416066cab4be7df8382bd224d9e4ddd7a903a. - XFAIL multiPointRawEventTranslationOnTouchPad() which started to fail at some point in Qt 5. - Mark as insignificant on OS X due to crash. Task-number: QTBUG-46266 Change-Id: I6676d021afb015411a24d97d9b8f7c327d4d3c3f Reviewed-by: Simon Hausmann --- tests/auto/gui/kernel/qtouchevent/qtouchevent.pro | 2 + .../gui/kernel/qtouchevent/tst_qtouchevent.cpp | 314 ++++++++++----------- 2 files changed, 152 insertions(+), 164 deletions(-) diff --git a/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro b/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro index 7136611165..b1e3c10724 100644 --- a/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro +++ b/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro @@ -1,3 +1,5 @@ +CONFIG += testcase +osx: CONFIG += insignificant_test # QTBUG-46266, crashes SOURCES=tst_qtouchevent.cpp TARGET=tst_qtouchevent QT += testlib widgets gui-private diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index fe11f39242..dc35058f66 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -31,11 +31,16 @@ ** ****************************************************************************/ -#include -#include +#include +#include +#include +#include +#include +#include #include #include +// FIXME: Use static functions of QWindowSystemInterface introduced with HighDPI scaling in 5.6 instead. static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt) { QWindowSystemInterface::TouchPoint p; @@ -72,8 +77,7 @@ public: ulong timestamp; QTouchDevice *deviceFromEvent; - tst_QTouchEventWidget() - : QWidget() + explicit tst_QTouchEventWidget(QWidget *parent = Q_NULLPTR) : QWidget(parent) { reset(); } @@ -88,7 +92,7 @@ public: deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false; } - bool event(QEvent *event) + bool event(QEvent *event) Q_DECL_OVERRIDE { switch (event->type()) { case QEvent::TouchBegin: @@ -142,8 +146,8 @@ public: bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd; tst_QTouchEventGraphicsItem **weakpointer; - tst_QTouchEventGraphicsItem() - : QGraphicsItem(), weakpointer(0) + explicit tst_QTouchEventGraphicsItem(QGraphicsItem *parent = Q_NULLPTR) + : QGraphicsItem(parent), weakpointer(0) { reset(); } @@ -165,10 +169,10 @@ public: deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false; } - QRectF boundingRect() const { return QRectF(0, 0, 10, 10); } - void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) { } + QRectF boundingRect() const Q_DECL_OVERRIDE { return QRectF(0, 0, 10, 10); } + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) Q_DECL_OVERRIDE { } - bool sceneEvent(QEvent *event) + bool sceneEvent(QEvent *event) Q_DECL_OVERRIDE { switch (event->type()) { case QEvent::TouchBegin: @@ -214,9 +218,9 @@ class tst_QTouchEvent : public QObject Q_OBJECT public: tst_QTouchEvent(); - ~tst_QTouchEvent() { } private slots: + void cleanup(); void touchDisabledByDefault(); void touchEventAcceptedByDefault(); void touchBeginPropagatesWhenIgnored(); @@ -236,15 +240,18 @@ private: QTouchDevice *touchPadDevice; }; -tst_QTouchEvent::tst_QTouchEvent() +tst_QTouchEvent::tst_QTouchEvent() : touchScreenDevice(new QTouchDevice), touchPadDevice(new QTouchDevice) { - touchScreenDevice = new QTouchDevice; - touchPadDevice = new QTouchDevice; touchPadDevice->setType(QTouchDevice::TouchPad); QWindowSystemInterface::registerTouchDevice(touchScreenDevice); QWindowSystemInterface::registerTouchDevice(touchPadDevice); } +void tst_QTouchEvent::cleanup() +{ + QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); +} + void tst_QTouchEvent::touchDisabledByDefault() { // QWidget @@ -261,8 +268,7 @@ void tst_QTouchEvent::touchDisabledByDefault() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&widget, &touchEvent); - QVERIFY(!res); + QVERIFY(!QApplication::sendEvent(&widget, &touchEvent)); QVERIFY(!touchEvent.isAccepted()); } @@ -290,8 +296,7 @@ void tst_QTouchEvent::touchDisabledByDefault() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(!res); + QVERIFY(!QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(!touchEvent.isAccepted()); QVERIFY(!item.seenTouchBegin); } @@ -299,7 +304,7 @@ void tst_QTouchEvent::touchDisabledByDefault() void tst_QTouchEvent::touchEventAcceptedByDefault() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); // QWidget @@ -317,16 +322,14 @@ void tst_QTouchEvent::touchEventAcceptedByDefault() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&widget, &touchEvent); - QVERIFY(res); - QVERIFY(touchEvent.isAccepted()); + QVERIFY(QApplication::sendEvent(&widget, &touchEvent)); + QVERIFY(!touchEvent.isAccepted()); // Qt 5.X ignores touch events. // tst_QTouchEventWidget does handle, sending succeeds tst_QTouchEventWidget touchWidget; touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchEvent.ignore(); - res = QApplication::sendEvent(&touchWidget, &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&touchWidget, &touchEvent)); QVERIFY(touchEvent.isAccepted()); } @@ -355,8 +358,7 @@ void tst_QTouchEvent::touchEventAcceptedByDefault() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(item.seenTouchBegin); } @@ -383,8 +385,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&grandchild, &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -398,8 +399,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() grandchild.setAttribute(Qt::WA_AcceptTouchEvents, false); touchEvent.ignore(); - res = QApplication::sendEvent(&grandchild, &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(!grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -435,8 +435,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -471,8 +470,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(!grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -499,8 +497,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&child, &touchBeginEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&child, &touchBeginEvent)); QVERIFY(touchBeginEvent.isAccepted()); QVERIFY(child.seenTouchBegin); QVERIFY(!window.seenTouchBegin); @@ -511,8 +508,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointMoved, touchPoints); - res = QApplication::sendEvent(&child, &touchUpdateEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&child, &touchUpdateEvent)); QVERIFY(!touchUpdateEvent.isAccepted()); QVERIFY(child.seenTouchUpdate); QVERIFY(!window.seenTouchUpdate); @@ -523,8 +519,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - res = QApplication::sendEvent(&child, &touchEndEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&child, &touchEndEvent)); QVERIFY(!touchEndEvent.isAccepted()); QVERIFY(child.seenTouchEnd); QVERIFY(!window.seenTouchEnd); @@ -558,8 +553,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); QVERIFY(touchBeginEvent.isAccepted()); QVERIFY(child.seenTouchBegin); QVERIFY(!root.seenTouchBegin); @@ -571,8 +565,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointMoved, (QList() << touchPoint)); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); // the scene accepts the event, since it found an item to send the event to QVERIFY(!touchUpdateEvent.isAccepted()); QVERIFY(child.seenTouchUpdate); @@ -585,8 +578,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointReleased, (QList() << touchPoint)); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); // the scene accepts the event, since it found an item to send the event to QVERIFY(!touchEndEvent.isAccepted()); QVERIFY(child.seenTouchEnd); @@ -601,17 +593,20 @@ QPointF normalized(const QPointF &pos, const QRectF &rect) void tst_QTouchEvent::basicRawEventTranslation() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); QPointF pos = touchWidget.rect().center(); QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint()); QPointF delta(10, 10); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QTouchEvent::TouchPoint rawTouchPoint; rawTouchPoint.setId(0); @@ -726,24 +721,24 @@ void tst_QTouchEvent::basicRawEventTranslation() void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); - tst_QTouchEventWidget leftWidget; - leftWidget.setParent(&touchWidget); + tst_QTouchEventWidget leftWidget(&touchWidget); leftWidget.setAttribute(Qt::WA_AcceptTouchEvents); leftWidget.setGeometry(0, 100, 100, 100); - leftWidget.show(); - tst_QTouchEventWidget rightWidget; - rightWidget.setParent(&touchWidget); + tst_QTouchEventWidget rightWidget(&touchWidget); rightWidget.setAttribute(Qt::WA_AcceptTouchEvents); rightWidget.setGeometry(300, 100, 100, 100); - rightWidget.show(); + + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -751,8 +746,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint()); QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint()); QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint()); - QPointF delta(10, 10); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QList rawTouchPoints; rawTouchPoints.append(QTouchEvent::TouchPoint(0)); @@ -956,24 +950,25 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); - tst_QTouchEventWidget leftWidget; - leftWidget.setParent(&touchWidget); + tst_QTouchEventWidget leftWidget(&touchWidget); leftWidget.setAttribute(Qt::WA_AcceptTouchEvents); leftWidget.setGeometry(0, 100, 100, 100); - leftWidget.show(); + leftWidget.acceptTouchBegin =true; - tst_QTouchEventWidget rightWidget; - rightWidget.setParent(&touchWidget); + tst_QTouchEventWidget rightWidget(&touchWidget); rightWidget.setAttribute(Qt::WA_AcceptTouchEvents); rightWidget.setGeometry(300, 100, 100, 100); - rightWidget.show(); + + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -981,8 +976,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint()); QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint()); QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint()); - QPointF delta(10, 10); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QList rawTouchPoints; rawTouchPoints.append(QTouchEvent::TouchPoint(0)); @@ -1003,7 +997,8 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); QVERIFY(!touchWidget.seenTouchEnd); - QVERIFY(leftWidget.seenTouchBegin); + QEXPECT_FAIL("", "QTBUG-46266, fails in Qt 5", Abort); + QVERIFY(!leftWidget.seenTouchBegin); QVERIFY(!leftWidget.seenTouchUpdate); QVERIFY(!leftWidget.seenTouchEnd); QVERIFY(!rightWidget.seenTouchBegin); @@ -1186,19 +1181,15 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() void tst_QTouchEvent::deleteInEventHandler() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); // QWidget { QWidget window; - tst_QTouchEventWidget *child1, *child2, *child3; - child1 = new tst_QTouchEventWidget; - child2 = new tst_QTouchEventWidget; - child3 = new tst_QTouchEventWidget; - child1->setParent(&window); - child2->setParent(&window); - child3->setParent(&window); + QPointer child1 = new tst_QTouchEventWidget(&window); + QPointer child2 = new tst_QTouchEventWidget(&window); + QPointer child3 = new tst_QTouchEventWidget(&window); child1->setAttribute(Qt::WA_AcceptTouchEvents); child2->setAttribute(Qt::WA_AcceptTouchEvents); child3->setAttribute(Qt::WA_AcceptTouchEvents); @@ -1223,47 +1214,43 @@ void tst_QTouchEvent::deleteInEventHandler() Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - QPointer p; - bool res; - touchBeginEvent.ignore(); - p = child1; - res = QApplication::sendEvent(child1, &touchBeginEvent); + QVERIFY(QApplication::sendEvent(child1, &touchBeginEvent)); // event is handled, but widget should be deleted - QVERIFY(res && touchBeginEvent.isAccepted() && p.isNull()); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child1.isNull()); touchBeginEvent.ignore(); - p = child2; - res = QApplication::sendEvent(child2, &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull()); + QVERIFY(QApplication::sendEvent(child2, &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(!child2.isNull()); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(child2, &touchUpdateEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && p.isNull()); + QVERIFY(QApplication::sendEvent(child2, &touchUpdateEvent)); + QVERIFY(touchUpdateEvent.isAccepted()); + QVERIFY(child2.isNull()); touchBeginEvent.ignore(); - p = child3; - res = QApplication::sendEvent(child3, &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull()); + QVERIFY(QApplication::sendEvent(child3, &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(!child3.isNull()); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(child3, &touchUpdateEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && !p.isNull()); + QVERIFY(QApplication::sendEvent(child3, &touchUpdateEvent)); + QVERIFY(touchUpdateEvent.isAccepted()); + QVERIFY(!child3.isNull()); touchEndEvent.ignore(); - res = QApplication::sendEvent(child3, &touchEndEvent); - QVERIFY(res && touchEndEvent.isAccepted() && p.isNull()); + QVERIFY(QApplication::sendEvent(child3, &touchEndEvent)); + QVERIFY(touchEndEvent.isAccepted()); + QVERIFY(child3.isNull()); } // QGraphicsView { QGraphicsScene scene; QGraphicsView view(&scene); - tst_QTouchEventGraphicsItem *root, *child1, *child2, *child3; - root = new tst_QTouchEventGraphicsItem; - child1 = new tst_QTouchEventGraphicsItem; - child2 = new tst_QTouchEventGraphicsItem; - child3 = new tst_QTouchEventGraphicsItem; - child1->setParentItem(root); - child2->setParentItem(root); - child3->setParentItem(root); + QScopedPointer root(new tst_QTouchEventGraphicsItem); + tst_QTouchEventGraphicsItem *child1 = new tst_QTouchEventGraphicsItem(root.data()); + tst_QTouchEventGraphicsItem *child2 = new tst_QTouchEventGraphicsItem(root.data()); + tst_QTouchEventGraphicsItem *child3 = new tst_QTouchEventGraphicsItem(root.data()); child1->setZValue(1.); child2->setZValue(0.); child3->setZValue(-1.); @@ -1274,7 +1261,7 @@ void tst_QTouchEvent::deleteInEventHandler() child2->deleteInTouchUpdate = true; child3->deleteInTouchEnd = true; - scene.addItem(root); + scene.addItem(root.data()); view.resize(200, 200); view.fitInView(scene.sceneRect()); @@ -1302,71 +1289,75 @@ void tst_QTouchEvent::deleteInEventHandler() Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - bool res; child1->weakpointer = &child1; touchBeginEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && !child1); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(!child1); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && !child1); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); // Qt 5.X ignores touch events. + QVERIFY(!child1); touchEndEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && !child1); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(!child1); child2->weakpointer = &child2; touchBeginEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && child2); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child2); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(!child2); touchEndEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(!child2); child3->weakpointer = &child3; - res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && child3); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res && !touchUpdateEvent.isAccepted() && child3); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res && !touchEndEvent.isAccepted() && !child3); - - delete root; + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child3); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(child3); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); + QVERIFY(!touchEndEvent.isAccepted()); + QVERIFY(!child3); } } void tst_QTouchEvent::deleteInRawEventTranslation() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 300, 300); - tst_QTouchEventWidget *leftWidget = new tst_QTouchEventWidget; - leftWidget->setParent(&touchWidget); + QPointer leftWidget = new tst_QTouchEventWidget(&touchWidget); leftWidget->setAttribute(Qt::WA_AcceptTouchEvents); leftWidget->setGeometry(0, 100, 100, 100); leftWidget->deleteInTouchBegin = true; - leftWidget->show(); - tst_QTouchEventWidget *centerWidget = new tst_QTouchEventWidget; - centerWidget->setParent(&touchWidget); + QPointer centerWidget = new tst_QTouchEventWidget(&touchWidget); centerWidget->setAttribute(Qt::WA_AcceptTouchEvents); centerWidget->setGeometry(100, 100, 100, 100); centerWidget->deleteInTouchUpdate = true; - centerWidget->show(); - tst_QTouchEventWidget *rightWidget = new tst_QTouchEventWidget; - rightWidget->setParent(&touchWidget); + QPointer rightWidget = new tst_QTouchEventWidget(&touchWidget); rightWidget->setAttribute(Qt::WA_AcceptTouchEvents); rightWidget->setGeometry(200, 100, 100, 100); rightWidget->deleteInTouchEnd = true; - rightWidget->show(); + + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); QPointF leftPos = leftWidget->rect().center(); QPointF centerPos = centerWidget->rect().center(); @@ -1374,9 +1365,7 @@ void tst_QTouchEvent::deleteInRawEventTranslation() QPointF leftScreenPos = leftWidget->mapToGlobal(leftPos.toPoint()); QPointF centerScreenPos = centerWidget->mapToGlobal(centerPos.toPoint()); QPointF rightScreenPos = rightWidget->mapToGlobal(rightPos.toPoint()); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); - - QPointer pl = leftWidget, pc = centerWidget, pr = rightWidget; + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QList rawTouchPoints; rawTouchPoints.append(QTouchEvent::TouchPoint(0)); @@ -1398,7 +1387,9 @@ void tst_QTouchEvent::deleteInRawEventTranslation() touchScreenDevice, touchPointList(rawTouchPoints)); QCoreApplication::processEvents(); - QVERIFY(pl.isNull() && !pc.isNull() && !pr.isNull()); + QVERIFY(leftWidget.isNull()); + QVERIFY(!centerWidget.isNull()); + QVERIFY(!rightWidget.isNull()); // generate update events on all widget, the center widget should die rawTouchPoints[0].setState(Qt::TouchPointMoved); @@ -1455,14 +1446,13 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() { QGraphicsScene scene; QGraphicsView view(&scene); - tst_QTouchEventGraphicsItem *root; - root = new tst_QTouchEventGraphicsItem; + QScopedPointer root(new tst_QTouchEventGraphicsItem); root->setAcceptTouchEvents(true); - scene.addItem(root); + scene.addItem(root.data()); - QGraphicsWidget *glassWidget = new QGraphicsWidget; + QScopedPointer glassWidget(new QGraphicsWidget); glassWidget->setMinimumSize(100, 100); - scene.addItem(glassWidget); + scene.addItem(glassWidget.data()); view.resize(200, 200); view.show(); @@ -1498,17 +1488,13 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() QCOMPARE(root->touchBeginCounter, 0); QCOMPARE(root->touchUpdateCounter, 0); QCOMPARE(root->touchEndCounter, 0); - - - delete root; - delete glassWidget; } class WindowTouchEventFilter : public QObject { Q_OBJECT public: - bool eventFilter(QObject *obj, QEvent *event); + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; struct TouchInfo { QList points; QEvent::Type lastSeenType; @@ -1537,18 +1523,18 @@ void tst_QTouchEvent::testQGuiAppDelivery() device->setType(QTouchDevice::TouchScreen); QWindowSystemInterface::registerTouchDevice(device); - QWindow *w = new QWindow; - w->setGeometry(100, 100, 100, 100); - w->show(); - QVERIFY(QTest::qWaitForWindowExposed(w)); + QWindow w; + w.setGeometry(100, 100, 100, 100); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); WindowTouchEventFilter filter; - w->installEventFilter(&filter); + w.installEventFilter(&filter); QList points; // Pass empty list, should be ignored. - QWindowSystemInterface::handleTouchEvent(w, 0, points); + QWindowSystemInterface::handleTouchEvent(&w, 0, points); QCoreApplication::processEvents(); QCOMPARE(filter.d.isEmpty(), true); @@ -1559,12 +1545,12 @@ void tst_QTouchEvent::testQGuiAppDelivery() points.append(tp); // Pass 0 as device, should be ignored. - QWindowSystemInterface::handleTouchEvent(w, 0, points); + QWindowSystemInterface::handleTouchEvent(&w, 0, points); QCoreApplication::processEvents(); QCOMPARE(filter.d.isEmpty(), true); // Now the real thing. - QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchBegin + QWindowSystemInterface::handleTouchEvent(&w, device, points); // TouchBegin QCoreApplication::processEvents(); QCOMPARE(filter.d.count(), 1); QCOMPARE(filter.d.contains(device), true); @@ -1572,7 +1558,7 @@ void tst_QTouchEvent::testQGuiAppDelivery() QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchBegin); points[0].state = Qt::TouchPointMoved; - QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchUpdate + QWindowSystemInterface::handleTouchEvent(&w, device, points); // TouchUpdate QCoreApplication::processEvents(); QCOMPARE(filter.d.count(), 1); QCOMPARE(filter.d.contains(device), true); @@ -1580,7 +1566,7 @@ void tst_QTouchEvent::testQGuiAppDelivery() QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchUpdate); points[0].state = Qt::TouchPointReleased; - QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchEnd + QWindowSystemInterface::handleTouchEvent(&w, device, points); // TouchEnd QCoreApplication::processEvents(); QCOMPARE(filter.d.count(), 1); QCOMPARE(filter.d.contains(device), true); @@ -1597,13 +1583,13 @@ void tst_QTouchEvent::testMultiDevice() deviceTwo->setType(QTouchDevice::TouchScreen); QWindowSystemInterface::registerTouchDevice(deviceTwo); - QWindow *w = new QWindow; - w->setGeometry(100, 100, 100, 100); - w->show(); - QVERIFY(QTest::qWaitForWindowExposed(w)); + QWindow w; + w.setGeometry(100, 100, 100, 100); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); WindowTouchEventFilter filter; - w->installEventFilter(&filter); + w.installEventFilter(&filter); QList pointsOne, pointsTwo; @@ -1620,8 +1606,8 @@ void tst_QTouchEvent::testMultiDevice() tp.area = QRectF(140, 140, 20, 20); pointsTwo.append(tp); - QWindowSystemInterface::handleTouchEvent(w, deviceOne, pointsOne); - QWindowSystemInterface::handleTouchEvent(w, deviceTwo, pointsTwo); + QWindowSystemInterface::handleTouchEvent(&w, deviceOne, pointsOne); + QWindowSystemInterface::handleTouchEvent(&w, deviceTwo, pointsTwo); QCoreApplication::processEvents(); QCOMPARE(filter.d.contains(deviceOne), true); -- cgit v1.2.3 From a7a0b741c57e0990373f18b7862799e5f6f032b7 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 12 May 2015 17:01:22 +0200 Subject: Remove unused call indirection The global variable is a left over from when there was an MMX assembler implementation, and is now just making the compiler's job harder. Change-Id: I686704b64a2f8c68ec8ca83f2ac3e465ded773e0 Reviewed-by: Konstantin Ritt Reviewed-by: Gunnar Sletta Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/painting/qimagescale.cpp | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 5f1b25e189..84b574dd34 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -38,22 +38,6 @@ QT_BEGIN_NAMESPACE -typedef void (*qt_qimageScaleFunc)(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -static void qt_qimageScaleAARGB(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -static void qt_qimageScaleAARGBA(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -qt_qimageScaleFunc qt_qimageScaleArgb = qt_qimageScaleAARGBA; -qt_qimageScaleFunc qt_qimageScaleRgb = qt_qimageScaleAARGB; - - /* * Copyright (C) 2004, 2005 Daniel M. Duley * @@ -794,11 +778,11 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh) } if (src.hasAlphaChannel()) - qt_qimageScaleArgb(scaleinfo, (unsigned int *)buffer.scanLine(0), - 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); + qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), + 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); else - qt_qimageScaleRgb(scaleinfo, (unsigned int *)buffer.scanLine(0), - 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); + qt_qimageScaleAARGB(scaleinfo, (unsigned int *)buffer.scanLine(0), + 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); qimageFreeScaleInfo(scaleinfo); return buffer; -- cgit v1.2.3 From 455653d77f274ffd16e7fa3198ef719162a26a71 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 12 May 2015 17:07:25 +0200 Subject: Combine x and y oriented sample helpers The range sampling operates the same in both directions just with different step-sizes, so the code can be unduplicated, Change-Id: I47805a7e925d4058f62c558ef08e79485915e937 Reviewed-by: Gunnar Sletta --- src/gui/painting/qimagescale.cpp | 136 +++++++++++----------------------- src/gui/painting/qimagescale_sse4.cpp | 42 ++++------- 2 files changed, 58 insertions(+), 120 deletions(-) diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 84b574dd34..9b4eabc552 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -99,13 +99,6 @@ using namespace QImageScale; // Code ported from Imlib... // -// FIXME: replace with qRed, etc... These work on pointers to pixels, not -// pixel values -#define A_VAL(p) (qAlpha(*p)) -#define R_VAL(p) (qRed(*p)) -#define G_VAL(p) (qGreen(*p)) -#define B_VAL(p) (qBlue(*p)) - const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh) { @@ -365,46 +358,25 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, } } -inline static void qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b, int &a) +inline static void qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b, int &a) { - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; - a = A_VAL(pix) * xap; + r = qRed(*pix) * xyap; + g = qGreen(*pix) * xyap; + b = qBlue(*pix) * xyap; + a = qAlpha(*pix) * xyap; int j; - for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ - pix++; - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - a += A_VAL(pix) * Cx; - } - pix++; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; -} - -inline static void qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b, int &a) -{ - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - a = A_VAL(pix) * yap; - int j; - for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ - pix += sow; - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - a += A_VAL(pix) * Cy; - } - pix += sow; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; + for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) { + pix += step; + r += qRed(*pix) * Cxy; + g += qGreen(*pix) * Cxy; + b += qBlue(*pix) * Cxy; + a += qAlpha(*pix) * Cxy; + } + pix += step; + r += qRed(*pix) * j; + g += qGreen(*pix) * j; + b += qBlue(*pix) * j; + a += qAlpha(*pix) * j; } static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, @@ -427,12 +399,12 @@ static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b, a; - qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, r, g, b, a); + qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, r, g, b, a); int xap = xapoints[x]; if (xap > 0) { int rr, gg, bb, aa; - qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb, aa); + qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa); r = r * (256 - xap); g = g * (256 - xap); @@ -468,12 +440,12 @@ static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b, a; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, r, g, b, a); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, r, g, b, a); int yap = yapoints[dyy + y]; if (yap > 0) { int rr, gg, bb, aa; - qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, rr, gg, bb, aa); + qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa); r = r * (256 - yap); g = g * (256 - yap); @@ -512,7 +484,7 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int rx, gx, bx, ax; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); int r = ((rx>>4) * yap); int g = ((gx>>4) * yap); @@ -522,14 +494,14 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); r += ((rx>>4) * Cy); g += ((gx>>4) * Cy); b += ((bx>>4) * Cy); a += ((ax>>4) * Cy); } sptr += sow; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); r += ((rx>>4) * j); g += ((gx>>4) * j); @@ -593,40 +565,22 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, } -inline static void qt_qimageScaleAARGB_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b) +inline static void qt_qimageScaleAARGB_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b) { - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; + r = qRed(*pix) * xyap; + g = qGreen(*pix) * xyap; + b = qBlue(*pix) * xyap; int j; - for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ - pix++; - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - } - pix++; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; -} - -inline static void qt_qimageScaleAARGB_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b) -{ - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - int j; - for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ - pix += sow; - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - } - pix += sow; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; + for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) { + pix += step; + r += qRed(*pix) * Cxy; + g += qGreen(*pix) * Cxy; + b += qBlue(*pix) * Cxy; + } + pix += step; + r += qRed(*pix) * j; + g += qGreen(*pix) * j; + b += qBlue(*pix) * j; } static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, @@ -649,12 +603,12 @@ static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int * for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b; - qt_qimageScaleAARGB_helper_y(sptr, yap, Cy, sow, r, g, b); + qt_qimageScaleAARGB_helper(sptr, yap, Cy, sow, r, g, b); int xap = xapoints[x]; if (xap > 0) { int rr, bb, gg; - qt_qimageScaleAARGB_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb); + qt_qimageScaleAARGB_helper(sptr + 1, yap, Cy, sow, rr, gg, bb); r = r * (256 - xap); g = g * (256 - xap); @@ -688,12 +642,12 @@ static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int * const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, r, g, b); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, r, g, b); int yap = yapoints[dyy + y]; if (yap > 0) { int rr, bb, gg; - qt_qimageScaleAARGB_helper_x(sptr + sow, xap, Cx, rr, gg, bb); + qt_qimageScaleAARGB_helper(sptr + sow, xap, Cx, 1, rr, gg, bb); r = r * (256 - yap); g = g * (256 - yap); @@ -729,7 +683,7 @@ static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int rx, gx, bx; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); int r = (rx >> 4) * yap; int g = (gx >> 4) * yap; @@ -738,14 +692,14 @@ static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); r += (rx >> 4) * Cy; g += (gx >> 4) * Cy; b += (bx >> 4) * Cy; } sptr += sow; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); r += (rx >> 4) * j; g += (gx >> 4) * j; diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp index 565ea4daa1..303e0fd980 100644 --- a/src/gui/painting/qimagescale_sse4.cpp +++ b/src/gui/painting/qimagescale_sse4.cpp @@ -41,33 +41,17 @@ QT_BEGIN_NAMESPACE using namespace QImageScale; -inline static __m128i qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, const __m128i vxap, const __m128i vCx) +inline static __m128i qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, const __m128i vxyap, const __m128i vCxy) { __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - __m128i vx = _mm_mullo_epi32(vpix, vxap); + __m128i vx = _mm_mullo_epi32(vpix, vxyap); int i; - for (i = (1 << 14) - xap; i > Cx; i -= Cx) { - pix++; + for (i = (1 << 14) - xyap; i > Cxy; i -= Cxy) { + pix += step; vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCx)); + vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCxy)); } - pix++; - vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); - return vx; -} - -inline static __m128i qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, const __m128i vyap, const __m128i vCy) -{ - __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - __m128i vx = _mm_mullo_epi32(vpix, vyap); - int i; - for (i = (1 << 14) - yap; i > Cy; i -= Cy) { - pix += sow; - vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCy)); - } - pix += sow; + pix += step; vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); return vx; @@ -97,13 +81,13 @@ void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *d unsigned int *dptr = dest + dx + ((y + dy) * dow); for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, vyap, vCy); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, vyap, vCy); int xap = xapoints[x]; if (xap > 0) { const __m128i vxap = _mm_set1_epi32(xap); const __m128i vinvxap = _mm_sub_epi32(v256, vxap); - __m128i vr = qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, vyap, vCy); + __m128i vr = qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow, vyap, vCy); vx = _mm_mullo_epi32(vx, vinvxap); vr = _mm_mullo_epi32(vr, vxap); @@ -145,13 +129,13 @@ void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *d const __m128i vxap = _mm_set1_epi32(xap); const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); int yap = yapoints[dyy + y]; if (yap > 0) { const __m128i vyap = _mm_set1_epi32(yap); const __m128i vinvyap = _mm_sub_epi32(v256, vyap); - __m128i vr = qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, vxap, vCx); + __m128i vr = qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, vxap, vCx); vx = _mm_mullo_epi32(vx, vinvyap); vr = _mm_mullo_epi32(vr, vyap); @@ -194,17 +178,17 @@ void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest, const __m128i vxap = _mm_set1_epi32(xap); const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); __m128i vr = _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vyap); int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vCy)); } sptr += sow; - vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), _mm_set1_epi32(j))); vr = _mm_srli_epi32(vr, 24); -- cgit v1.2.3 From 5b739a5b8cfbbedd9265b192d08b346d9b265590 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 29 May 2015 12:21:21 +0200 Subject: Revert "Android: Don't show translucent system UI on top of Qt" This reverts commit c9aaa3e2cde5ffe5edaa4f17f84020d82609b7e9. This fix broke fullscreen mode on Android. A better solution is in the works, but we'll probably push that to Qt 5.5.1 instead since it comes with a risk and we don't want to delay the release any further. Change-Id: I3aae6d52ebb8425089cdb6f7fc4c8ce9ad4911df Task-number: QTBUG-38700 Task-number: QTBUG-46234 Reviewed-by: BogDan Vatra --- .../qtproject/qt5/android/QtActivityDelegate.java | 25 +--------------------- src/android/templates/AndroidManifest.xml | 4 ---- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 73140839cc..d6cd49f44c 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -65,7 +65,6 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; -import android.widget.LinearLayout; import java.io.BufferedReader; import java.io.DataOutputStream; @@ -789,29 +788,7 @@ public class QtActivityDelegate 0, 0, metrics.xdpi, metrics.ydpi, metrics.scaledDensity); } - - ViewGroup layout = null; m_layout = new QtLayout(m_activity); - if (Build.VERSION.SDK_INT >= 14) { - try { - ActivityInfo activityInfo = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), - PackageManager.GET_META_DATA); - if (activityInfo.metaData == null - || !activityInfo.metaData.containsKey("android.app.allow_overlapping_system_ui") - || !activityInfo.metaData.getBoolean("android.app.allow_overlapping_system_ui")) { - layout = new LinearLayout(m_activity); - layout.setFitsSystemWindows(true); - layout.addView(m_layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (layout == null) - layout = m_layout; - m_editText = new QtEditText(m_activity, this); m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE); m_surfaces = new HashMap(); @@ -834,7 +811,7 @@ public class QtActivityDelegate Log.w("Qt A11y", "Unknown exception: " + e.toString()); } - m_activity.setContentView(layout, + m_activity.setContentView(m_layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 779612cdaf..60c612976f 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -44,10 +44,6 @@ signal is sent! --> - - - - -- cgit v1.2.3 From 71c85c554a49ed3a17167e436630ddaff2b9fcb1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 29 May 2015 12:39:24 +0200 Subject: moc: Fix crash parsing invalid macro invocation When invoking a macro with less argument than it expect, we would crash trying to access the vector of arguments from the invocation as we are trying to substitute an argument. (Note that we do not show an error in case of argument mismatch because ithat might happen parsing valid code as moc's c++ parser is not 100% accurate (that was QTBUG-29331)) Task-number: QTBUG-46210 Change-Id: I3f08d7f5049e593a5bdc02a594ea63cadf66e7a4 Reviewed-by: Gabriel de Dietrich --- src/tools/moc/preprocessor.cpp | 8 +++++--- tests/auto/tools/moc/tst_moc.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 51873033c7..f253c49995 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -661,8 +661,10 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym expansion += s; } } else if (mode == Hash) { - if (index < 0) + if (index < 0 || index >= arguments.size()) { that->error("'#' is not followed by a macro parameter"); + continue; + } const Symbols &arg = arguments.at(index); QByteArray stringified; @@ -681,7 +683,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym expansion.pop_back(); Symbol next = s; - if (index >= 0) { + if (index >= 0 && index < arguments.size()) { const Symbols &arg = arguments.at(index); if (arg.size() == 0) { mode = Normal; @@ -703,7 +705,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym expansion += next; } - if (index >= 0) { + if (index >= 0 && index < arguments.size()) { const Symbols &arg = arguments.at(index); for (int i = 1; i < arg.size(); ++i) expansion += arg.at(i); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 8bef678af9..350c6142d2 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1882,6 +1882,13 @@ void tst_Moc::warnings_data() << 1 << QString() << QString("standard input:5: Error: Class declaration lacks Q_OBJECT macro."); + + QTest::newRow("QTBUG-46210: crash on invalid macro") + << QByteArray("#define Foo(a, b, c) a b c #a #b #c a##b##c #d\n Foo(45);") + << QStringList() + << 1 + << QString("IGNORE_ALL_STDOUT") + << QString(":2: Error: '#' is not followed by a macro parameter"); } void tst_Moc::warnings() -- cgit v1.2.3 From 45751d0ea3c4325f8f8c33969015763b5b897e77 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 18 May 2015 10:52:06 +0200 Subject: Fix combobox regression 5.4 -> 5.5 To avoid a touch release outside the combobox triggering the popup, a check was added that the combobox was hit. This fails if the combox itself is only used for the popup and associated behavior, but does not exist as widget. This patch changes the check so that only touch release checks for a hit, but a generic click still behaves as in 5.4 to avoid regressions. This fixes comboboxes no longer working in QtWebKit, since QtWebKit renders its own comboxes in webpages, and only uses the popup of the QComboBox. Task-number: QTBUG-46152 Change-Id: I74fd57b2e42e77aa4a269d812ca4a6689f254889 Reviewed-by: Florian Bruhin Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qcombobox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 76f923904d..ef80e359df 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -3034,7 +3034,7 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e) QStyle::SubControl sc = q->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, e->pos(), q); if (e->button() == Qt::LeftButton - && sc != QStyle::SC_None + && !(sc == QStyle::SC_None && e->type() == QEvent::MouseButtonRelease) && (sc == QStyle::SC_ComboBoxArrow || !q->isEditable()) && !viewContainer()->isVisible()) { if (sc == QStyle::SC_ComboBoxArrow) -- cgit v1.2.3 From 218e6cc6c9b4d4c54dce74ee5a65bb44c9f93b11 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 29 May 2015 12:48:33 +0200 Subject: Fix subpixel rendered text in QGLWidget Subpixel rendered text doesn't work in the old OpenGL paint engine because it assumes the glyphs are returned in RGB32 format, when they may be in ARGB32. This patch changes the test of the returned format to just check for 32bit matching the logic in the new OpenGL paint engine. Change-Id: Ib5b784dedba51cf22f216e2f035361518610b96b Reviewed-by: Laszlo Agocs --- src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 637c375311..9a1ae6e008 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -304,19 +304,23 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub for (int x = 0; x < maskWidth; ++x) src[x] = -src[x]; // convert 0 and 1 into 0 and 255 } - } else if (mask.format() == QImage::Format_RGB32) { + } else if (mask.depth() == 32) { // Make the alpha component equal to the average of the RGB values. // This is needed when drawing sub-pixel antialiased text on translucent targets. for (int y = 0; y < maskHeight; ++y) { quint32 *src = (quint32 *) mask.scanLine(y); for (int x = 0; x < maskWidth; ++x) { - uchar r = src[x] >> 16; - uchar g = src[x] >> 8; - uchar b = src[x]; - quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. + int r = qRed(src[x]); + int g = qGreen(src[x]); + int b = qBlue(src[x]); + int avg; + if (mask.format() == QImage::Format_RGB32) + avg = (r + g + b + 1) / 3; // "+1" for rounding. + else // Format_ARGB_Premultiplied + avg = qAlpha(src[x]); if (ctx->contextHandle()->isOpenGLES()) { // swizzle the bits to accommodate for the GL_RGBA upload. - src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16); + src[x] = (avg << 24) | (r << 0) | (g << 8) | (b << 16); } else { src[x] = (src[x] & 0x00ffffff) | (avg << 24); } @@ -325,7 +329,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub } funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - if (mask.format() == QImage::Format_RGB32) { + if (mask.depth() == 32) { GLenum format = GL_RGBA; #if !defined(QT_OPENGL_ES_2) if (!ctx->contextHandle()->isOpenGLES()) -- cgit v1.2.3 From 2d7004c58752eda813496fcf8a7d2582e956ba5e Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 29 May 2015 10:26:03 +0200 Subject: configure: Show only LGPLv3 for WinRT & WinCE With Qt 5.5 we are changing the license of the Qt for the WinRT & WinCE ports to LGPLv3 / GPLv2+ / commercial. Change-Id: I221559c5c42b1dcda172eb85e6bfa53c91976b23 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index faeb45417b..3bf0546ac1 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -4388,7 +4388,9 @@ bool Configure::showLicense(QString orgLicenseFile) QString licenseFile = orgLicenseFile; QString theLicense; if (dictionary["EDITION"] == "OpenSource") { - if (platform() != ANDROID || dictionary["ANDROID_STYLE_ASSETS"] == "no") { + if (platform() != WINDOWS_RT + && platform() != WINDOWS_CE + && (platform() != ANDROID || dictionary["ANDROID_STYLE_ASSETS"] == "no")) { theLicense = "GNU Lesser General Public License (LGPL) version 2.1" "\nor the GNU Lesser General Public License (LGPL) version 3"; } else { -- cgit v1.2.3 From 53d289ec4c0f512a3475da4bbf1f940cd6838ace Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 27 Mar 2015 11:51:02 +0100 Subject: xcb: Use XIGrabDevice instead of xcb_grab_pointer with XI 2.2 Switch to using the pointer events from XI2 when touch is available (i.e. version is >= 2.2). This allows us to select and grab the button and motion events together with the touch ones. This prevents the issue of not getting touch events when grabbing via the plain xcb functions. To prevent touch sequences from being replayed after ungrabbing (for example after dismissing a popup that caused a grab), we try to accept touches via XIAllowTouchEvents. Unfortunately this leads to a deadlock and therefore we can only do it when we know we have a new enough libXi. This is a configure time check which is not ideal since the system on which apps run can have a newer libXi than the machine that did the Qt build, but seems like the best we can do. The environment variable QT_XCB_NO_XI2_MOUSE can be set to 1 in order to prevent processing mouse events through XInput. This restores the old behavior with broken grabbing. [ChangeLog][QtGui] Pointer event delivery on X11 is now done via XInput 2.2+ when available. Done-with: Michal Klocek Done-with: Alexander Volkov Task-number: QTBUG-43525 Task-number: QTBUG-45054 Task-number: QTBUG-30417 Change-Id: I7cb2002b31bef4cd527aa427549dcf2d5467968e Reviewed-by: Laszlo Agocs Reviewed-by: Shawn Rutledge --- configure | 8 + src/plugins/platforms/xcb/qxcbconnection.cpp | 79 ++--- src/plugins/platforms/xcb/qxcbconnection.h | 35 +- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 433 +++++++++++++++-------- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 31 ++ src/plugins/platforms/xcb/qxcbkeyboard.h | 1 + src/plugins/platforms/xcb/qxcbwindow.cpp | 126 +++++-- src/plugins/platforms/xcb/qxcbwindow.h | 10 + src/plugins/platforms/xcb/xcb_qpa_lib.pro | 5 + 9 files changed, 501 insertions(+), 227 deletions(-) diff --git a/configure b/configure index de0a1bd5d7..7251e8e673 100755 --- a/configure +++ b/configure @@ -5358,6 +5358,14 @@ fi # auto-detect XInput2 support if [ "$CFG_XINPUT2" != "no" ]; then if compileTest x11/xinput2 "XInput2"; then + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists xi 2>/dev/null; then + QMAKE_LIBXI_VERSION_MAJOR=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 1` + QMAKE_LIBXI_VERSION_MINOR=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 2` + QMAKE_LIBXI_VERSION_PATCH=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 3` + QMakeVar set QMAKE_LIBXI_VERSION_MAJOR "$QMAKE_LIBXI_VERSION_MAJOR" + QMakeVar set QMAKE_LIBXI_VERSION_MINOR "$QMAKE_LIBXI_VERSION_MINOR" + QMakeVar set QMAKE_LIBXI_VERSION_PATCH "$QMAKE_LIBXI_VERSION_PATCH" + fi CFG_XINPUT2=yes CFG_XINPUT=no else diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 92d064df9b..80c844e658 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -70,7 +70,6 @@ #endif #if defined(XCB_USE_XINPUT2) -#include #include #endif @@ -457,6 +456,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra , m_focusWindow(0) , m_systemTrayTracker(0) , m_glIntegration(Q_NULLPTR) + , m_xiGrab(false) { #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); @@ -909,7 +909,7 @@ static Qt::MouseButtons translateMouseButtons(int s) return ret; } -static Qt::MouseButton translateMouseButton(xcb_button_t s) +Qt::MouseButton QXcbConnection::translateMouseButton(xcb_button_t s) { switch (s) { case 1: return Qt::LeftButton; @@ -944,39 +944,6 @@ static Qt::MouseButton translateMouseButton(xcb_button_t s) } } -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); - qCDebug(lcQpaXInput, "xcb: pressed mouse button %d, button state %X", event->detail, static_cast(m_buttons)); -} - -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); - qCDebug(lcQpaXInput, "xcb: released mouse button %d, button state %X", event->detail, static_cast(m_buttons)); -} - -void QXcbConnection::handleMotionNotify(xcb_generic_event_t *ev) -{ - xcb_motion_notify_event_t *event = (xcb_motion_notify_event_t *)ev; - - m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); -#ifdef Q_XCB_DEBUG - qCDebug(lcQpaXInput, "xcb: moved mouse to %4d, %4d; button state %X", - event->event_x, event->event_y, static_cast(m_buttons)); -#endif -} - #ifndef QT_NO_XKB namespace { typedef union { @@ -1018,18 +985,35 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) switch (response_type) { case XCB_EXPOSE: HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent); - case XCB_BUTTON_PRESS: - m_keyboard->updateXKBStateFromCore(((xcb_button_press_event_t *)event)->state); - handleButtonPress(event); + + // press/release/motion is only delivered here when XI 2.2+ is _not_ in use + case XCB_BUTTON_PRESS: { + xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; + m_keyboard->updateXKBStateFromCore(ev->state); + // the event explicitly contains the state of the three first buttons, + // the rest we need to manage ourselves + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); + m_buttons |= translateMouseButton(ev->detail); + qCDebug(lcQpaXInput, "legacy mouse press, button %d state %X", ev->detail, static_cast(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); - case XCB_BUTTON_RELEASE: - m_keyboard->updateXKBStateFromCore(((xcb_button_release_event_t *)event)->state); - handleButtonRelease(event); + } + case XCB_BUTTON_RELEASE: { + xcb_button_release_event_t *ev = (xcb_button_release_event_t *)event; + m_keyboard->updateXKBStateFromCore(ev->state); + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); + m_buttons &= ~translateMouseButton(ev->detail); + qCDebug(lcQpaXInput, "legacy mouse release, button %d state %X", ev->detail, static_cast(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); - case XCB_MOTION_NOTIFY: - m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state); - handleMotionNotify(event); + } + case XCB_MOTION_NOTIFY: { + xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event; + m_keyboard->updateXKBStateFromCore(ev->state); + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); + qCDebug(lcQpaXInput, "legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y, + ev->detail, static_cast(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); + } + case XCB_CONFIGURE_NOTIFY: HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent); case XCB_MAP_NOTIFY: @@ -1090,6 +1074,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) break; #if defined(XCB_USE_XINPUT2) case XCB_GE_GENERIC: + // Here the windowEventListener is invoked from xi2HandleEvent() if (m_xi2Enabled) xi2HandleEvent(reinterpret_cast(event)); break; @@ -1931,6 +1916,12 @@ void QXcbConnection::initializeXKB() #endif } +bool QXcbConnection::xi2MouseEvents() const +{ + static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); + return mouseViaXI2; +} + #if defined(XCB_USE_XINPUT2) static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index e4274eca4d..2005ae0701 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -69,7 +69,8 @@ #endif #endif struct XInput2TouchDeviceData; -#endif +#endif // XCB_USE_XINPUT2 + struct xcb_randr_get_output_info_reply_t; //#define Q_XCB_DEBUG @@ -347,6 +348,7 @@ public: virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {} virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {} virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {} + virtual void handleXIMouseEvent(xcb_ge_event_t *) {} virtual QXcbWindow *toWindow() { return 0; } }; @@ -413,14 +415,14 @@ public: void xi2Select(xcb_window_t window); #endif #ifdef XCB_USE_XINPUT21 - bool isUsingXInput21() const { return m_xi2Enabled && m_xi2Minor >= 1; } + bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; } #else - bool isUsingXInput21() const { return false; } + bool isAtLeastXI21() const { return false; } #endif #ifdef XCB_USE_XINPUT22 - bool isUsingXInput22() const { return m_xi2Enabled && m_xi2Minor >= 2; } + bool isAtLeastXI22() const { return m_xi2Enabled && m_xi2Minor >= 2; } #else - bool isUsingXInput22() const { return false; } + bool isAtLeastXI22() const { return false; } #endif void sync(); @@ -457,7 +459,9 @@ public: xcb_timestamp_t getTimestamp(); + void setButton(Qt::MouseButton button, bool down) { if (down) m_buttons |= button; else m_buttons &= ~button; } Qt::MouseButtons buttons() const { return m_buttons; } + Qt::MouseButton translateMouseButton(xcb_button_t s); QXcbWindow *focusWindow() const { return m_focusWindow; } void setFocusWindow(QXcbWindow *); @@ -477,11 +481,19 @@ public: void handleEnterEvent(const xcb_enter_notify_event_t *); #endif +#ifdef XCB_USE_XINPUT22 + bool xi2SetMouseGrabEnabled(xcb_window_t w, bool grab); +#endif + Qt::MouseButton xiToQtMouseButton(uint32_t b); + QXcbEventReader *eventReader() const { return m_reader; } bool canGrab() const { return m_canGrabServer; } QXcbGlIntegration *glIntegration() const { return m_glIntegration; } + + bool xi2MouseEvents() const; + protected: bool event(QEvent *e) Q_DECL_OVERRIDE; @@ -509,9 +521,6 @@ private: bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output); void initializeScreens(); void updateScreens(const xcb_randr_notify_event_t *event); - void handleButtonPress(xcb_generic_event_t *event); - void handleButtonRelease(xcb_generic_event_t *event); - void handleMotionNotify(xcb_generic_event_t *event); bool m_xi2Enabled; int m_xi2Minor; @@ -524,6 +533,9 @@ private: void xi2HandleHierachyEvent(void *event); void xi2HandleDeviceChangedEvent(void *event); int m_xiOpCode, m_xiEventBase, m_xiErrorBase; +#ifdef XCB_USE_XINPUT22 + void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow); +#endif // XCB_USE_XINPUT22 #ifndef QT_NO_TABLETEVENT struct TabletData { TabletData() : deviceId(0), pointerType(QTabletEvent::UnknownPointer), @@ -543,10 +555,10 @@ private: }; QHash valuatorInfo; }; - bool xi2HandleTabletEvent(void *event, TabletData *tabletData); + bool xi2HandleTabletEvent(void *event, TabletData *tabletData, QXcbWindowEventListener *eventListener); void xi2ReportTabletEvent(TabletData &tabletData, void *event); QVector m_tabletData; -#endif +#endif // !QT_NO_TABLETEVENT struct ScrollingDevice { ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { } int deviceId; @@ -559,9 +571,7 @@ private: void updateScrollingDevice(ScrollingDevice& scrollingDevice, int num_classes, void *classes); void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice); QHash m_scrollingDevices; -#endif // XCB_USE_XINPUT2 -#if defined(XCB_USE_XINPUT2) static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value); static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode); #endif @@ -633,6 +643,7 @@ private: QByteArray m_startupId; QXcbSystemTrayTracker *m_systemTrayTracker; QXcbGlIntegration *m_glIntegration; + bool m_xiGrab; friend class QXcbEventReader; }; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 1848fc14f0..0e8a162a7d 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -275,34 +275,37 @@ void QXcbConnection::xi2Select(xcb_window_t window) unsigned char *xiBitMask = reinterpret_cast(&bitMask); #ifdef XCB_USE_XINPUT22 - if (isUsingXInput22()) { + if (isAtLeastXI22()) { bitMask |= XI_TouchBeginMask; bitMask |= XI_TouchUpdateMask; bitMask |= XI_TouchEndMask; + bitMask |= XI_PropertyEventMask; // for tablets + if (xi2MouseEvents()) { + // We want both mouse and touch through XI2 if touch is supported (>= 2.2). + // The plain xcb press and motion events will not be delivered after this. + bitMask |= XI_ButtonPressMask; + bitMask |= XI_ButtonReleaseMask; + bitMask |= XI_MotionMask; + qCDebug(lcQpaXInput, "XInput 2.2: Selecting press/release/motion events in addition to touch"); + } XIEventMask mask; mask.mask_len = sizeof(bitMask); mask.mask = xiBitMask; - if (!m_touchDevices.isEmpty()) { - // If we select for touch events on the master pointer, XInput2 - // will not synthesize mouse events. This means Qt must do it, - // which is also preferable, since Qt can control better when - // to do so. - mask.deviceid = XIAllMasterDevices; - Status result = XISelectEvents(xDisplay, window, &mask, 1); - if (result != Success) - qCDebug(lcQpaXInput, "XInput 2.2: failed to select touch events, window %x, result %d", window, result); - } + // When xi2MouseEvents() is true (the default), pointer emulation for touch and tablet + // events will get disabled. This is preferable for touch, as Qt Quick handles touch events + // directly while for others QtGui synthesizes mouse events, not so much for tablets. For + // the latter we will synthesize the events ourselves. + mask.deviceid = XIAllMasterDevices; + Status result = XISelectEvents(xDisplay, window, &mask, 1); + if (result != Success) + qCDebug(lcQpaXInput, "XInput 2.2: failed to select pointer/touch events, window %x, result %d", window, result); } #endif // XCB_USE_XINPUT22 + const bool pointerSelected = isAtLeastXI22() && xi2MouseEvents(); QSet tabletDevices; #ifndef QT_NO_TABLETEVENT - // For each tablet, select some additional event types. - // Press, motion, etc. events must never be selected for _all_ devices - // as that would render the standard XCB_MOTION_NOTIFY and - // similar handlers useless and we have no intention to infect - // all the pure xcb code with Xlib-based XI2. - if (!m_tabletData.isEmpty()) { + if (!m_tabletData.isEmpty() && !pointerSelected) { unsigned int tabletBitMask; unsigned char *xiTabletBitMask = reinterpret_cast(&tabletBitMask); QVector xiEventMask(m_tabletData.count()); @@ -323,7 +326,8 @@ void QXcbConnection::xi2Select(xcb_window_t window) #ifdef XCB_USE_XINPUT21 // Enable each scroll device - if (!m_scrollingDevices.isEmpty()) { + if (!m_scrollingDevices.isEmpty() && !pointerSelected) { + // Only when XI2 mouse events are not enabled, otherwise motion and release are selected already. QVector xiEventMask(m_scrollingDevices.size()); unsigned int scrollBitMask; unsigned char *xiScrollBitMask = reinterpret_cast(&scrollBitMask); @@ -425,7 +429,7 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) dev->size.width() > 10000 || dev->size.height() > 10000) dev->size = QSizeF(130, 110); } - if (!isUsingXInput22() || type == QTouchDevice::TouchPad) + if (!isAtLeastXI22() || type == QTouchDevice::TouchPad) caps |= QTouchDevice::MouseEmulation; if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) { @@ -447,7 +451,7 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) } #if defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT) -static qreal fixed1616ToReal(FP1616 val) +static inline qreal fixed1616ToReal(FP1616 val) { return qreal(val) / 0x10000; } @@ -468,155 +472,280 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) { if (xi2PrepareXIGenericDeviceEvent(event, m_xiOpCode)) { xXIGenericDeviceEvent *xiEvent = reinterpret_cast(event); + int sourceDeviceId = xiEvent->deviceid; // may be the master id + xXIDeviceEvent *xiDeviceEvent = 0; + QXcbWindowEventListener *eventListener = 0; - if (xiEvent->evtype == XI_HierarchyChanged) { + switch (xiEvent->evtype) { + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_Motion: + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: + { + xiDeviceEvent = reinterpret_cast(event); + eventListener = windowEventListenerFromId(xiDeviceEvent->event); + if (eventListener) { + long result = 0; + if (eventListener->handleGenericEvent(reinterpret_cast(event), &result)) + return; + } + sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master + break; + } + case XI_HierarchyChanged: xi2HandleHierachyEvent(xiEvent); return; - } - if (xiEvent->evtype == XI_DeviceChanged) { + case XI_DeviceChanged: xi2HandleDeviceChangedEvent(xiEvent); return; + default: + break; } #ifndef QT_NO_TABLETEVENT for (int i = 0; i < m_tabletData.count(); ++i) { - if (m_tabletData.at(i).deviceId == xiEvent->deviceid) { - if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i])) + if (m_tabletData.at(i).deviceId == sourceDeviceId) { + if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) return; } } #endif // QT_NO_TABLETEVENT #ifdef XCB_USE_XINPUT21 - QHash::iterator device = m_scrollingDevices.find(xiEvent->deviceid); + QHash::iterator device = m_scrollingDevices.find(sourceDeviceId); if (device != m_scrollingDevices.end()) xi2HandleScrollEvent(xiEvent, device.value()); #endif // XCB_USE_XINPUT21 #ifdef XCB_USE_XINPUT22 - if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) { - xXIDeviceEvent* xiDeviceEvent = reinterpret_cast(event); - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f", - event->event_type, xiEvent->sequenceNumber, xiDeviceEvent->detail, - fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y), - fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y) ); - - if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) { - XInput2TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid); - Q_ASSERT(dev); - const bool firstTouch = m_touchPoints.isEmpty(); - if (xiEvent->evtype == XI_TouchBegin) { - QWindowSystemInterface::TouchPoint tp; - tp.id = xiDeviceEvent->detail % INT_MAX; - tp.state = Qt::TouchPointPressed; - tp.pressure = -1.0; - m_touchPoints[tp.id] = tp; - } - QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; - qreal x = fixed1616ToReal(xiDeviceEvent->root_x); - qreal y = fixed1616ToReal(xiDeviceEvent->root_y); - qreal nx = -1.0, ny = -1.0, d = 0.0; - QXcbScreen* screen = m_screens.at(0); - for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { - XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; - if (classinfo->type == XIValuatorClass) { - XIValuatorClassInfo *vci = reinterpret_cast(classinfo); - int n = vci->number; - double value; - if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value)) - continue; - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput, " valuator %20s value %lf from range %lf -> %lf", - atomName(vci->label).constData(), value, vci->min, vci->max ); - if (vci->label == atom(QXcbAtom::RelX)) { - nx = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::RelY)) { - ny = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsX)) { - nx = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsY)) { - ny = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsMTPositionX)) { - nx = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { - ny = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { - d = valuatorNormalized(value, vci) * screen->geometry().width(); - } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || - vci->label == atom(QXcbAtom::AbsPressure)) { - touchPoint.pressure = valuatorNormalized(value, vci); - } - } - } - // If any value was not updated, use the last-known value. - if (nx == -1.0) { - x = touchPoint.area.center().x(); - nx = x / screen->geometry().width(); - } - if (ny == -1.0) { - y = touchPoint.area.center().y(); - ny = y / screen->geometry().height(); - } - if (xiEvent->evtype != XI_TouchEnd) { - if (d == 0.0) - d = touchPoint.area.width(); - } - - switch (xiEvent->evtype) { - case XI_TouchBegin: - if (firstTouch) { - dev->firstPressedPosition = QPointF(x, y); - dev->firstPressedNormalPosition = QPointF(nx, ny); - } - dev->pointPressedPosition.insert(touchPoint.id, QPointF(x, y)); - break; - case XI_TouchUpdate: - if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { - qreal dx = (nx - dev->firstPressedNormalPosition.x()) * - dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); - qreal dy = (ny - dev->firstPressedNormalPosition.y()) * - dev->size.height() * screen->geometry().height() / screen->physicalSize().height(); - x = dev->firstPressedPosition.x() + dx; - y = dev->firstPressedPosition.y() + dy; - touchPoint.state = Qt::TouchPointMoved; - } else if (touchPoint.area.center() != QPoint(x, y)) { - touchPoint.state = Qt::TouchPointMoved; - dev->pointPressedPosition[touchPoint.id] = QPointF(x, y); - } - break; - case XI_TouchEnd: - touchPoint.state = Qt::TouchPointReleased; - if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { - qreal dx = (nx - dev->firstPressedNormalPosition.x()) * - dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); - qreal dy = (ny - dev->firstPressedNormalPosition.y()) * - dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); - x = dev->firstPressedPosition.x() + dx; - y = dev->firstPressedPosition.y() + dy; - } - dev->pointPressedPosition.remove(touchPoint.id); - } - touchPoint.area = QRectF(x - d/2, y - d/2, d, d); - touchPoint.normalPosition = QPointF(nx, ny); + if (xiDeviceEvent) { + switch (xiDeviceEvent->evtype) { + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_Motion: + if (xi2MouseEvents() && eventListener) + eventListener->handleXIMouseEvent(event); + break; + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << - " area " << touchPoint.area << " pressure " << touchPoint.pressure; - QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiEvent->time, dev->qtTouchDevice, m_touchPoints.values()); - if (touchPoint.state == Qt::TouchPointReleased) - // If a touchpoint was released, we can forget it, because the ID won't be reused. - m_touchPoints.remove(touchPoint.id); - else - // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent - // with this touch point if the next XI2 event is about a different touch point. - touchPoint.state = Qt::TouchPointStationary; + qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x", + event->event_type, xiDeviceEvent->sequenceNumber, xiDeviceEvent->detail, + fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y), + fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event); + if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) + xi2ProcessTouch(xiDeviceEvent, platformWindow); + break; } } #endif // XCB_USE_XINPUT22 } } +#ifdef XCB_USE_XINPUT22 +void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow) +{ + xXIDeviceEvent *xiDeviceEvent = static_cast(xiDevEvent); + XInput2TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid); + Q_ASSERT(dev); + const bool firstTouch = m_touchPoints.isEmpty(); + if (xiDeviceEvent->evtype == XI_TouchBegin) { + QWindowSystemInterface::TouchPoint tp; + tp.id = xiDeviceEvent->detail % INT_MAX; + tp.state = Qt::TouchPointPressed; + tp.pressure = -1.0; + m_touchPoints[tp.id] = tp; + } + QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; + qreal x = fixed1616ToReal(xiDeviceEvent->root_x); + qreal y = fixed1616ToReal(xiDeviceEvent->root_y); + qreal nx = -1.0, ny = -1.0, d = 0.0; + QXcbScreen* screen = m_screens.at(0); + for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { + XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; + if (classinfo->type == XIValuatorClass) { + XIValuatorClassInfo *vci = reinterpret_cast(classinfo); + int n = vci->number; + double value; + if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value)) + continue; + if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) + qCDebug(lcQpaXInput, " valuator %20s value %lf from range %lf -> %lf", + atomName(vci->label).constData(), value, vci->min, vci->max ); + if (vci->label == atom(QXcbAtom::RelX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::RelY)) { + ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsY)) { + ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsMTPositionX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { + ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { + d = valuatorNormalized(value, vci) * screen->geometry().width(); + } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || + vci->label == atom(QXcbAtom::AbsPressure)) { + touchPoint.pressure = valuatorNormalized(value, vci); + } + } + } + // If any value was not updated, use the last-known value. + if (nx == -1.0) { + x = touchPoint.area.center().x(); + nx = x / screen->geometry().width(); + } + if (ny == -1.0) { + y = touchPoint.area.center().y(); + ny = y / screen->geometry().height(); + } + if (xiDeviceEvent->evtype != XI_TouchEnd) { + if (d == 0.0) + d = touchPoint.area.width(); + } + + switch (xiDeviceEvent->evtype) { + case XI_TouchBegin: + if (firstTouch) { + dev->firstPressedPosition = QPointF(x, y); + dev->firstPressedNormalPosition = QPointF(nx, ny); + } + dev->pointPressedPosition.insert(touchPoint.id, QPointF(x, y)); + + // Touches must be accepted when we are grabbing touch events. Otherwise the entire sequence + // will get replayed when the grab ends. + if (m_xiGrab) { + // XIAllowTouchEvents deadlocks with libXi < 1.7.4 (this has nothing to do with the XI2 versions like 2.2) + // http://lists.x.org/archives/xorg-devel/2014-July/043059.html +#ifndef LIBXI_MAJOR + static bool allowTouchWarningShown = false; + if (!allowTouchWarningShown) { + allowTouchWarningShown = true; + qWarning("Skipping XIAllowTouchEvents() because it was not possible to detect libXi version at build time." + " Minimum libXi version required is 1.7.4." + " Expect issues with touch behavior."); + } +#elif LIBXI_MAJOR == 1 && (LIBXI_MINOR < 7 || (LIBXI_MINOR == 7 && LIBXI_PATCH < 4)) + static bool allowTouchWarningShown = false; + if (!allowTouchWarningShown) { + allowTouchWarningShown = true; + qWarning("Skipping XIAllowTouchEvents() due to not having libXi >= 1.7.4." + " libXi version at build time was %d.%d.%d." + " Expect issues with touch behavior.", LIBXI_MAJOR, LIBXI_MINOR, LIBXI_PATCH); + } +#else + XIAllowTouchEvents(static_cast(m_xlib_display), xiDeviceEvent->deviceid, + xiDeviceEvent->detail, xiDeviceEvent->event, XIAcceptTouch); +#endif + } + break; + case XI_TouchUpdate: + if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { + qreal dx = (nx - dev->firstPressedNormalPosition.x()) * + dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); + qreal dy = (ny - dev->firstPressedNormalPosition.y()) * + dev->size.height() * screen->geometry().height() / screen->physicalSize().height(); + x = dev->firstPressedPosition.x() + dx; + y = dev->firstPressedPosition.y() + dy; + touchPoint.state = Qt::TouchPointMoved; + } else if (touchPoint.area.center() != QPoint(x, y)) { + touchPoint.state = Qt::TouchPointMoved; + dev->pointPressedPosition[touchPoint.id] = QPointF(x, y); + } + break; + case XI_TouchEnd: + touchPoint.state = Qt::TouchPointReleased; + if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { + qreal dx = (nx - dev->firstPressedNormalPosition.x()) * + dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); + qreal dy = (ny - dev->firstPressedNormalPosition.y()) * + dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); + x = dev->firstPressedPosition.x() + dx; + y = dev->firstPressedPosition.y() + dy; + } + dev->pointPressedPosition.remove(touchPoint.id); + } + touchPoint.area = QRectF(x - d/2, y - d/2, d, d); + touchPoint.normalPosition = QPointF(nx, ny); + + if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) + qCDebug(lcQpaXInput) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << + " area " << touchPoint.area << " pressure " << touchPoint.pressure; + QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, m_touchPoints.values()); + if (touchPoint.state == Qt::TouchPointReleased) + // If a touchpoint was released, we can forget it, because the ID won't be reused. + m_touchPoints.remove(touchPoint.id); + else + // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent + // with this touch point if the next XI2 event is about a different touch point. + touchPoint.state = Qt::TouchPointStationary; +} + +bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) +{ + if (grab && !canGrab()) + return false; + + int num_devices = 0; + Display *xDisplay = static_cast(xlib_display()); + XIDeviceInfo *info = XIQueryDevice(xDisplay, XIAllMasterDevices, &num_devices); + if (!info) + return false; + + XIEventMask evmask; + unsigned char mask[XIMaskLen(XI_LASTEVENT)]; + evmask.mask = mask; + evmask.mask_len = sizeof(mask); + memset(mask, 0, sizeof(mask)); + evmask.deviceid = XIAllMasterDevices; + + XISetMask(mask, XI_ButtonPress); + XISetMask(mask, XI_ButtonRelease); + XISetMask(mask, XI_Motion); + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchEnd); + + bool grabbed = true; + for (int i = 0; i < num_devices; i++) { + int id = info[i].deviceid, n = 0; + XIDeviceInfo *deviceInfo = XIQueryDevice(xDisplay, id, &n); + if (deviceInfo) { + const bool grabbable = deviceInfo->use != XIMasterKeyboard; + XIFreeDeviceInfo(deviceInfo); + if (!grabbable) + continue; + } + if (!grab) { + Status result = XIUngrabDevice(xDisplay, id, CurrentTime); + if (result != Success) { + grabbed = false; + qCDebug(lcQpaXInput, "XInput 2.2: failed to ungrab events for device %d (result %d)", id, result); + } + } else { + Status result = XIGrabDevice(xDisplay, id, w, CurrentTime, None, XIGrabModeAsync, + XIGrabModeAsync, False, &evmask); + if (result != Success) { + grabbed = false; + qCDebug(lcQpaXInput, "XInput 2.2: failed to grab events for device %d on window %x (result %d)", id, w, result); + } + } + } + + XIFreeDeviceInfo(info); + + m_xiGrab = grabbed; + + return grabbed; +} +#endif // XCB_USE_XINPUT22 + void QXcbConnection::xi2HandleHierachyEvent(void *event) { xXIHierarchyEvent *xiEvent = reinterpret_cast(event); @@ -785,7 +914,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin #endif // XCB_USE_XINPUT21 } -static Qt::MouseButton xiToQtMouseButton(uint32_t b) { +Qt::MouseButton QXcbConnection::xiToQtMouseButton(uint32_t b) +{ switch (b) { case 1: return Qt::LeftButton; case 2: return Qt::MiddleButton; @@ -832,20 +962,29 @@ static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) { } #ifndef QT_NO_TABLETEVENT -bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData) +bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, QXcbWindowEventListener *eventListener) { bool handled = true; Display *xDisplay = static_cast(m_xlib_display); xXIGenericDeviceEvent *xiEvent = static_cast(event); + xXIDeviceEvent *xiDeviceEvent = reinterpret_cast(xiEvent); + +#ifdef XCB_USE_XINPUT22 + // Synthesize mouse events since otherwise there are no mouse events from + // the pen on the XI 2.2+ path. + if (xi2MouseEvents() && eventListener) + eventListener->handleXIMouseEvent(reinterpret_cast(event)); +#endif + switch (xiEvent->evtype) { case XI_ButtonPress: { - Qt::MouseButton b = xiToQtMouseButton(reinterpret_cast(event)->detail); + Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail); tabletData->buttons |= b; xi2ReportTabletEvent(*tabletData, xiEvent); break; } case XI_ButtonRelease: { - Qt::MouseButton b = xiToQtMouseButton(reinterpret_cast(event)->detail); + Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail); tabletData->buttons ^= b; xi2ReportTabletEvent(*tabletData, xiEvent); break; @@ -908,7 +1047,7 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData) // TODO maybe have a hash of tabletData->deviceId to device data so we can // look up the tablet name here, and distinguish multiple tablets qCDebug(lcQpaXInput, "XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x TabletDevice %d", - ev->deviceid, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID], + tabletData->deviceId, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID], ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], tabletData->tool); } XFree(data); @@ -972,7 +1111,7 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event) if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) qCDebug(lcQpaXInput, "XI2 event on tablet %d with tool %d type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf", - ev->deviceid, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, + tabletData.deviceId, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y), fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y), (int)tabletData.buttons, pressure, xTilt, yTilt, rotation); diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 6a9ef5869e..2d96ed1c21 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -47,6 +47,12 @@ #include #include +#ifdef XCB_USE_XINPUT22 +#include +#undef KeyPress +#undef KeyRelease +#endif + #ifndef XK_ISO_Left_Tab #define XK_ISO_Left_Tab 0xFE20 #endif @@ -791,6 +797,31 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state) } } +void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) +{ +#ifdef XCB_USE_XINPUT22 + if (m_config && !connection()->hasXKB()) { + xXIModifierInfo *mods = static_cast(modInfo); + xXIGroupInfo *group = static_cast(groupInfo); + const xkb_state_component newState = xkb_state_update_mask(xkb_state, + mods->base_mods, + mods->latched_mods, + mods->locked_mods, + group->base_group, + group->latched_group, + group->locked_group); + + if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { + //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); + } + } +#else + Q_UNUSED(modInfo); + Q_UNUSED(groupInfo); + Q_ASSERT(false); // this can't be +#endif +} + quint32 QXcbKeyboard::xkbModMask(quint16 state) { quint32 xkb_mask = 0; diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 2281674e2f..d2e37d624c 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -68,6 +68,7 @@ public: void updateXKBMods(); quint32 xkbModMask(quint16 state); void updateXKBStateFromCore(quint16 state); + void updateXKBStateFromXI(void *modInfo, void *groupInfo); #ifndef QT_NO_XKB // when XKEYBOARD is present on the X server int coreDeviceId() const { return core_device_id; } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 3188a7f19d..d1b688857d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -96,6 +96,7 @@ #if defined(XCB_USE_XINPUT2) #include +#include #endif #define XCOORD_MAX 16383 @@ -2106,16 +2107,17 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) } } -void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) +void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { - const bool isWheel = event->detail >= 4 && event->detail <= 7; + const bool isWheel = detail >= 4 && detail <= 7; if (!isWheel && window() != QGuiApplication::focusWindow()) { QWindow *w = static_cast(QObjectPrivate::get(window()))->eventReceiver(); if (!(w->flags() & Qt::WindowDoesNotAcceptFocus)) w->requestActivate(); } - updateNetWmUserTime(event->time); + updateNetWmUserTime(timestamp); if (m_embedded) { if (window() != QGuiApplication::focusWindow()) { @@ -2126,53 +2128,125 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) } } const int dpr = int(devicePixelRatio()); - QPoint local(event->event_x/dpr, event->event_y/dpr); - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); - - Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + QPoint local(event_x / dpr, event_y / dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); if (isWheel) { - if (!connection()->isUsingXInput21()) { + if (!connection()->isAtLeastXI21()) { // Logic borrowed from qapplication_x11.cpp - int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1); - bool hor = (((event->detail == 4 || event->detail == 5) + int delta = 120 * ((detail == 4 || detail == 6) ? 1 : -1); + bool hor = (((detail == 4 || detail == 5) && (modifiers & Qt::AltModifier)) - || (event->detail == 6 || event->detail == 7)); + || (detail == 6 || detail == 7)); - QWindowSystemInterface::handleWheelEvent(window(), event->time, + QWindowSystemInterface::handleWheelEvent(window(), timestamp, local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers); } return; } - handleMouseEvent(event->time, local, global, modifiers); + handleMouseEvent(timestamp, local, global, modifiers); } -void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event) +void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { const int dpr = int(devicePixelRatio()); - QPoint local(event->event_x/dpr, event->event_y/dpr); - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); - Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + QPoint local(event_x / dpr, event_y / dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); - if (event->detail >= 4 && event->detail <= 7) { + if (detail >= 4 && detail <= 7) { // mouse wheel, handled in handleButtonPressEvent() return; } - handleMouseEvent(event->time, local, global, modifiers); + handleMouseEvent(timestamp, local, global, modifiers); } -void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) +void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { - const int dpr = int(devicePixelRatio()); - QPoint local(event->event_x/dpr, event->event_y/dpr); if (!xcbScreen()) return; - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); + const int dpr = int(devicePixelRatio()); + QPoint local(event_x / dpr, event_y / dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); + handleMouseEvent(timestamp, local, global, modifiers); +} + +// Handlers for plain xcb events. Used only when XI 2.2 or newer is not available. +void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) +{ Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + handleButtonPressEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail, + modifiers, event->time); +} - handleMouseEvent(event->time, local, global, modifiers); +void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event) +{ + Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + handleButtonReleaseEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail, + modifiers, event->time); +} + +void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) +{ + Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers, event->time); +} + +#ifdef XCB_USE_XINPUT22 +static inline int fixed1616ToInt(FP1616 val) +{ + return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); +} +#endif + +// With XI 2.2+ press/release/motion comes here instead of the above handlers. +void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) +{ +#ifdef XCB_USE_XINPUT22 + QXcbConnection *conn = connection(); + xXIDeviceEvent *ev = reinterpret_cast(event); + const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods); + const int event_x = fixed1616ToInt(ev->event_x); + const int event_y = fixed1616ToInt(ev->event_y); + const int root_x = fixed1616ToInt(ev->root_x); + const int root_y = fixed1616ToInt(ev->root_y); + + conn->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group); + + const Qt::MouseButton button = conn->xiToQtMouseButton(ev->detail); + + if (ev->buttons_len > 0) { + unsigned char *buttonMask = (unsigned char *) &ev[1]; + for (int i = 1; i <= 15; ++i) + conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i)); + } + + switch (ev->evtype) { + case XI_ButtonPress: + qCDebug(lcQpaXInput, "XI2 mouse press, button %d", button); + conn->setButton(button, true); + handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); + break; + case XI_ButtonRelease: + qCDebug(lcQpaXInput, "XI2 mouse release, button %d", button); + conn->setButton(button, false); + handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); + break; + case XI_Motion: + qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d", event_x, event_y); + handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time); + break; + default: + qWarning() << "Unrecognized XI2 mouse event" << ev->evtype; + break; + } +#else + Q_UNUSED(event); + Q_ASSERT(false); // this can't be +#endif } QXcbWindow *QXcbWindow::toWindow() { return this; } @@ -2356,6 +2430,10 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab) bool QXcbWindow::setMouseGrabEnabled(bool grab) { +#ifdef XCB_USE_XINPUT22 + if (connection()->xi2MouseEvents()) + return connection()->xi2SetMouseGrabEnabled(m_window, grab); +#endif if (grab && !connection()->canGrab()) return false; diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 512bc54255..e62bfcba64 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -131,6 +131,7 @@ public: void handleFocusInEvent(const xcb_focus_in_event_t *event) Q_DECL_OVERRIDE; void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE; void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE; + void handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE; QXcbWindow *toWindow() Q_DECL_OVERRIDE; @@ -199,6 +200,15 @@ protected: void doFocusIn(); void doFocusOut(); + void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + + void handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + + void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + xcb_window_t m_window; QXcbScreen *m_xcbScreen; diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index fd704dd904..12987567ff 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -59,6 +59,11 @@ contains(QT_CONFIG, xcb-xlib) { DEFINES += XCB_USE_XINPUT2 SOURCES += qxcbconnection_xi2.cpp LIBS += -lXi + !isEmpty(QMAKE_LIBXI_VERSION_MAJOR) { + DEFINES += LIBXI_MAJOR=$$QMAKE_LIBXI_VERSION_MAJOR \ + LIBXI_MINOR=$$QMAKE_LIBXI_VERSION_MINOR \ + LIBXI_PATCH=$$QMAKE_LIBXI_VERSION_PATCH + } } } -- cgit v1.2.3 From ecb25dac6894cf3e9169528d56adbe92eb1182b9 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 28 May 2015 18:13:18 +0200 Subject: QCocoaMenu: return YES if we have a shortcut for a pseudo-first responder When running a modal session with NSOpenPanel (QFileDialog), our menu delegate should not touch qApp->focusObject, since it's not what actually has focus inside NSOpenPanel (will be some native view). Return YES instead. Task-number: QTBUG-17291 Change-Id: I94f3281237fb25495d317b02310bf9d77b21d2ba Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoamenu.mm | 34 ++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 09a4c95469..dd2c37d914 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -81,7 +81,7 @@ QT_END_NAMESPACE } - (id) initWithMenu:(QCocoaMenu*) m; -- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier; +- (NSMenuItem *)findItem:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier; @end @@ -152,11 +152,20 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); // Change the private unicode keys to the ones used in setting the "Key Equivalents" NSString *characters = qt_mac_removePrivateUnicode([event characters]); - if ([self hasShortcut:menu - forKey:characters - // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ... - forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask)) - ]) { + // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ... + const NSUInteger mask = NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask; + if (NSMenuItem *menuItem = [self findItem:menu forKey:characters forModifiers:([event modifierFlags] & mask)]) { + if (!menuItem.target) { + // This item was modified by QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder + // and it looks like we're running a modal session for NSOpenPanel/NSSavePanel. + // QCocoaFileDialogHelper is actually the only place we use this and we run NSOpenPanel modal + // (modal sheet, window modal, application modal). + // Whatever the current first responder is, let's give it a chance + // and do not touch the Qt's focusObject (which is different from some native view + // having a focus inside NSSave/OpenPanel. + return YES; + } + QObject *object = qApp->focusObject(); if (object) { QChar ch; @@ -194,22 +203,23 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); return NO; } -- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier +- (NSMenuItem *)findItem:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier { for (NSMenuItem *item in [menu itemArray]) { if (![item isEnabled] || [item isHidden] || [item isSeparatorItem]) continue; - if ([item hasSubmenu] - && [self hasShortcut:[item submenu] forKey:key forModifiers:modifier]) - return YES; + if ([item hasSubmenu]) { + if (NSMenuItem *nested = [self findItem:[item submenu] forKey:key forModifiers:modifier]) + return nested; + } NSString *menuKey = [item keyEquivalent]; if (menuKey && NSOrderedSame == [menuKey compare:key] && modifier == [item keyEquivalentModifierMask]) - return YES; + return item; } - return NO; + return nil; } @end -- cgit v1.2.3 From 55f3e6bc342ba52304febbc1159c566daa894993 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 25 May 2015 23:31:05 +0300 Subject: WinRT: Fix argument handling on Windows 10 The Windows 10 CRT does not export __getmainargs(), so we need to move to GetCommandLine like on WinCE and desktop Windows. As CommandLineToArgv is not available, the command line is split according by spaces, allowing for quotes (and quote escaping) around arguments. Change-Id: Ibc969df94ca5423a3a71d8190bbacd201189ea19 Reviewed-by: Andrew Knight Reviewed-by: Maurice Kalinowski --- src/winmain/qtmain_winrt.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 5a44df622a..e68da520e7 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -222,11 +222,49 @@ private: // Main entry point for Appx containers int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { +#if _MSC_VER < 1900 int argc = 0; char **argv, **env; _startupinfo info = { _query_new_mode() }; if (int init = __getmainargs(&argc, &argv, &env, false, &info)) return init; +#else + QByteArray commandLine = QString::fromWCharArray(GetCommandLine()).toUtf8(); + QVarLengthArray args; + args.append(commandLine.data()); + bool quote = false; + bool escape = false; + for (int i = 0; i < commandLine.size(); ++i) { + switch (commandLine.at(i)) { + case '\\': + escape = true; + break; + case '"': + if (escape) { + escape = false; + break; + } + quote = !quote; + commandLine[i] = '\0'; + break; + case ' ': + if (quote) + break; + commandLine[i] = '\0'; + if (args.last()[0] != '\0') + args.append(commandLine.data() + i + 1); + // fall through + default: + if (args.last()[0] == '\0') + args.last() = commandLine.data() + i; + escape = false; // only quotes are escaped + break; + } + } + int argc = args.size(); + char **argv = args.data(); + char **env = Q_NULLPTR; +#endif // _MSC_VER >= 1900 for (int i = 0; env && env[i]; ++i) { QByteArray var(env[i]); -- cgit v1.2.3 From 069be1654359ab93f89d339775795508d106153a Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Tue, 21 Oct 2014 22:44:12 +0400 Subject: Fix statfs usage for BSD4 systems in QStorageInfo According to NETBSD manual pages, there's no statfs structure; statvfs should be used instead, change introduces defines for the stat(v)fs struct/function. Task-number: QTBUG-40785 Change-Id: I98599e4635e46f90ffcc99c768f4c250f09f914f Reviewed-by: Thiago Macieira --- src/corelib/io/qstorageinfo_unix.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 7b8f608050..d170e7c0c0 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -67,8 +67,20 @@ #endif #if defined(Q_OS_BSD4) -# define QT_STATFSBUF struct statvfs -# define QT_STATFS ::statvfs +# if defined(Q_OS_NETBSD) + define QT_STATFSBUF struct statvfs + define QT_STATFS ::statvfs +# else +# define QT_STATFSBUF struct statfs +# define QT_STATFS ::statfs +# endif + +# if !defined(ST_RDONLY) +# define ST_RDONLY MNT_RDONLY +# endif +# if !defined(_STATFS_F_FLAGS) +# define _STATFS_F_FLAGS 1 +# endif #elif defined(Q_OS_ANDROID) # define QT_STATFS ::statfs # define QT_STATFSBUF struct statfs @@ -122,11 +134,7 @@ public: inline QByteArray device() const; private: #if defined(Q_OS_BSD4) -# if defined(Q_OS_NETBSD) - struct statvfs *stat_buf; -# else - struct statfs *stat_buf; -# endif + QT_STATFSBUF *stat_buf; int entryCount; int currentIndex; #elif defined(Q_OS_SOLARIS) @@ -501,7 +509,7 @@ void QStorageInfoPrivate::retrieveVolumeInfo() bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize; bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize; bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize; -#if defined(Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4) #if defined(_STATFS_F_FLAGS) readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0; #endif -- cgit v1.2.3 From 78e335408303380310dd59fab421e495cf517ead Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 1 Jun 2015 11:44:37 +0200 Subject: Clip QOpenGLWidget and QQuickWidget correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce support for the widgets' clipRect(). Right now render-to-texture widgets in scroll areas placed close to each other result in broken (non-existent) clipping. Similarly, stack-on-top widgets fail to clip when placed inside a scroll area. This is now corrected and the qopenglwidget example is enhanced to utilize a scroll area. Task-number: QTBUG-45860 Change-Id: I859a63d61a50d64ba9e87244f83c5969dce12337 Reviewed-by: Jørgen Lind --- examples/opengl/qopenglwidget/glwidget.cpp | 6 +-- examples/opengl/qopenglwidget/mainwindow.cpp | 20 ++++++-- examples/opengl/qopenglwidget/mainwindow.h | 2 + src/gui/painting/qplatformbackingstore.cpp | 59 ++++++++++++++++------ src/gui/painting/qplatformbackingstore.h | 4 +- .../platformcompositor/qopenglcompositor.cpp | 31 ++++++++++-- .../qopenglcompositorbackingstore.cpp | 3 +- src/widgets/kernel/qwidgetbackingstore.cpp | 3 +- 8 files changed, 99 insertions(+), 29 deletions(-) diff --git a/examples/opengl/qopenglwidget/glwidget.cpp b/examples/opengl/qopenglwidget/glwidget.cpp index f93e667615..df52e3efbf 100644 --- a/examples/opengl/qopenglwidget/glwidget.cpp +++ b/examples/opengl/qopenglwidget/glwidget.cpp @@ -537,14 +537,14 @@ void GLWidget::setTransparent(bool transparent) window()->update(); } -void GLWidget::resizeGL(int w, int h) +void GLWidget::resizeGL(int, int) { if (m_hasButton) { if (!m_btn) { - m_btn = new QPushButton("A widget on top.\nPress me!", this); + m_btn = new QPushButton("A widget on top.\nPress for more widgets.", this); connect(m_btn, &QPushButton::clicked, this, &GLWidget::handleButtonPress); } - m_btn->move(w / 2, h / 2); + m_btn->move(20, 80); } } diff --git a/examples/opengl/qopenglwidget/mainwindow.cpp b/examples/opengl/qopenglwidget/mainwindow.cpp index 6cf1d5d6e2..22111afdcb 100644 --- a/examples/opengl/qopenglwidget/mainwindow.cpp +++ b/examples/opengl/qopenglwidget/mainwindow.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include "glwidget.h" @@ -69,7 +70,7 @@ MainWindow::MainWindow() "and therefore an interval < 16 ms will likely lead to a 60 FPS update rate."); QGroupBox *updateGroupBox = new QGroupBox(this); QCheckBox *timerBased = new QCheckBox("Use timer", this); - timerBased->setChecked(true); + timerBased->setChecked(false); timerBased->setToolTip("Toggles using a timer to trigger update().\n" "When not set, each paintGL() schedules the next update immediately,\n" "expecting the blocking swap to throttle the thread.\n" @@ -87,7 +88,7 @@ MainWindow::MainWindow() slider->setRange(0, 50); slider->setSliderPosition(30); m_timer->setInterval(10); - label->setText("A QOpenGLWidget"); + label->setText("A scrollable QOpenGLWidget"); label->setAlignment(Qt::AlignHCenter); QGroupBox * groupBox = new QGroupBox(this); @@ -96,7 +97,10 @@ MainWindow::MainWindow() m_layout = new QGridLayout(groupBox); - m_layout->addWidget(glwidget,1,0,8,1); + QScrollArea *scrollArea = new QScrollArea; + scrollArea->setWidget(glwidget); + + m_layout->addWidget(scrollArea,1,0,8,1); m_layout->addWidget(label,9,0,1,1); m_layout->addWidget(updateGroupBox, 10, 0, 1, 1); m_layout->addWidget(slider, 11,0,1,1); @@ -134,7 +138,10 @@ MainWindow::MainWindow() connect(timerBased, &QCheckBox::toggled, this, &MainWindow::timerUsageChanged); connect(timerBased, &QCheckBox::toggled, updateInterval, &QWidget::setEnabled); - m_timer->start(); + if (timerBased->isChecked()) + m_timer->start(); + else + updateInterval->setEnabled(false); } void MainWindow::updateIntervalChanged(int value) @@ -170,3 +177,8 @@ void MainWindow::timerUsageChanged(bool enabled) w->update(); } } + +void MainWindow::resizeEvent(QResizeEvent *) +{ + m_glWidgets[0]->setMinimumSize(size() + QSize(128, 128)); +} diff --git a/examples/opengl/qopenglwidget/mainwindow.h b/examples/opengl/qopenglwidget/mainwindow.h index f1b2c51e53..9ad8a01339 100644 --- a/examples/opengl/qopenglwidget/mainwindow.h +++ b/examples/opengl/qopenglwidget/mainwindow.h @@ -56,6 +56,8 @@ public: void addNew(); bool timerEnabled() const { return m_timer->isActive(); } + void resizeEvent(QResizeEvent *); + private slots: void updateIntervalChanged(int value); void timerUsageChanged(bool enabled); diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 14a9429c71..83077f38ca 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -86,6 +86,7 @@ struct QBackingstoreTextureInfo QWidget *widget; // may be null GLuint textureId; QRect rect; + QRect clipRect; QPlatformTextureList::Flags flags; }; @@ -142,6 +143,12 @@ QRect QPlatformTextureList::geometry(int index) const return d->textures.at(index).rect; } +QRect QPlatformTextureList::clipRect(int index) const +{ + Q_D(const QPlatformTextureList); + return d->textures.at(index).clipRect; +} + void QPlatformTextureList::lock(bool on) { Q_D(QPlatformTextureList); @@ -157,13 +164,15 @@ bool QPlatformTextureList::isLocked() const return d->locked; } -void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags) +void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, + const QRect &clipRect, Flags flags) { Q_D(QPlatformTextureList); QBackingstoreTextureInfo bi; bi.widget = widget; bi.textureId = textureId; bi.rect = geometry; + bi.clipRect = clipRect; bi.flags = flags; d->textures.append(bi); } @@ -198,7 +207,7 @@ void QPlatformTextureList::clear() #ifndef QT_NO_OPENGL -static QRect deviceRect(const QRect &rect, QWindow *window) +static inline QRect deviceRect(const QRect &rect, QWindow *window) { QRect deviceRect(rect.topLeft() * window->devicePixelRatio(), rect.size() * window->devicePixelRatio()); @@ -219,6 +228,32 @@ static QRegion deviceRegion(const QRegion ®ion, QWindow *window) return deviceRegion; } +static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) +{ + return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1, + topLeftRect.width(), topLeftRect.height()); +} + +static void blit(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect, + QOpenGLTextureBlitter *blitter) +{ + const QRect rectInWindow = textures->geometry(idx); + QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); + const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); + + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(deviceRect(clippedRectInWindow, window), + deviceWindowRect); + + const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window), + deviceRect(rectInWindow, window).size(), + QOpenGLTextureBlitter::OriginBottomLeft); + + blitter->blit(textures->textureId(idx), target, source); +} + /*! Flushes the given \a region from the specified \a window onto the screen, and composes it with the specified \a textures. @@ -254,15 +289,12 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i d_ptr->blitter->bind(); - QRect windowRect(QPoint(), window->size() * window->devicePixelRatio()); + const QRect deviceWindowRect = deviceRect(QRect(QPoint(), window->size()), window); // Textures for renderToTexture widgets. for (int i = 0; i < textures->count(); ++i) { - if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QRect targetRect = deviceRect(textures->geometry(i), window); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); - d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); - } + if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) + blit(textures, i, window, deviceWindowRect, d_ptr->blitter); } funcs->glEnable(GL_BLEND); @@ -272,6 +304,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // semi-transparency even when it is not wanted. funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + // Backingstore texture with the normal widgets. GLuint textureId = 0; QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft; if (QPlatformGraphicsBuffer *graphicsBuffer = this->graphicsBuffer()) { @@ -307,7 +340,6 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i origin = QOpenGLTextureBlitter::OriginBottomLeft; textureId = d_ptr->textureId; } else { - // Backingstore texture with the normal widgets. TextureFlags flags = 0; textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &flags); d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0; @@ -316,7 +348,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i } if (textureId) { - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), windowRect); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), deviceWindowRect); if (d_ptr->needsSwizzle) d_ptr->blitter->setSwizzleRB(true); d_ptr->blitter->blit(textureId, target, origin); @@ -326,11 +358,8 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set. for (int i = 0; i < textures->count(); ++i) { - if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QRect targetRect = deviceRect(textures->geometry(i), window); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); - d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); - } + if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) + blit(textures, i, window, deviceWindowRect, d_ptr->blitter); } funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index ae7314b6d0..5fa7e6dac0 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -82,12 +82,14 @@ public: bool isEmpty() const { return count() == 0; } GLuint textureId(int index) const; QRect geometry(int index) const; + QRect clipRect(int index) const; QWidget *widget(int index); Flags flags(int index) const; void lock(bool on); bool isLocked() const; - void appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags = 0); + void appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, + const QRect &clipRect = QRect(), Flags flags = 0); void clear(); Q_SIGNALS: diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp index 3fd6c999a2..2e386532e2 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp @@ -169,6 +169,29 @@ struct BlendStateBinder bool m_blend; }; +static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) +{ + return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1, + topLeftRect.width(), topLeftRect.height()); +} + +static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter) +{ + const QRect rectInWindow = textures->geometry(idx); + QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); + const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); + + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(clippedRectInWindow, targetWindowRect); + const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect, rectInWindow.size(), + QOpenGLTextureBlitter::OriginBottomLeft); + + blitter->blit(textures->textureId(idx), target, source); +} + void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) { const QPlatformTextureList *textures = window->textures(); @@ -181,7 +204,6 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) for (int i = 0; i < textures->count(); ++i) { uint textureId = textures->textureId(i); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); const float opacity = window->sourceWindow()->opacity(); if (opacity != currentOpacity) { currentOpacity = opacity; @@ -191,24 +213,25 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) if (textures->count() > 1 && i == textures->count() - 1) { // Backingstore for a widget with QOpenGLWidget subwidgets blend.set(true); + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); } else if (textures->count() == 1) { // A regular QWidget window const bool translucent = window->sourceWindow()->requestedFormat().alphaBufferSize() > 0; blend.set(translucent); + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); } else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { // Texture from an FBO belonging to a QOpenGLWidget blend.set(false); - m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft); + clippedBlit(textures, i, targetWindowRect, &m_blitter); } } for (int i = 0; i < textures->count(); ++i) { if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); blend.set(true); - m_blitter.blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); + clippedBlit(textures, i, targetWindowRect, &m_blitter); } } diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 3caec468a6..4cf64e61da 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -175,7 +175,8 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi m_textures->clear(); for (int i = 0; i < textures->count(); ++i) - m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), textures->flags(i)); + m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), + textures->clipRect(i), textures->flags(i)); updateTexture(); m_textures->appendTexture(Q_NULLPTR, m_bsTexture, window->geometry()); diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 485cf82078..5752317924 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -962,7 +962,8 @@ static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatfo QPlatformTextureList::Flags flags = 0; if (widget->testAttribute(Qt::WA_AlwaysStackOnTop)) flags |= QPlatformTextureList::StacksOnTop; - widgetTextures->appendTexture(widget, wd->textureId(), QRect(widget->mapTo(tlw, QPoint()), widget->size()), flags); + const QRect rect(widget->mapTo(tlw, QPoint()), widget->size()); + widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags); } for (int i = 0; i < wd->children.size(); ++i) { -- cgit v1.2.3 From 0e1b4e896fba50ce6603bc323b2940e6859e7421 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 1 Jun 2015 15:23:19 +0200 Subject: Avoid QWidget dependency in QtGui MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not a real dependency as all we need is to store a pointer, but better not to use the name QWidget at all. Change-Id: I30ef1dd44ac7e42c1b9c84675f94088b8c516076 Reviewed-by: Jørgen Lind --- src/gui/painting/qplatformbackingstore.cpp | 10 +++++----- src/gui/painting/qplatformbackingstore.h | 4 ++-- .../platformcompositor/qopenglcompositorbackingstore.cpp | 2 +- src/widgets/kernel/qwidgetbackingstore.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 83077f38ca..62492980de 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -83,7 +83,7 @@ public: struct QBackingstoreTextureInfo { - QWidget *widget; // may be null + void *source; // may be null GLuint textureId; QRect rect; QRect clipRect; @@ -125,10 +125,10 @@ GLuint QPlatformTextureList::textureId(int index) const return d->textures.at(index).textureId; } -QWidget *QPlatformTextureList::widget(int index) +void *QPlatformTextureList::source(int index) { Q_D(const QPlatformTextureList); - return d->textures.at(index).widget; + return d->textures.at(index).source; } QPlatformTextureList::Flags QPlatformTextureList::flags(int index) const @@ -164,12 +164,12 @@ bool QPlatformTextureList::isLocked() const return d->locked; } -void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, +void QPlatformTextureList::appendTexture(void *source, GLuint textureId, const QRect &geometry, const QRect &clipRect, Flags flags) { Q_D(QPlatformTextureList); QBackingstoreTextureInfo bi; - bi.widget = widget; + bi.source = source; bi.textureId = textureId; bi.rect = geometry; bi.clipRect = clipRect; diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index 5fa7e6dac0..eac97e9cf6 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -83,12 +83,12 @@ public: GLuint textureId(int index) const; QRect geometry(int index) const; QRect clipRect(int index) const; - QWidget *widget(int index); + void *source(int index); Flags flags(int index) const; void lock(bool on); bool isLocked() const; - void appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, + void appendTexture(void *source, GLuint textureId, const QRect &geometry, const QRect &clipRect = QRect(), Flags flags = 0); void clear(); diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 4cf64e61da..8ce1ed2d2b 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -175,7 +175,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi m_textures->clear(); for (int i = 0; i < textures->count(); ++i) - m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), + m_textures->appendTexture(textures->source(i), textures->textureId(i), textures->geometry(i), textures->clipRect(i), textures->flags(i)); updateTexture(); diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 5752317924..d1070839fa 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1157,7 +1157,7 @@ void QWidgetBackingStore::doSync() #ifndef QT_NO_OPENGL if (widgetTextures && widgetTextures->count()) { for (int i = 0; i < widgetTextures->count(); ++i) { - QWidget *w = widgetTextures->widget(i); + QWidget *w = static_cast(widgetTextures->source(i)); if (dirtyRenderToTextureWidgets.contains(w)) { const QRect rect = widgetTextures->geometry(i); // mapped to the tlw already dirty += rect; -- cgit v1.2.3 From 6fba3c1904aa7601722a70099d88126191cf60cf Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 1 Jun 2015 09:58:59 +0200 Subject: Stabilize tst_qtouchevent. - Use QTRY_COMPARE() in touchBeginWithGraphicsWidget. - Change raw event translation tests to wait for the window to become active to avoid WM positioning issues. - Blacklist the raw event translation tests on Linux. Task-number: QTBUG-46266 Change-Id: I73aae375ee279a518a2a083d0ce8919cce474cb3 Reviewed-by: Simon Hausmann --- tests/auto/gui/kernel/qtouchevent/BLACKLIST | 6 ++++++ tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 tests/auto/gui/kernel/qtouchevent/BLACKLIST diff --git a/tests/auto/gui/kernel/qtouchevent/BLACKLIST b/tests/auto/gui/kernel/qtouchevent/BLACKLIST new file mode 100644 index 0000000000..8e78d7e41f --- /dev/null +++ b/tests/auto/gui/kernel/qtouchevent/BLACKLIST @@ -0,0 +1,6 @@ +[basicRawEventTranslation] +linux +[multiPointRawEventTranslationOnTouchScreen] +linux +[multiPointRawEventTranslationOnTouchPad] +linux diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index dc35058f66..aa1f573aa9 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -601,7 +601,7 @@ void tst_QTouchEvent::basicRawEventTranslation() touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); touchWidget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); QPointF pos = touchWidget.rect().center(); QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint()); @@ -738,7 +738,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() rightWidget.setGeometry(300, 100, 100, 100); touchWidget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -968,7 +968,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() rightWidget.setGeometry(300, 100, 100, 100); touchWidget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -1468,7 +1468,7 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()) .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); - QCOMPARE(root->touchBeginCounter, 1); + QTRY_COMPARE(root->touchBeginCounter, 1); QCOMPARE(root->touchUpdateCounter, 1); QCOMPARE(root->touchEndCounter, 1); QCOMPARE(root->touchUpdatePoints.size(), 2); -- cgit v1.2.3